`

ELResolver Escapes JSP EL Values To Prevent Cross-Site Scripting

    博客分类:
  • SSH
 
阅读更多
JspFactory.getDefaultFactory()返回null的异常解决办法:
unable to register a custom ELResolver http://stackoverflow.com/questions/2551517/gae-j-unable-to-register-a-custom-elresolver
I am not sure which servletcontainer GAE uses "under the hoods" (Jetty? Tomcat?), but this is recognizeable as a bug in Tomcat 6.x. A workaround is to force the loading of JspRuntimeContext yourself before getting the factory:
Class.forName("org.apache.jasper.compiler.JspRuntimeContext");
See if this or similar hack helps.

ELResolverhttp://pz0513.blog.51cto.com/443986/112605
能够自定义 EL 表达式求值的变量和属性解析行为。
对一个表达式进行求值时,参考与 ELContext 关联的 ELResolver,以对表达式的第一个变量进行初始解析。遇到 . 或 [] 操作符时也要参考它,但方法表达式中最后一个这样的操作符除外,因为在这种情况下解析规则是固定编码的。
例如,在 EL 表达式 ${employee.lastName} 中,ELResolver 确定 employee 引用的对象,以及获取该对象 lastName 属性的含义。
此类中的大多数方法都接受 base 和 property 参数。如果是变量解析(例如,确定 ${employee.lastName} 中 employee 引用的内容),则 base 参数将为 null,property 参数将总是为 String 类型。这种情况下,如果 property 不是 String,则 ELResolver 的行为未定义。
如果是属性解析,则 base 参数标识 base 对象,property 对象标识 base 上的属性。例如,在表达式 ${employee.lastName} 中,base 是 employee 变量解析的结果,property 是字符串 "lastName"。在表达式 ${y[x]} 中,base 是 y 变量解析的结果,property 是 x 变量解析的结果。
尽管只有一个 ELResolver 与 ELContext 关联,但对于任何给定的变量或属性解析,通常可以使用多个解析器。ELResolver 使用 CompositeELResolver 连接到一起,以定义丰富语义来计算表达式。
对于 #getValue、#getType、#setValue 和 #isReadOnly 方法,ELResolver 不负责解析所有可能的 (base, property) 对。实际上,大部分解析器将仅能处理一种类型的 base。要指示解析器成功地解析特定 (base, property) 对,它必须将 ELContext 的 propertyResolved 属性设置为 true。如果它无法处理给定对,则必须保持此属性不变。如果 propertyResolved 为 false,则调用者必须忽略该方法的返回值。
设计 #getFeatureDescriptors 和 #getCommonPropertyType 方法的主要目的是支持设计时工具,但它们也必须在运行时处理调用。可以使用 java.beans.Beans#isDesignTime 方法确定是否在设计时(或运行时)参考了解析器。
......
详解见原文

原文:http://pukkaone.github.io/2011/01/03/jsp-cross-site-scripting-elresolver.html
Cross-site scripting is a computer security vulnerability enabling an attacker to inject malicious code into a Web page that will be executed by the Web browser when other users view the page. If your Web application accepts data from the user and then outputs that data unaltered in HTML, then it is vulnerable because user-controlled data might contain executable code.

Since JSP 2.0, EL expressions can appear in the template text:

<h1>Hello, ${user.name}</h1>

Unfortunately, the JSP container does not escape expression values, so if the expression contains user-controlled data, then cross-site scripting is possible. JSTL provides a couple of ways to sanitize the output. The c:out tag escapes XML characters by default:

<c:out value="${user.name}"/>

Alternatively, the EL function fn:escapeXml also escapes XML characters:

${fn:escapeXml(user.name)}

The default option should be the safe option. That's a sensible engineering principle. If EL values are escaped by default, then you're protected from coders who forget to wrap expressions in c:out or fn:escapeXml.

Starting with JSP 2.1, a Web application can register a custom ELResolver. I'm going to present a custom ELResolver that escapes EL values, allowing you to use EL in JSPs while preventing cross-site scripting.

A custom servlet context listener registers the custom ELResolver when the application starts. To use it, define a listener in the web.xml file:

<listener>
  <listener-class>com.github.pukkaone.jsp.EscapeXmlELResolverListener</listener-class>
</listener> 

Disable escaping

When you register this custom ELResolver, all EL values will be escaped by default. If you want a JSP to programmatically output HTML, you can resort to a JSP scriptlet or JSP expression, unless the application configured scripting-invalid to true.

Another way uses a custom tag to surround JSP code in which EL values should not be escaped:

<%@ taglib prefix="enhance" uri="http://pukkaone.github.com/jsp" %>

<enhance:out escapeXml="false">
  I hope this expression returns safe HTML: ${user.name}
</enhance:out>

The escapeXml attribute is true by default. You must explicitly set it to false in the tag to disable escaping.

Details

The servlet context listener's contextInitialized method calls the JspApplicationContext.addELResolver method to register the custom ELResolver.

    public void contextInitialized(ServletContextEvent event) {
        JspFactory.getDefaultFactory()
                .getJspApplicationContext(event.getServletContext())
                .addELResolver(new EscapeXmlELResolver());
    }

The addELResolver method inserts the custom ELResolver into a chain of standard resolvers. When evaluating an expression, the JSP container consults the chain of resolvers in the following order, stopping at the first resolver to succeed:

ImplicitObjectELResolver
ELResolvers registered by the addELResolver method.
MapELResolver
ListELResolver
ArrayELResolver
BeanELResolver
ScopedAttributeELResolver
This presents a slight problem because the custom ELResolver wants to escape the value that would have resulted from consulting the chain. When asked for a value, the custom ELResolver invokes the chain of resolvers. The custom ELResolver is itself in the chain of resolvers, so before invoking the chain, it sets a flag telling itself to do nothing when its turn in the chain comes around.

    private boolean gettingValue;

    @Override
    public Object getValue(ELContext context, Object base, Object property)
        throws NullPointerException, PropertyNotFoundException, ELException
    {
        if (gettingValue) {
            return null;
        }

        gettingValue = true;
        Object value = context.getELResolver().getValue(
                context, base, property);
        gettingValue = false;

        if (value instanceof String) {
            value = EscapeXml.escape((String) value);
        }
        return value;
    }

There's a resolver in the chain before the custom ELResolver. This resolver, ImplicitObjectELResolver, will be invoked twice. First, before reaching the custom ELResolver, and again when the custom ELResolver invokes the chain. Multiple invocations of ImplicitObjectELResolver is harmless because ImplicitObjectELResolver had to fail in order for the custom ELResolver to be invoked. When the custom ELResolver invokes the chain, the ImplicitObjectELResolver will fail again.

A resolver indicates success by setting the propertyResolved property of the ELContext to true. When consulting the chain, one of the resolvers very likely set this property to true, so no other resolvers are invoked after returning from the custom ELResolver.
分享到:
评论
1 楼 nizen 2013-08-02  
一个比较纠结的问题是,resolver初衷是解决不能解析的base,但是在这里,目的是在已解析的基础上做一层封装。正是由于这个不同,最终导致在xss过滤前可能会出现递归调用resolver。pukkaone的做法是通过成员变量+threadLocal来识别是否已调用。这个有没更优雅的实现?

相关推荐

    JavaScript Security(PACKT,2014)

    You will then focus on one of the most common JavaScript security attacks, cross-site scripting, and how to prevent cross-site scripting and cross-site forgery. Last but not least, the book covers ...

    Wicked.Cool.PHP

    So you'll learn how to encrypt your confidential data, safeguard your passwords, and prevent common cross-site-scripting attacks. And you'll learn how to customize all of the scripts to fit your own ...

    Android代码-Prevent-Screen-Off

    Prevent-Screen-Off Featured in: Medium What is this library for? Ideally, when you user is looking at the screen, your application should not turn the screen off. This is huge deal for the ...

    Pro PHP Security(Pro)

    4. **Mitigating Cross-Site Scripting (XSS) Attempts**: XSS attacks involve injecting malicious scripts into web pages viewed by other users. The authors explore methods for encoding output, validating...

    Android-Prevent-Screen-Off这个库实现当用户看屏幕时将一直保持屏幕不关掉

    "Android-Prevent-Screen-Off"是一个专门为此目的设计的库,它允许开发者轻松地实现在用户查看屏幕时阻止设备自动熄屏。这个库由Keval Patel(kevalpatel2106)开发,其主要功能是在检测到用户正在注视屏幕时,防止...

    第五节 限制输入长度的XSS-01

    XSS(Cross-Site Scripting)攻击是一种常见的 Web 应用程序攻击,攻击者可以 inject 恶意代码到 Web 应用程序中,从而盗窃用户信息或控制用户行为。限制输入长度是防止 XSS 攻击的一种重要措施。 HTML 表单文本框...

    Android代码-ForceStopGB

    "Prevent Running" hajacks several system API to prevent not-in-use apps in prevent list from running or keep running. Furthermore, it applies to system apps too, specially, support google-family apps...

    java_ssm基于bs模式的医院在线挂号预约系统的设计与实现jsp毕业论文.doc

    session management to prevent unauthorized access, and validation checks to protect against SQL injection and cross-site scripting attacks. These precautions ensure the protection of personal health ...

    Dropout:A Simple Way to Prevent Neural Networks from Overfitting.zip

    《Dropout:一种防止神经网络过拟合的简单方法》 在深度学习领域,过拟合是一个常见的问题,它指的是模型在训练集上表现良好,但在测试集或新数据上性能急剧下降。过拟合是由于模型过度依赖训练数据中的特定特征,...

    基于PHP的经典建筑网站的设计与实现论文.doc

    The system must implement measures to protect user data, prevent unauthorized access, and safeguard against common web vulnerabilities like SQL injection and cross-site scripting attacks. In ...

    AWS CloudShell prevent CTRL-W close-crx插件

    然后,用户需要在该页面开启“开发者模式”,找到“加载已解压的扩展程序”按钮,选择包含"prevent CTRL-W close.crx"文件的目录,这样插件就会被添加到浏览器中。 安装插件后,用户可以测试其功能,尝试在Cloud...

    Common System and Software Testing Pitfalls How to Prevent and Mitigate epub

    Common System and Software Testing Pitfalls How to Prevent and Mitigate Them 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除

    WebRTC Leak Prevent Toggle-crx插件

    GitHub源-https://github.com/aghorler/WebRTC-Leak-Prevent-Toggle CHANGELOG 1.0.14-自动保存选项。 1.0.11-现在,选件在首次安装时会自动打开,并提供新的说明。 1.0.10-更改GitHub用户名,非常小的修复。 1.0.9-...

    essential skills of java

    - **Data Validation:** Ability to validate input data to prevent injection attacks like SQL injection and cross-site scripting (XSS). - **Sanitization Techniques:** Proficiency in sanitizing user ...

    prevent-backspace:防止退格键在浏览器中返回

    npm install prevent-backspace 成分 component install jprichardson/prevent-backspace 例子 var preventBackspace = require ( 'prevent-backspace' ) preventBackspace ( ) //hitting `backspace` outside of...

    prevent-copy-paste:防止复制和粘贴的 Javascript 库

    防止复制粘贴 防止复制和粘贴的 Javascript 库。 这会为本身不支持它的... 用法 &lt;!-- Include library --&gt; [removed][removed] ...-- Input with onpaste property --&gt;...input type="text" onpaste="return false;...

Global site tag (gtag.js) - Google Analytics