c: out вложенный внутри атрибута элемента

#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 с момента публикации этого ответа.