1

I have unprotected JSPs which have XSS holes. I need to replace all ${...} strings which are not already inside a <c:out value="${...}" /> tag by a <c:out value="${...}" />.

For example,

<select>
   <option value="${foo}">label</option>
</select>    
${bar}
<c:out value="${message}" />

needs to be regex-replaced to the following:

<select>
   <option value="<c:out value="${foo}" />">label</option>
</select>    
<c:out value="${bar}" />
<c:out value="${message}" />
vyegorov
  • 21,787
  • 7
  • 59
  • 73
  • Usually it's quite reverse - – Eugene Retunsky Apr 25 '12 at 17:16
  • @EugeneRetunsky Using ` – Beau Grantham Apr 25 '12 at 17:34
  • @Eugene: read this: http://stackoverflow.com/questions/2658922/xss-prevention-in-java/2658941#2658941 Perhaps you're confusing JSP with its successor Facelets. EL in template text is then indeed implicitly escaped. – BalusC Apr 25 '12 at 17:36
  • So it might be actual only for user-controlled-content. Which is not usually the case when any user input is cleared from any HTML tags. – Eugene Retunsky Apr 25 '12 at 17:42
  • @Eugene: indeed, for user-controlled input only. Escaping/sanitizing them on input is **not** the right way. You end up with possibly unreusable data which cannot be used in PDFs/CSV/XML/XLS/etc, or unrecoverable mistakes which can only be rectified by having original data, or double-escaping when the website is completely redesigned to (automatically) perform proper escaping. It should be escaped on output only. – BalusC Apr 25 '12 at 21:21
  • For example, if that is a comment on a web-site - then what issues can be with sanitizing on input? What could be a purpose of ` – Eugene Retunsky Apr 25 '12 at 22:26

2 Answers2

0

It sounds like your starting text has a mixture of <c:out value="${...}" /> and ${...} in it. If that's the case, you could try something like this:

str = str.replaceAll(
             "(?:<c:out\\s+value=\")?\\$\\{([^}]*)\\}(?:\"\\s*/>)?", 
             "<c:out value=\"\\${$1}\" />"
      );

I'm a little rusty on my Java regex syntax, so check that I have the backslashes right. Otherwise, I think that will work.

Justin Morgan - On strike
  • 30,035
  • 12
  • 80
  • 104
0

Regex is not the tool to use when requiring context. However, it would be simple enough to do in two steps by first replacing all instances of <c:out value="${...}" /> to ${...} and then all ${...} to <c:out value="${...}" />.

Regular expressions

\${[^}]+}
<c:out value="\${[^}]+}" />
erikxiv
  • 3,965
  • 1
  • 23
  • 22