Краткий ответ: главная проблема AI-сгенерированного PHP-кода не в том, что он “не работает”, а в том, что он часто работает без нормальной проверки прав, nonce, входных данных, SQL-запросов и вывода HTML. Для WordPress это может закончиться XSS, SQL injection, CSRF, утечкой данных, удалением записей, поломкой админки или взломом сайта.
AI может быстро написать шорткод, AJAX-обработчик, форму, мини-плагин или интеграцию с API. Но он не видит весь сайт: роли пользователей, активные плагины, кеш, WooCommerce, REST API, ограничения хостинга, старый код темы и реальные сценарии атаки. Поэтому код от AI нужно воспринимать как черновик, а не как готовое безопасное решение.
Если плагин или сниппет был написан через ChatGPT, Cursor, Claude или другой AI-инструмент, его лучше проверить до установки на рабочий сайт. Подробный чек-лист по этому сценарию есть в статье как проверить WordPress-плагин, написанный через ChatGPT.
AI обычно генерирует PHP-код по видимому запросу: “сделай форму”, “сохрани настройку”, “выведи таблицу”, “добавь AJAX”. Он старается выполнить задачу, но не всегда добавляет защитные проверки, которые обязательны для WordPress-разработки.
В WordPress входные данные нужно проверять, очищать и экранировать. Официальная документация WordPress прямо разделяет валидацию, sanitization и escaping: данные нужно проверять до использования и экранировать перед выводом на страницу. :contentReference[oaicite:0]{index=0}
Типичная логическая ошибка AI-кода: он добавляет только “чтобы работало”, но не добавляет “чтобы безопасно работало”. Например, AJAX-запрос сохраняет данные, но не проверяет, кто именно отправил запрос. Или SQL-запрос строится напрямую из $_POST. Или HTML выводится без esc_html() и esc_attr().
functions.php, и ошибка ломает весь сайт.admin-ajax.php.| Ошибка | Что ломает | Чем опасно | Как исправлять |
|---|---|---|---|
| Нет проверки прав | Любой авторизованный пользователь может выполнить действие | Удаление данных, изменение настроек, доступ к чужим данным | Добавить current_user_can() |
| Нет nonce | Запрос можно отправить со сторонней страницы | CSRF-атака | Добавить wp_nonce_field(), wp_create_nonce(), check_ajax_referer() |
SQL из $_GET или $_POST |
Запрос к базе становится управляемым извне | SQL injection | Использовать $wpdb->prepare() |
| Вывод без escaping | В HTML попадает чужой скрипт | XSS | Использовать esc_html(), esc_attr(), esc_url(), wp_kses_post() |
| Небезопасная загрузка файлов | На сайт можно загрузить опасный файл | Вредоносный код, фишинг, заражение | Проверять MIME, расширение, размер, права и путь загрузки |
| Прямое подключение PHP-файлов | Файл можно открыть напрямую | Ошибки, раскрытие путей, обход логики WordPress | Добавить проверку defined( 'ABSPATH' ) |
| Опасный REST endpoint | API отдаёт или меняет данные без контроля | Утечка данных, изменение настроек | Добавить permission_callback |
Проверять AI PHP-код нужно не только на синтаксис. Синтаксически правильный код может быть небезопасным. Визуально он выглядит аккуратно, но внутри может отсутствовать проверка прав, nonce или подготовка SQL-запроса.
defined( 'ABSPATH' ) || exit;?current_user_can() перед изменением данных?$_POST, $_GET, $_REQUEST проходят через wp_unslash() и sanitization?$wpdb->prepare()?eval(), unserialize() для внешних данных, shell_exec(), exec(), base64_decode() без понятной причины?wp_ajax_nopriv_, если действие должно быть только для авторизованных пользователей?wp-content/debug.log — ошибки PHP, warnings, notices, fatal errors.admin-ajax.php, REST API, формы.wp_options, post meta, user meta.Если после установки AI-кода сайт начал вести себя нестабильно, стоит отдельно разобрать не только ошибку, но и архитектуру решения. Такая ситуация часто похожа на сценарий, когда проект после вайб-кодинга начал ломаться: отдельные функции работают, но связанная логика сайта постепенно разваливается.
Если не хотите рисковать сайтом и тратить время на эксперименты, можно оставить заявку. Я посмотрю задачу и предложу аккуратное решение.
Безопасное исправление AI PHP-кода начинается с простого правила: нельзя вставлять код на рабочий сайт без проверки входа, прав, базы данных и вывода.
ABSPATH в начале PHP-файлов.current_user_can() перед действиями, которые меняют данные.check_ajax_referer() или wp_verify_nonce() для защиты запросов.sanitize_text_field(), sanitize_email(), absint(), sanitize_key() для входных данных.$wpdb->prepare() для SQL.esc_html(), esc_attr(), esc_url() перед выводом.wp_send_json_success() и wp_send_json_error() для AJAX.permission_callback для REST API.Важно не путать nonce и права доступа. Nonce помогает защититься от подделки запроса, но сам по себе не означает, что пользователь имеет право выполнить действие. Для административных операций нужна отдельная проверка через current_user_can(). В документации и примерах WordPress эти проверки обычно идут вместе: nonce проверяет запрос, capability проверяет полномочия пользователя. :contentReference[oaicite:1]{index=1}
Важно: код ниже влияет на сохранение данных через AJAX. Не вставляйте его вместо существующего обработчика без проверки на копии сайта. Лучше добавлять такие правки в отдельный мини-плагин или в functions.php дочерней темы, если вы понимаете, какой обработчик заменяете.
Такой код может работать, но он небезопасен: нет nonce, нет проверки прав, данные из $_POST используются напрямую.
<?php
add_action( 'wp_ajax_save_ai_title', 'save_ai_title' );
function save_ai_title() {
global $wpdb;
$post_id = $_POST['post_id'];
$title = $_POST['title'];
$wpdb->query(
"UPDATE {$wpdb->posts} SET post_title = '$title' WHERE ID = $post_id"
);
echo 'saved';
wp_die();
}
$_POST['post_id'] не приведён к числу.$_POST['title'] не очищен.$wpdb->prepare().current_user_can().echo, а не через JSON.Этот пример показывает базовую структуру безопасного AJAX-обработчика для WordPress.
<?php
defined( 'ABSPATH' ) || exit;
add_action( 'wp_ajax_sc_save_ai_title', 'sc_save_ai_title' );
function sc_save_ai_title() {
check_ajax_referer( 'sc_save_ai_title_nonce', 'nonce' );
if ( ! current_user_can( 'edit_posts' ) ) {
wp_send_json_error(
array(
'message' => 'Недостаточно прав для выполнения действия.',
),
403
);
}
$post_id = isset( $_POST['post_id'] ) ? absint( wp_unslash( $_POST['post_id'] ) ) : 0;
$title = isset( $_POST['title'] ) ? sanitize_text_field( wp_unslash( $_POST['title'] ) ) : '';
if ( ! $post_id || '' === $title ) {
wp_send_json_error(
array(
'message' => 'Некорректные данные.',
),
400
);
}
if ( ! current_user_can( 'edit_post', $post_id ) ) {
wp_send_json_error(
array(
'message' => 'Нет доступа к этой записи.',
),
403
);
}
$updated = wp_update_post(
array(
'ID' => $post_id,
'post_title' => $title,
),
true
);
if ( is_wp_error( $updated ) ) {
wp_send_json_error(
array(
'message' => 'Не удалось сохранить заголовок.',
),
500
);
}
wp_send_json_success(
array(
'message' => 'Заголовок сохранён.',
'post_id' => $post_id,
'title' => $title,
)
);
}
Куда вставлять: в PHP-шаблон формы настроек, метабокса или административной страницы плагина.
<?php
wp_nonce_field( 'sc_save_ai_title_nonce', 'sc_save_ai_title_nonce_field' );
Куда вставлять: в обработчик сохранения формы. Для AJAX чаще используется check_ajax_referer(), для обычной POST-формы — wp_verify_nonce().
<?php
if (
! isset( $_POST['sc_save_ai_title_nonce_field'] ) ||
! wp_verify_nonce(
sanitize_text_field( wp_unslash( $_POST['sc_save_ai_title_nonce_field'] ) ),
'sc_save_ai_title_nonce'
)
) {
wp_die( 'Ошибка проверки безопасности.' );
}
Куда вставлять: в плагин или обработчик, где действительно нужен прямой запрос к базе. Если можно использовать функции WordPress вроде wp_update_post(), update_post_meta(), get_users(), лучше использовать их.
<?php
global $wpdb;
$user_id = isset( $_POST['user_id'] ) ? absint( wp_unslash( $_POST['user_id'] ) ) : 0;
$results = $wpdb->get_results(
$wpdb->prepare(
"SELECT ID, user_email FROM {$wpdb->users} WHERE ID = %d",
$user_id
)
);
Куда вставлять: в шаблон, шорткод, виджет, админ-таблицу или HTML-вывод плагина.
<?php
$title = get_the_title();
$url = get_permalink();
echo '<a href="' . esc_url( $url ) . '">' . esc_html( $title ) . '</a>';
После исправления AI PHP-кода сайт должен работать предсказуемее: AJAX-запросы не выполняются без nonce, пользователи без нужных прав не могут менять данные, SQL-запросы не принимают внешние значения как часть команды, а HTML-вывод не пропускает чужой скрипт.
Хороший результат проверки — это не только отсутствие fatal error. Нормальный результат выглядит так:
debug.log не заполняется новыми предупреждениями;Важно: не показывайте ошибки посетителям на рабочем сайте. Логирование можно включить временно для диагностики, а вывод ошибок на экран лучше оставить выключенным.
Куда вставлять: wp-config.php, выше строки /* That's all, stop editing! */.
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
Куда выполнять: SSH/терминал на хостинге, если доступен WP-CLI.
wp plugin list --status=active
wp-content/debug.log.AI часто генерирует один большой кусок кода. Для поддержки и безопасности лучше разделять:
Если код уже превратился в большой неуправляемый файл, лучше не дописывать новые функции сверху, а провести технический аудит. Для таких случаев подходит услуга доработка проекта после вайб-кодинга, когда нужно не просто “пофиксить одну ошибку”, а привести AI-код в рабочее и безопасное состояние.
Нет. Nonce не заменяет проверку прав. Он помогает понять, что запрос пришёл из ожидаемого места, но не доказывает, что пользователь имеет право менять настройки, удалять данные или редактировать запись.
Нужно проверять разные роли. Часто проблема проявляется только у редактора, менеджера магазина, подписчика или гостя.
Нельзя. В базе могут быть данные, которые раньше попали туда через форму, импорт, API, старый плагин или ручное редактирование. WordPress рекомендует экранировать данные как можно ближе к месту вывода. :contentReference[oaicite:2]{index=2}
Не всегда. Для числа нужен absint(), для email — sanitize_email(), для URL — esc_url_raw() при сохранении и esc_url() при выводе, для HTML — wp_kses_post() или более строгий список разрешённых тегов.
Можно, но это риск. Ошибка в functions.php может вызвать белый экран, критическую ошибку или недоступность админки. Для сложной логики лучше делать отдельный плагин.
Нужен, если в запрос попадает переменная. Даже если кажется, что там только ID, значение всё равно должно быть приведено к нужному типу и передано через подготовленный запрос.
URL не является защитой. Если endpoint зарегистрирован, его можно найти. Для REST API нужен нормальный permission_callback.
action.check_ajax_referer().current_user_can().debug.log.Это частая ситуация в AI-коде. Например, сначала обработчик был только для администратора, потом AI добавил wp_ajax_nopriv_, чтобы форма работала для гостей, но не добавил ограничение действия. В итоге публичная форма получает доступ к логике, которая должна была быть закрытой.
Самое опасное — скрытые ошибки безопасности: отсутствие проверки прав, nonce, sanitization, escaping и безопасных SQL-запросов. Код может выглядеть рабочим, но открывать доступ к данным или настройкам сайта.
Можно, но только после проверки. AI-код лучше считать черновиком: его нужно протестировать на копии сайта, проверить роли, nonce, SQL, AJAX, REST API и вывод HTML.
Проверьте, есть ли в коде current_user_can(), check_ajax_referer(), sanitize_*, esc_* и $wpdb->prepare(). Если код меняет данные, но этих проверок нет, это тревожный сигнал.
Потому что запрос пользователя обычно описывает функцию, а не все ограничения безопасности. AI может написать код, который выполняет действие, но не знает реальных ролей, структуры сайта, плагинов, форм, API и сценариев атаки.
Часто встречается отсутствие проверки прав через current_user_can(). Особенно в AJAX-обработчиках, настройках плагина, удалении записей, импорте данных и REST API.
Обе проблемы опасны. SQL injection может повлиять на базу данных, а XSS может выполнить чужой JavaScript в браузере пользователя. Для WordPress-сайта с админкой, формами и WooCommerce обе ошибки критичны.
Да. Админка тоже требует проверки прав, nonce и escaping. Внутренний интерфейс может использовать редактор, менеджер магазина, контент-менеджер или другой пользователь с неполными правами.
Для маленьких проверенных сниппетов — можно, но осторожно. Для AJAX, REST API, интеграций, таблиц базы данных, загрузки файлов и WooCommerce лучше делать отдельный плагин. Так проще отключить код через FTP, если что-то сломается.
Минимально: сделать бэкап, поставить код на копию сайта, включить debug.log, проверить действия под разными ролями, посмотреть ошибки в DevTools и не устанавливать код на рабочий сайт, если есть 403, 500, warnings или непонятные SQL-запросы.
Security-плагин может заблокировать часть атак, но он не исправляет неправильную логику внутри вашего кода. Если AJAX-обработчик сам разрешает пользователю удалить данные без проверки прав, плагин не всегда поймёт бизнес-логику сайта.
Отключите проблемный сниппет или плагин через FTP, проверьте debug.log, восстановите доступ к админке, затем разберите код по частям. Не стоит сразу просить AI “починить всё”, лучше сначала найти точную функцию, которая вызвала ошибку.
Ошибки безопасности в AI-сгенерированном PHP-коде чаще всего появляются не из-за синтаксиса, а из-за пропущенной логики защиты. Код может красиво выглядеть, успешно сохранять данные и даже решать задачу, но при этом открывать доступ к AJAX, REST API, SQL, настройкам или HTML-выводу.
Для WordPress безопасный минимум такой: проверка прав, nonce, sanitization, validation, prepared SQL, escaping, логирование ошибок и тестирование на копии сайта. AI можно использовать как помощника, но финальную ответственность за безопасность кода должен нести разработчик, который понимает WordPress, PHP и реальные риски конкретного сайта.
Рекомендуем услугу: исправление AI-сгенерированного PHP-кода
Об авторе