问题
We use jspx as template engine. We have dozen of screens with hundreds of el expressions like ${user.firstName} or "${mail.subject}"
And all this HTML code is not escaped by default. If there would be something with < or " in field -- screen will fail. We can always use fn:escapeXml but doing so in all places really boring.
1) Does there is a way to do escape by default?
The only way I know is to hack JSP compiler (like jasper for tomcat). But it is not a way to go.
2) Why somebody may ever need unescaped HTML in el? Storing HTML outside of template (in database for example) is not a good practice.
3) I am sure template engine should handle it automatically (as it done in XSLT), why should user care about it? Manual escaping (fn:escapeXml) smells like SQL manual escaping (which is used instead of JDBC setParam): boilerplate code and good place for sql-injection (cross-site scripting in our case).
回答1:
1) Is there a way to do escape by default?
Not in the vintage JSP. Its successor Facelets, however, escapes them by default. The only way to disable escaping is to use <h:outputText value="#{bean.foo}" escape="false" />
instead of #{bean.foo}
.
2) Why somebody may ever need unescaped HTML in el? Storing HTML outside of template (in database for example) is not a good practice.
Storing sanitized HTML is however more than commonly done. E.g. to allow a small subset of innocent HTML tags like <p>
, <b>
, <i>
and on from which the on*
attributes are already stripped.
3) I am sure template engine should handle it automatically (as it done in XSLT), why should user care about it? Manual escaping (fn:escapeXml) smells like SQL manual escaping (which is used instead of JDBC setParam): boilerplate code and good place for sql-injection (cross-site scripting in our case).
JSP is an ancient view technology. It's not really a flexible template engine.
SQL injections are usually to be prevented by just using PreparedStatement
instead of Statement
(or by using an ORM framework instead of "raw JDBC", like as your XSS issue can be prevented by just using a MVC framework instead of "raw JSP").
As to your concrete problem, well, you can solve this in basically 4 ways:
Bite the bullet and replace all EL-in-template-text which redisplays user-controlled input by
fn:escapeXml()
or<c:out>
and teach yourself and your team to pay attention to this in the future. Hint, a bit decent IDE like Eclipse has a regex based find-and-replace-in-all-files.Have sort of DB interceptor which strips malicious HTML before inserting in DB. If necessary run a DB script to sanitize the existing data. This is however more a workaround than a real solution.
Replace the JSP EL resolver by a custom one which escapes all the HTML. This has however the disadvantage that you can never show plain HTML by EL whenever really needed.
Use a decent MVC framework with builtin HTML escaping. This is however more work than just fixing the individual EL expressions.
回答2:
Yes, it is possible to escape all EL-expressions by default. This can be done by registrating a custom ELResolver. See for instance this site for an example of how it can be done: http://pukkaone.github.com/2011/01/03/jsp-cross-site-scripting-elresolver.html
来源:https://stackoverflow.com/questions/5887037/escape-html-entities-in-jsp-jspx-no-solution-for-problem-that-should-not-even