Я пытаюсь взять результат запроса «Яркий» и вывести его результаты как ответ JSON. Мое приложение использует Slim и Twig для генерации HTML-ответов, однако я не уверен, что я должен использовать Twig для генерации JSON.Уместно ли использовать Twig для генерации чистых ответов JSON?
Я знаю, что могу использовать встроенную функцию PHP echo json_encode(...)
, но это создает потенциальную уязвимость XSS, если моя база данных содержит объекты HTML. Предполагается, что Twig будет отвечать за то, чтобы избежать выхода на выходе.
Я знаю this question, однако, похоже, он не дает соответствующего ответа. Я также знаю о json_encode
фильтра, но когда я делаю это:
/api/users-json.twig
{
"rows" : {{rows | json_encode}}
}
/API/пользователей контроллер:
// Simulate database query results
$result = [
"rows" => [
[
"user_name" => "alex",
"message" => "grawr!"
],
[
"user_name" => "h4xx0r",
"message" => "<script>alert('hello, I can execute JS on your website!');</script>"
]
]
];
$app->response->headers->set('Content-Type', 'application/json; charset=utf-8');
$app->render("api/users-json.twig", $result);
Ответ выглядит так:
{
"rows" : [{"user_name":"alex","message":"grawr!"},{"user_name":"h4xx0r","message":"<script>alert('hello, I can execute JS on your website!');<\/script>"}]
}
Это не интерпретируемая клиентская сторона без дальнейшей обработки. Согласно моему браузеру, тип контента правильно установлен на application/json
.
Я могу, конечно, сделать: /api/users-json.twig
{
"rows" : {{rows | json_encode | raw}}
}
Который дает мне ответ:
{
"rows" : [{"user_name":"alex","message":"grawr!"},{"user_name":"h4xx0r","message":"<script>alert('hello, I can execute JS on your website!');<\/script>"}]
}
Но если бы я, чтобы сделать h4xx0r-х сообщение в клиентском коде, я открыт для атаки XSS.
Вывод, который я считаю, было бы «правильным» будет:
{
"rows" : [{"user_name":"alex","message":"grawr!"},{"user_name":"h4xx0r","message":"<script>alert('hello, I can execute JS on your website!');<\/script>"}]
}
Обратите внимание, что «сообщение» h4xx0r в настоящее время спасся, но структура ответа в целом сохраняется действительным JSON.
Я мог бы, конечно, прокрутить каждую строку и вручную htmlspecialchars
каждое значение, а затем либо echo json_encode
, либо передать его в Twig. Но похоже, что это должно быть ответственностью Twig!
Edit: Казалось бы, что РНР filter_var_array
, в сочетании с json_encode
, является разумной альтернативой использованию Twig:
$app->response->headers->set('Content-Type', 'application/json; charset=utf-8');
echo json_encode(filter_var_array($result, FILTER_SANITIZE_SPECIAL_CHARS));
Производит:
{"rows":[{"user_name":"alex","message":"grawr!"},{"user_name":"h4xx0r","message":"<script>alert('hello, I can execute JS on your website!');<\/script>"}]}
Но я до сих пор не уверен, если это то, что «должно» сделать с помощью Twig.
Есть ли способ сделать это с помощью Slim и Twig? Или я полностью ошибаюсь в треке, и должен ли мой клиентский код (JS) правильно избегать содержимого перед рендерингом?
Я не думаю, что предотвращение XSS atracks - ответственность Twig. Чтобы предотвратить это, вы должны фильтровать свой вход, а не вывод. –
@gustavo Неправильное использование. Конечно, вы всегда должны ** фильтровать ** свой вход, когда это возможно, но ** ускорение ** - это то, что должно быть сделано на выходе. Исходный вход - это [antipattern] (http://security.stackexchange.com/a/42521/74909). – alexw
Ух, ты спрашиваешь риторически? – alexw