Этот вопрос задан много раз. См here, here и herePHP json_encode и XSS
На основе ответов на эти вопросы, я сделал несколько тестов, и я вынужден задать тот же вопрос снова, как ни один из ответов являются правильными (по-крайней мере, для меня). Пожалуйста, поправьте меня, если мое понимание предмета плохое.
Я работаю над API для веб-приложения, которое выводит ответ JSON. Ответ на серверный сервер обрабатывается json_encode
в PHP. Поскольку это был бы публичный API, я бы хотел предотвратить любой XSS из-за неправильной реализации на стороне клиента разработчиком, использующим API.
Для моего теста я сделал следующее на стороне сервера:
header("Content-Type: application/json", true);
$bad = array('bad_key' => 'alert("hi");');
echo json_encode($bad);
На стороне клиента я использую JQuery AJAX, которая автоматически разбирает JSON получил. Первоначально это не показало никакой проблемы с XSS. Затем я прошел response.bad_key
до eval()
.
eval(response.bad_key);
Это сразу же привело к исполнению строки в bad_key
. Я знаю, что использование eval
является плохим и его следует избегать. Тем не менее, это то, что я знаю и не могу обеспечить, чтобы другой разработчик следовал той же практике. Чтобы избежать таких сценариев, решением было бы выполнить кодировку на стороне сервера. Для этого предположим, что я использую htmlspecialchars
.
header("Content-Type: application/json", true);
$bad = array('bad_key' => htmlspecialchars('alert("hi");'));
echo json_encode($bad);
Это, хотя он не выполняет alert("hi");
на стороне клиента, но ломает код JS из-за наличия &
. json_encode
с опцией JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS
как предложено here тоже не помогает.
Как я могу предотвратить XSS в таком сценарии?
+1 Вы не можете защитить людей от своей собственной глупости. Санирование всех и всех * потенциально опасных «строк» оставляет вас в основном без содержания. – deceze
@thiefmaster Да, это серая область, где я действительно не могу что-то сделать, чтобы предотвратить неправильное поведение из-за плохой реализации другими. Я думал, что я что-то упустил. Спасибо за ясность. – John
Это даже не было бы «плохой реализацией» - это потребовало бы, чтобы другой пользователь активно выполнял некоторые данные в виде кода JavaScript. – ThiefMaster