17

I would appreciate providing me with a set of clear guidelines or ruling for handling escaping strings. What I use for escaping strings is the apache commons-lang-x.x.jar library. Specifically the StringEscapeUtils.escapeHtml(String toEscape) method.

I need to know:

(1) Where is it better to escape strings, on the JSP page or in the Servlet?

(2) What do you recommend StringEscapeUtils.escapeHtml(..) or <c:out> from JSTL

(3) Handling multiline strings, which is better, use <br> directly in the string, or \n and a nl2br() method:

String strError = "Invalid username.\nPlease try again.";

or

String strError = "Invalid username.<br>Please try again.";

(4) How would I go escaping strings that receive wild cards, example:

String strError = "Invalid user [%s].<br>Please specify another user."

(5) Since javascript escape characters are different. What should I use to escape Java strings that are to be rendered inside the javascript sections of the JSP page (eg. var name = "<%=javaStringHoldingName%>").

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Basil Musa
  • 8,198
  • 6
  • 64
  • 63

3 Answers3

16

You only need to escape it exactly there where it can harm. In this particular case, it's in the view. User-controlled HTML can harm when it get inlined among all your HTML in the view. This is a source for XSS.

In a well-designed JSP page (read: no scriptlets), JSTL offers you the <c:out> tag and fn:escapeXml() function to escape HTML/XML.

<c:out value="${param.foo}" />
<input type="text" name="foo" value="${fn:escapeXml(param.foo)}" />
Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • What about cases where I have a template string like "Invalid range [%s].
    Should contain alphanumeric only.". And lets say the value is "1..<5". How would this be handled in escaping? Please note that the template string contains a
    because it is intended to be displayed on two lines.
    – Basil Musa Feb 10 '11 at 22:06
  • In basic JSP, you normally use JSTL ``. Or when you're using a (MVC) framework on top of JSP like Spring, JSF, etc, they have all their own message format tags. See also this related question which I by coincidence answered today: http://stackoverflow.com/questions/4961558/best-practice-for-translations – BalusC Feb 10 '11 at 22:10
  • just so you know, it also works using `StringEscapeUtils.escapeHtml("lala");` printed out in the jsp. – Vince Aug 02 '12 at 15:00
  • 1
    @Vince: Sure it'll work, whether it's the *right* way is a second big question. See also http://stackoverflow.com/questions/3177733/how-to-avoid-java-code-in-jsp-files Don't use *scriptlets* wherever possible! – BalusC Aug 02 '12 at 15:02
2

For two of your questions:

1) Escaping strings for display purposes - I would consider this a view concern. Your JSP could handle this, if you're using your JSP as a view.

3) Error messages from your models / business logic layer should not include formatting such as newline characters. Let your view determine how to format error messages. With HTML, the use of a div tag with appropriate width styling can eliminate the need for br tags, for example.

Shan Plourde
  • 8,528
  • 2
  • 29
  • 42
  • Can you edit your answer to give me an example on the third point? By the way, where's the second point :) Please read the example in the comment section of the first answer in respond to BalusC – Basil Musa Feb 10 '11 at 22:12
2

I would probably not pass a String object, but instead just pass an error object up to the view and let the jsp do whatever it wants

In the controller:

errorObj.name = "invalid login";
errorObj.description = "try again";

In the view:

<c:out value="${errorObj.name}" /><br /><c:out value="${errorObj.description}" />

Not really related to your question, but it's also a good practice to use a message like, "invalid login attempt" no matter what the login error really is. The message you are giving, "invalid username" lets someone intent on hacking your accounts know if they have a good username that they can use to then attack the password with. If this is exposed publicly, this can be a small, but very real, issue.

David
  • 1,887
  • 2
  • 13
  • 14