2013-05-17 2 views
1

Этот вопрос задан много раз. См 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 в таком сценарии?

ответ

9

В этом случае вам не нужно предотвращать «XSS». Если кто-то достаточно глуп, чтобы выполнить некоторые случайные данные, которые вы отправляете ему как JavaScript, вы ничего не можете сделать против него. На самом деле, если вы избежали чего-то, чтобы предотвратить это, он, вероятно, отменил бы его, чтобы заставить его работать снова.

Обратите внимание, что с помощью eval для синтаксического анализа строка JSON несколько безопасна (если вы отправить действительный JSON) - хотя это не рекомендуется в любом современном браузере, который имеет собственный JSON.parse(). Но в вашем примере вы не используете его для разбора JSON, но для выполнения некоторой случайной строки данных! Когда кто-то это делает, это означает, что он ХОЧЕТ, чтобы он исполнялся как код - так что это не XSS, а «работает по назначению»!

+1

+1 Вы не можете защитить людей от своей собственной глупости. Санирование всех и всех * потенциально опасных «строк» ​​оставляет вас в основном без содержания. – deceze

+0

@thiefmaster Да, это серая область, где я действительно не могу что-то сделать, чтобы предотвратить неправильное поведение из-за плохой реализации другими. Я думал, что я что-то упустил. Спасибо за ясность. – John

+1

Это даже не было бы «плохой реализацией» - это потребовало бы, чтобы другой пользователь активно выполнял некоторые данные в виде кода JavaScript. – ThiefMaster