#java #jsp #jstl
#java #jsp #jstl
Вопрос:
Является ли хорошей практикой вложение JSTL-тега c: out внутри атрибута элемента или обычно предпочтительнее использовать атрибут var c: out? Кажется, это работает в любом случае, но я подозреваю, что вложение может не работать на некоторых серверах приложений или версиях JSP (и это просто выглядит неправильно).
Например, входной элемент, значение которого восстанавливается при сбое проверки и с экранированием специального символа:
<input type="text" name="firstname" value="<c:out value="${param.firstname}"/>"/>
против:
<c:out value="${param.firstname}" var="firstname"/>
<input type="text" name="firstname" value="${firstname}"/>
Ответ №1:
Обычной практикой предотвращения XSS-атак в атрибутах HTML-элемента без нарушения правильно сформированного синтаксиса XML вложенным <c:out>
тегом является использование fn:escapeXml()
вместо этого функции:
<input type="text" name="firstname" value="${fn:escapeXml(param.firstname)}"/>
Комментарии:
1. Хммм, похоже, что тогда нет веских причин когда-либо использовать c: out?
2. Не в атрибутах элемента HTML, нет. Вне его, это зависит. Для
<c:out value="${bean.foo}" />
некоторых разработчиков более удобочитаем, чем${fn:escapeXml(bean.foo)}
. Кроме того, вы также можете использовать MVC-фреймворк, такой как JSF, чтобы вам никогда не нужно было беспокоиться об этом (и обо всех других повторяющихся шаблонах в сервлетах).
Ответ №2:
Я обычно использую ${}
везде, где могу. Это просто и более читаемо. Я использую <c:out>
, когда мне нужны дополнительные функциональные возможности, такие как escapeXml
функция.
В вашем примере вы действительно могли бы обойтись без <c:out>
:
<input type="text" name="firstname" value="${param.firstname}"/>
Редактировать: проблемы с XSS
Мой ответ не касается дыр XSS, о которых упоминают BalusC и StuartWakefield. Хотя мой ответ упрощенно верен, вы действительно всегда должны смягчать пробелы XSS. Я предпочитаю использовать OWASP taglib.
<span>${esc:forHtml(sketchyText)}</span>
<span><esc:forHtml(sketchyText)/></span>
<input value="${esc:forHtmlAttribute(sketchyText)}"/>
Комментарии:
1. Это работает только в JSP 2.0 и новее, что в наши дни не должно быть проблемой, но это только открывает широкую дыру в атаке XSS…
2. Это где-нибудь задокументировано? Я хотел бы узнать об этом больше, и я не могу понять, почему использование ${} непосредственно в атрибуте HTML приведет к атаке XSS…
3. @IcedDante — Если вы используете «@{username}» в своем комментарии, он отправит уведомление в BalusC. В противном случае он, вероятно, пропустит ваш комментарий.
4. Имя моего друга
"/><script>/*xss here*/</script><img src="lolcatz.jpg"
… Некоторые другие меры безопасности могут зафиксировать этот случай до того, как мы перейдем к вводу, но его можно обойти. В любом случае, с приведенным выше кодом любая ошибочная двойная кавычка в firstname «вырвется» из атрибута HTML. Вы должны экранировать его для контекста, который вы выводите, т. Е. ФункцияescapeHtmlAttribute
была бы идеальной,${fn:escapeXml(person.firstname)}
достаточно.5. @StuartWakefield — Пожалуйста, скажите мне, что вы действительно знаете кого-то с таким именем. Я думал, что это всего лишь миф . К счастью, я узнал намного больше о XSS с момента публикации этого ответа.