Security Research Laboratoryhttps://communities.coverity.com/blogs/security
Fri, 06 Sep 2013 01:02:18 GMTJive SBS 5.0.2.0 (http://jivesoftware.com/products/clearspace/)2013-09-06T01:02:18ZNew Blog Sitehttps://communities.coverity.com/blogs/security/2013/09/05/new-blog-site
<!-- [DocumentBodyStart:2285b2dd-f5d5-4477-9270-279771908dfd] --><div class="jive-rendered-content"><p><span>We've decided to move our blogging platform onto a new site that we've been working on for a while: </span><a class="jive-link-external-small" href="http://security.coverity.com">http://security.coverity.com</a><span>.&nbsp; Thanks for reading, and enjoy the new site!</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Andy</p></div><!-- [DocumentBodyEnd:2285b2dd-f5d5-4477-9270-279771908dfd] -->Fri, 06 Sep 2013 01:02:18 GMThttps://communities.coverity.com/blogs/security/2013/09/05/new-blog-siteAndy Chou2013-09-06T01:02:18Z1 year, 11 months ago0https://communities.coverity.com/blogs/security/comment/new-blog-sitehttps://communities.coverity.com/blogs/security/feeds/comments?blogPost=1346Struts 2 Remote Code Execution via OGNL Double Evaluationhttps://communities.coverity.com/blogs/security/2013/05/29/struts2-remote-code-execution-via-ognl-injection
<!-- [DocumentBodyStart:0f961638-c88b-4e51-aaa0-42fa5809d035] --><div class="jive-rendered-content"><h1>Advisory</h1><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>Overview</h2><p>(Note: this write-up uses the <a class="jive-link-external-small" href="http://maven.apache.org/">Maven</a> sample application provided by Struts2. Refer to the Appendix section at the bottom to install the application. References to the blank-archetype application refer to this sample application.)</p><p>From the Struts 2 <a class="jive-link-external-small" href="http://struts.apache.org/release/2.3.x/index.html">website</a></p><blockquote class="jive-quote"><p>Apache Struts 2 is an elegant, extensible framework for creating enterprise-ready Java web applications. The framework is designed to streamline the full development cycle, from building, to deploying, to maintaining applications over time.</p></blockquote><p>Struts 2 heavily utilizes <a class="jive-link-external-small" href="http://commons.apache.org/proper/commons-ognl/">OGNL</a> as a templating / expression language. OGNL, similar to other expression languages, is vulnerable to a class of issues informally termed "double evaluation". That is, the value of an OGNL expression is mistakenly evaluated again as an OGNL expression. For a background on previous OGNL double evaluation issues, I recommend <a class="jive-link-external-small" href="https://twitter.com/meder">@meder's</a> <a class="jive-link-external-small" href="http://conference.hitb.org/hitbsecconf2010kul/materials/D1T1%20-%20Meder%20Kydyraliev%20-%20Milking%20a%20Horse.pdf">"Milking a horse or executing remote code in modern Java frameworks"</a> presentation. (The exploit used below is based on @meder's exploit, just condensed.) For other examples of double evaluation in different expression languages, check out Aspect Security's <a class="jive-link-external-small" href="https://www.aspectsecurity.com/uploads/downloads/2012/12/Remote-Code-with-Expression-Language-Injection.pdf">"Remote Code with Expression Language"</a>.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Struts 2 calls its controllers <a class="jive-link-external-small" href="http://struts.apache.org/release/2.3.x/docs/coding-struts-2-actions.html">Actions</a>. Actions are mapped to URLs and views within an <a class="jive-link-external-small" href="http://struts.apache.org/release/2.3.x/docs/strutsxml.html">XML configuration file</a> or via Java annotations. For a good background on Struts 2 and <code>Actions</code>, refer to their <a class="jive-link-external-small" href="http://struts.apache.org/development/2.x/docs/getting-started.html">"Getting Started"</a> page.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Struts 2 allows a developer to configure <a class="jive-link-external-small" href="http://struts.apache.org/release/2.3.x/docs/wildcard-mappings.html">wildcard mappings</a> in its XML configuration files. The blank-archetype application has the following wildcard example in its XML configuration:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:364cb06a-57f0-48b3-a7f5-b19eeecc0b9f][excluded]--><pre class="xml" name="code">
&lt;action name="*" class="tutorial2.example.ExampleSupport"&gt;
&nbsp; &lt;result&gt;/example/{1}.jsp&lt;/result&gt;
&lt;/action&gt;</pre><!--[CodeBlockEnd:364cb06a-57f0-48b3-a7f5-b19eeecc0b9f]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>This allows one to specify an arbitrary Action name. If the name doesn't match any of the other more specific mappings in the XML configuration (or possibly others annotated in the Java code), then this acts as a catch-all. The Action name provided is substituted as a component of the file name. Struts then dispatches to the selfsame JSP defined in the <a class="jive-link-external-small" href="http://struts.apache.org/release/2.3.x/docs/result-types.html">result</a> section.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>Vulnerability and Exploit</h2><p>There exists a vulnerability in this Action name to replacement mapping. If the Action name provided is in the form of <code>${STUFF_HERE}</code> or <code>%{STUFF_HERE}</code>, and the contents of the expression are <a class="jive-link-external-small" href="http://struts.apache.org/release/2.3.x/docs/ognl.html">OGNL</a>, then Struts2 unsafely double evaluates the contents.</p><p>To view this exploit, start up the blank-archetype application using <code>jetty:run</code>. The <a class="jive-link-external-small" href="http://127.0.0.1:8080/struts2-blank/example/${%23context['xwork.MethodAccessor.denyMethodExecution']=%21%28%23_memberAccess['allowStaticMethodAccess']=true%29,%28@java.lang.Runtime@getRuntime%28%29%29.exec%28'touch%20aaa'%29.waitFor%28%29}.action/">following URL</a> exploits a vulnerability within the replacement support in Struts 2. If the exploit is successful, something similar to the following should be displayed:</p><blockquote class="jive-quote"><h1>HTTP ERROR 404</h1><p>Problem accessing /struts2-blank/example/0.jsp. Reason:</p><p><code>Not Found</code></p></blockquote><p>Note the "0.jsp" part in the 404 page. When successfully executed, <a class="jive-link-external-small" href="http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html#waitFor()"><code>Process.waitFor</code></a> returns a value of "0". This is then used as the JSP file name, "0.jsp". This implies the <code>touch aaa</code> executed successfully. A patched version doesn't have a return value since the process never executed.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>Root Cause Analysis</h2><p>Using <a class="jive-link-external-small" href="https://www.aspectsecurity.com/research/appsec_tools/javasnoop/">JavaSnoop</a>, instrumenting the blank-archetype application application, and setting canaries for strings to match against the payload URL showed numerous potential traces. Scoping the trace to <code>org.apache.struts2</code> packages shows an interesting call to <a class="jive-link-external-small" href="https://github.com/apache/struts2/tree/STRUTS_2_3_14/core/src/main/java/org/apache/struts2/dispatcher/StrutsResultSupport.java#L196">StrutsResultSupport.conditionalParse</a>:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:e6adf083-516d-4bfe-8f6f-939f02ab2250][excluded]--><pre class="java" name="code">
/**
* Parses the parameter for OGNL expressions against the valuestack
*
* @param param The parameter value
* @param invocation The action invocation instance
* @return The resulting string
*/
protected String conditionalParse(String param, ActionInvocation invocation) {
&nbsp;&nbsp;&nbsp; if (parse &amp;&amp; param != null &amp;&amp; invocation != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return TextParseUtil.translateVariables(param, invocation.getStack(),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new TextParseUtil.ParsedValueEvaluator() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Object evaluate(String parsedValue) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (encode) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (parsedValue != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // use UTF-8 as this is the recommended encoding by W3C to
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // avoid incompatibilities.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return URLEncoder.encode(parsedValue, "UTF-8");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(UnsupportedEncodingException e) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (LOG.isWarnEnabled()) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOG.warn("error while trying to encode ["+parsedValue+"]", e);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return parsedValue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });
&nbsp;&nbsp;&nbsp; } else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return param;
&nbsp;&nbsp;&nbsp; }
}</pre><!--[CodeBlockEnd:e6adf083-516d-4bfe-8f6f-939f02ab2250]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The method above is called from the <code>StrutsResultSupport.execute(ActionInvocation)</code>. It then calls <a class="jive-link-external-small" href="https://github.com/apache/struts2/tree/STRUTS_2_3_14/xwork-core/src/main/java/com/opensymphony/xwork2/util/TextParseUtil.java#L70"><code>TextParseUtil.translateVariables</code></a>:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:133a456b-32a8-40f8-86dd-80876410b5aa][excluded]--><pre class="java" name="code">
/**
* Function similarly as {@link #translateVariables(char, String, ValueStack)}
* except for the introduction of an additional &lt;code&gt;evaluator&lt;/code&gt; that allows
* the parsed value to be evaluated by the &lt;code&gt;evaluator&lt;/code&gt;. The &lt;code&gt;evaluator&lt;/code&gt;
* could be null, if it is it will just be skipped as if it is just calling
* {@link #translateVariables(char, String, ValueStack)}.
*
* &lt;p/&gt;
*
* A typical use-case would be when we need to URL Encode the parsed value. To do so
* we could just supply a URLEncodingEvaluator for example.
*
* @param expression
* @param stack
* @param evaluator The parsed Value evaluator (could be null).
* @return the parsed (and possibly evaluated) variable String.
*/
public static String translateVariables(String expression, ValueStack stack, ParsedValueEvaluator evaluator) {
&nbsp; return translateVariables(new char[]{'$', '%'}, expression, stack, String.class, evaluator).toString();
}</pre><!--[CodeBlockEnd:133a456b-32a8-40f8-86dd-80876410b5aa]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>This method evaluates expressions surrounded with <code>${}</code> or <code>%{}</code>. The subsequent call to <a class="jive-link-external-small" href="https://github.com/apache/struts2/tree/STRUTS_2_3_14/xwork-core/src/main/java/com/opensymphony/xwork2/util/TextParseUtil.java#L154"><code>translateVariables</code></a> method evaluates the expression via the <code>parser.evaluate</code> call:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:c7bb0787-d647-4028-8bbd-32d77e1a02d0][excluded]--><pre class="java" name="code">
/**
* Converted object from variable translation.
*
* @param open
* @param expression
* @param stack
* @param asType
* @param evaluator
* @return Converted object from variable translation.
*/
public static Object translateVariables(char[] openChars, String expression, final ValueStack stack, final Class asType, final ParsedValueEvaluator evaluator, int maxLoopCount) {
&nbsp;&nbsp;&nbsp; ParsedValueEvaluator ognlEval = new ParsedValueEvaluator() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Object evaluate(String parsedValue) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object o = stack.findValue(parsedValue, asType);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (evaluator != null &amp;&amp; o != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o = evaluator.evaluate(o.toString());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return o;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; };
&nbsp;&nbsp;&nbsp; TextParser parser = ((Container)stack.getContext().get(ActionContext.CONTAINER)).getInstance(TextParser.class);
&nbsp;&nbsp;&nbsp; XWorkConverter conv = ((Container)stack.getContext().get(ActionContext.CONTAINER)).getInstance(XWorkConverter.class);
&nbsp;&nbsp;&nbsp; Object result = parser.evaluate(openChars, expression, ognlEval, maxLoopCount);
&nbsp;&nbsp;&nbsp; return conv.convertValue(stack.getContext(), result, asType);
}</pre><!--[CodeBlockEnd:c7bb0787-d647-4028-8bbd-32d77e1a02d0]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>That passes the expression to an instance of <a class="jive-link-external-small" href="https://github.com/apache/struts2/tree/STRUTS_2_3_14/xwork-core/src/main/java/com/opensymphony/xwork2/util/OgnlTextParser.java#L10"><code>OgnlTextParser.evaluate</code></a>. And then it's game over.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h3>Other Vectors</h3><p>Suspicious calls to <code>TextParseUtil.translateVariables</code> were also examined for exploitability.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h4>org.apache.struts2.dispatcher.HttpHeaderResult.execute (Tested)</h4><p><a class="jive-link-external-small" href="https://github.com/apache/struts2/tree/STRUTS_2_3_14/core/src/main/java/org/apache/struts2/dispatcher/HttpHeaderResult.java#L185"><code>HttpHeaderResult.execute</code></a> has the following call to <code>TextParseUtil.translateVariables</code>:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:dc50968e-ae81-4d5c-8af4-7512e94772f7][excluded]--><pre class="java" name="code">
if (headers != null) {
&nbsp;&nbsp;&nbsp; for (Map.Entry&lt;String, String&gt; entry : headers.entrySet()) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String value = entry.getValue();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String finalValue = parse ? TextParseUtil.translateVariables(value, stack) : value;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.addHeader(entry.getKey(), finalValue);
&nbsp;&nbsp;&nbsp; }
}</pre><!--[CodeBlockEnd:dc50968e-ae81-4d5c-8af4-7512e94772f7]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The blank-archetype application's HelloWorld XML example was modified below to test out the call. This is probably a very unlikely scenario and also can be mitigated by the <code>&lt;param name="parse"&gt;false&lt;/param&gt;</code> setting. (By default, this value is true.) In this case, the <code>${message}</code> value is user-controllable within the <code>HelloWorld</code> class. This tainted value is then supplied as a header. While it's an obvious header injection, it's also a RCE vector.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:9d4cdc98-2dc5-4ea6-81a1-f70242ce0842][excluded]--><pre class="xml" name="code">
&lt;action name="HelloWorld" class="com.coverity.internal.examples.example.HelloWorld"&gt;
&nbsp; &lt;result name="success"&gt;/example/HelloWorld.jsp&lt;/result&gt;
&nbsp; &lt;result name="foobar" type="httpheader"&gt;
&nbsp;&nbsp;&nbsp; &lt;param name="headers.foobar"&gt;${message}&lt;/param&gt;
&nbsp; &lt;/result&gt;
&lt;/action&gt;</pre><!--[CodeBlockEnd:9d4cdc98-2dc5-4ea6-81a1-f70242ce0842]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h4>org.apache.struts2.views.util.DefaultUrlHelper.* (Tested)</h4><p>Pretty much every method in the <a class="jive-link-external-small" href="https://github.com/apache/struts2/tree/STRUTS_2_3_14/core/src/main/java/org/apache/struts2/views/util/DefaultUrlHelper.java"><code>DefaultUrlHelper</code></a> class allows for RCE if one of the parameters is tainted. This is because of the <a class="jive-link-external-small" href="https://github.com/apache/struts2/blob/STRUTS_2_3_14/core/src/main/java/org/apache/struts2/views/util/DefaultUrlHelper.java#L281"><code>DefaultUrlHelper.translateVariable</code></a> method is called by most methods in the class. This class is also heavily utilized throughout Struts2 as the default UrlHelper class via <a class="jive-link-external-small" href="http://struts.apache.org/release/2.3.x/docs/struts-defaultxml.html">struts-default.xml</a>.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Here is an instance of the defect, mocked up from the blank-archetype application HelloWorld.jsp:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:28c8912b-2d9a-46ba-a3f6-2d6f5581eb2b][excluded]--><pre class="xml" name="code">
&lt;s:url id="url" action="HelloWorld"&gt;
&nbsp;&nbsp;&nbsp; &lt;s:param name="request_locale"&gt;&lt;s:property value="message"/&gt;&lt;/s:param&gt;
&lt;/s:url&gt;</pre><!--[CodeBlockEnd:28c8912b-2d9a-46ba-a3f6-2d6f5581eb2b]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Assume the <code>s:property</code> 'message' is tainted via <code>?message=${OGNL_HERE}</code>. Since the <code>s:url</code> / URL component uses the <code>DefaultUrlHandler.urlRenderer</code> (via <code>ServletUrlRenderer</code>), the parameter is double evaluated as OGNL.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h4>org.apache.struts2.util.URLBean.getURL (Untested)</h4><p><a class="jive-link-external-small" href="http://struts.apache.org/release/2.3.x/struts2-core/apidocs/org/apache/struts2/util/URLBean.html">URLBean</a> seems to mainly be used in Velocity via a macro. If URLBean is called w/o a <code>setPage()</code> method and either the <code>addParameter()</code> method contains tainted data or no <code>addParameter()</code> method calls occur, then URLBean seems susceptible to RCE via the DefaultUrlHelper issue above.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h3>Non-Vectors</h3><p>Some potential vectors that seemed to double evaluate OGNL were tested but found not to be exploitable using this technique.</p><p>When the action name is used as a replacement value within the <code>method</code> attribute of the Action, the replacement value is not double evaluated. Rather, the unevaluated value is passed as a method name via reflection. The blank-archetype application has this example, which is not exploitable:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:d0a71957-89d6-4ca7-a51b-14db111aa704][excluded]--><pre class="xml" name="code">
&lt;action name="Login_*" method="{1}" class="tutorial.example.Login"&gt;
&nbsp; &lt;result name="input"&gt;/example/Login.jsp&lt;/result&gt;
&nbsp; &lt;result type="redirectAction"&gt;Menu&lt;/result&gt;
&lt;/action&gt;</pre><!--[CodeBlockEnd:d0a71957-89d6-4ca7-a51b-14db111aa704]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Another non-vector tested in the blank-archetype application is to enable <a class="jive-link-external-small" href="http://struts.apache.org/release/2.3.x/docs/action-configuration.html#ActionConfiguration-DynamicMethodInvocation">Dynamic Method Invocation</a>. Then modify HelloWorld Action mapping in the blank-archetype application as follows:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:5d0ab651-5af1-49c5-ad00-0698df5c776b][excluded]--><pre class="xml" name="code">
&lt;action name="HelloWorld" class="tutorial.example.HelloWorld"&gt;
&nbsp; &lt;result&gt;/example/${message}.jsp&lt;/result&gt;
&lt;/action&gt;</pre><!--[CodeBlockEnd:5d0ab651-5af1-49c5-ad00-0698df5c776b]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Finally, call the <code>getMessage</code> function on the HelloWorld Action (<code>HelloWorld!getMessage?message=${PAYLOAD}</code>). Test stack traces didn't show the OGNL expression being evaluated twice.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h3>Untested</h3><p><a class="jive-link-external-small" href="http://struts.apache.org/release/2.3.x/docs/convention-plugin.html#ConventionPlugin-Annotationreference">Struts2 annotations</a> may be susceptible but have not been tested.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>Testing</h2><p>Outside of testing for vulnerable versions of Struts 2, testers can use a blind-ish dynamic technique:</p><ul><li>Identify Actions (usually via a .action suffix) and fingerprint responses to the Actions. For this example URL <code><a class="jive-link-external-small" href="http://www.example.com/app/Bar.action">http://www.example.com/app/Bar.action</a></code>, the Action name is <code>Bar</code>.</li><li>For each Action, substitute the Action name&nbsp; with <code>ACTION_NAME</code> in the following expression: <code>$%7B%23foo='ACTION_NAME',%23foo%7D</code>. For example: <code>$%7B%23foo='Bar',%23foo%7D</code>.</li><li>Replace the Action name in the URL with the substituted expression. For example: <code><a class="jive-link-external-small" href="http://www.example.com/app/$%7B%23foo='Bar',%23foo%7D.action">http://www.example.com/app/$%7B%23foo='Bar',%23foo%7D.action</a></code>.</li><li>If the Action is susceptible to this double evaluation vector, the application ought to return the same page as before. If it's not vulnerable, a 404 or other page will probably be returned.</li></ul><p>To test out the <code>Welcome.action</code> blank-archetype above via <code>jetty:run</code>, use <a class="jive-link-external-small" href="http://127.0.0.1:8080/struts2-blank/example/$%7B%23foo='Welcome',%23foo%7D">this URL</a>.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>Remedy</h2><p>Struts developers recommend upgrading to 2.3.14.2. Refer to <a class="jive-link-external-small" href="http://struts.apache.org/development/2.x/docs/s2-013.html">S2-013</a> and <a class="jive-link-external-small" href="http://struts.apache.org/development/2.x/docs/s2-014.html">S2-014</a> for details. The Struts developers mitigate the effects of double evaluation. While double evaluation still occurs within the sample application, remote code execution is not possible using @meder's vector.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>Maven Appendix</h2><p>First, <a class="jive-link-external-small" href="http://maven.apache.org/download.cgi">get Maven</a>. Then create an application based on the <a class="jive-link-external-small" href="http://struts.apache.org/development/2.x/docs/struts-2-blank-archetype.html">blank-archetype</a>.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:bc639c25-9994-47e7-a77a-b381717618a0][excluded]--><pre class="plain" name="code">
mvn archetype:generate -B -DgroupId=tutorial -DartifactId=tutorial -DarchetypeGroupId=org.apache.struts -DarchetypeArtifactId=struts2-archetype-blank
cd tutorial&nbsp; # ensure the struts2 entry in the pom.xml points to 2.3.14
mvn package jetty:run</pre><!--[CodeBlockEnd:bc639c25-9994-47e7-a77a-b381717618a0]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>To test out the application, try accessing the <code>Welcome</code> Action by navigating to <a class="jive-link-external-small" href="http://127.0.0.1:8080/struts2-blank/example/Welcome.action">following URL</a>.</p></div><!-- [DocumentBodyEnd:0f961638-c88b-4e51-aaa0-42fa5809d035] -->security-research-laboratoryjavastruts2remote-code-executionWed, 29 May 2013 16:08:40 GMThttps://communities.coverity.com/blogs/security/2013/05/29/struts2-remote-code-execution-via-ognl-injectionJon Passki2013-05-29T16:08:40Z2 years, 2 months ago80https://communities.coverity.com/blogs/security/comment/struts2-remote-code-execution-via-ognl-injectionhttps://communities.coverity.com/blogs/security/feeds/comments?blogPost=1305Angular Template Injectionhttps://communities.coverity.com/blogs/security/2013/04/23/angular-template-injection
<!-- [DocumentBodyStart:4cbb740a-eafd-4c80-8113-eb0195b042bb] --><div class="jive-rendered-content"><p>As part of our work at Coverity, the Security Research Laboratory (SRL) performs security reviews of our own software. Last week I had a look at some of the new code in our reporting webapp. It turned out that we were using some technologies and vulnerable code patterns I had not seen before, so I thought I would share what I saw with the world in case anyone sees the same pattern I did.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>As I began to review this code for the first time, I identified a series of <a class="jive-link-external-small" href="https://developers.google.com/closure/templates/">Closure Templates</a> that were being used to generate HTML output, with the usual <code>{$modelKey.property}</code> syntax being used to insert model values into the output. After a little bit of looking around, I saw that they hadn't changed Closure's default escaping away from HTML escaping, and they were also not putting these properties into any contexts where HTML escaping was incorrect.</p><p>However, I also noticed that there was a lot of syntax similar to <code>{literal}{{modelVar.property}}{/literal}</code> and many HTML attributes such as <code>ng-repeat</code> that I hadn't seen before.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Somewhat confused by this, I dug a bit further and discovered that rather than being directly displayed, the output of these views was being passed to a JavaScript framework called Angular.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>If you are like me and have never heard of Angular before, it seems to be a complete MVC framework for JavaScript and it turned out that our HTML output was actually being used as the views for Angular.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Like most server-side MVC, most of the view in Angular is plain old HTML. Angular augments this by a <a class="jive-link-external-small" href="http://docs.angularjs.org/api">series of directives</a> that are specified as attributes (e.g., the <code>ng-repeat</code> attribute I had seen) and the ability to bind data into attributes or right into HTML as <a class="jive-link-external-small" href="http://docs.angularjs.org/guide/expression">Angular expressions</a>. So the <code>{literal}{{modelVar.property}}{/literal}</code> I was seeing in our Closure Templates was being output as <code>{{modelVar.property}}</code> and being consumed by Angular, which was binding the values from its own model in there.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>So, in my eternal quest for more XSS, I went to investigate what would happen if a user was able to inject <code>{{}}</code> expressions into an Angular template. I was convinced that this would let me XSS our application somehow.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>After digging a bit, it turns out that Angular doesn't simply <code>eval()</code> these expressions, but rather has its own expression tokenizer/evaluator written in JavaScript.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The things that this evaluator supports are:</p><ul><li>Model access: <code>{{modelVar}}</code></li><li>Field access: <code>{{modelVar.field}}</code></li><li>Function calls: <code>{{modelVar.function(1)}}</code></li><li>Built-in filter functions: <code>{{ modelVar | json }}</code></li><li>Arithmetic and logical operators: <code>{{1+2}}</code>, <code>{{true&amp;&amp;false}}</code>, etc.</li><li>Object and Array constructors: <code>{{ {name: 'test'} }}</code></li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The first thing I tried was to find a filter function that would allow me to somehow execute JavaScript, but after reviewing the built-in filter functions as well as the ones our application injected, I determined this wasn't going to work.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>One of the filters our application created was called <code>autoescape</code>, which did some HTML escaping and was being applied to some data like <code>{{tts.get('id')|autoescape}}</code> which made me wonder if I could have my XSS by creating an expression that would return <code>&lt;script&gt;alert(1)&lt;/script&gt;</code> without using any characters that would be encoded on the server side. Using <a class="jive-link-external-small" href="http://jsfiddle.net/yHaNU/">this JsFiddle</a> to test what would happen if I could I could get an expression that returned an XSS string, I realized that this too was a dead end for my XSS dreams.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>So I decided to review the expression parser to see what was going on in there, and if anything looked sketchy. I discovered that the underlying objects that Angular was using in its expressions were native JavaScript objects (rather than providing their own custom object model, which some view technologies do); so field access was implemented by simply accessing the native fields of an object. This was interesting because besides properties you assign to an object, native objects will have several other fields attached.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>After staring at the <a class="jive-link-external-small" href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/prototype">MDN</a> for a bit, I discovered the same thing that many before me had discovered:</p><p><code>{}.toString.constructor('alert(1)')</code> creates a new function from a string by invoking the <a class="jive-link-external-small" href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function">Function constructor</a>.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>So to wrap this all up, if you can inject <code>{{}}</code> into an angular template, the following will execute JavaScript when data values are bound into the template:</p><pre><code>{{{}.toString.constructor('alert(1)')()}} </code></pre><p>And now our developers have one more XSS to fix before the code ships to our customers. If you'd like to play around with it yourself, I've set-up <a class="jive-link-external-small" href="http://jsfiddle.net/ZfCbN/">another jsFiddle</a> with the payload already working.</p></div><!-- [DocumentBodyEnd:4cbb740a-eafd-4c80-8113-eb0195b042bb] -->injectionjavascriptTue, 23 Apr 2013 16:13:54 GMThttps://communities.coverity.com/blogs/security/2013/04/23/angular-template-injectionAlex Kouzemtchenko2013-04-23T16:13:54Z2 years, 3 months ago70https://communities.coverity.com/blogs/security/comment/angular-template-injectionhttps://communities.coverity.com/blogs/security/feeds/comments?blogPost=1300RSA 2013 speaking sessionhttps://communities.coverity.com/blogs/security/2013/02/27/rsa-2013-speaking-session
<!-- [DocumentBodyStart:20c7d4d0-61ce-456e-873b-bcbb158ae129] --><div class="jive-rendered-content"><p><strong>Update March 1st:</strong> Since the PDF on RSA website seems broken, I have attached a version to this blog post.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p style="text-align: center;">---</p><p style="text-align: center;"></p><p>I'll be at RSA this week. My session is Friday morning (10:20am, Room 132) and is called:</p><blockquote class="jive-quote">
<p>Why haven't we stamped out XSS and SQL yet?</p>
</blockquote><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>RSA talk content</h2><p>Since all the slides are apparently available for everyone on the RSA website, I can give some more insight about what I will be talking about. We ran an experiment at Coverity in which we analyzed many Java web applications and looked for where developers add dynamic data. The goal was to try to understand what contexts (both HTML contexts and SQL contexts) are frequently used.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The tone of the talk is fairly straightforward: security pros. have been giving advice to developers for a long time, yet we still have these issues on a frequent basis, so we map common advice with what we see from the data.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>What you can expect from this talk:</p><ul><li>Some information about observed HTML contexts: that's about <strong>26 different contexts stacks</strong>, 45% of them had 2 elements in the stack (e.g., HTML attribute -&gt; CSS code), and the longest ones had 3 elements.</li><li>A list of SQL contexts and good notes about what developers usually do.</li><li>Advice for security pros. on how to communicate with developers (things that led to the creation of our <a class="jive-link-external-small" href="http://www.coverity.com/srl/a-guide-to-fixing-xss-for-devs.html">Fixing XSS: A practical guide for developers</a> document).</li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Anyhow, this blog post is not only to announce this talk, but also to give some insight on how we extracted the data from these applications.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>Analysis technique</h2><p>We created and modified different checkers from Coverity <a class="jive-link-external-small" href="http://www.coverity.com/products/security-advisor.html">Security Advisor</a> in order to extract all injection sites that are related to dynamic data regardless of its taintedness. For each injection site, we computed the context in which it belonged to the sub language (one of HTML, JavaScript, CSS, SQL, HQL, and JQPL). This represents our working dataset.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Here's an example of an injection site (using JSP and EL):</p><!--[CodeBlockStart:f3ae8c3e-0540-4c96-b224-b95fe124c03d][excluded]--><pre class="javascript" name="code">
&lt;script type="text/javascript"&gt;
var content = '${dynamic_data}';
// context ::= {HTML SCRIPT TAG -&gt; JS STRING}
&lt;/script&gt;
</pre><!--[CodeBlockEnd:f3ae8c3e-0540-4c96-b224-b95fe124c03d]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>We tracked the construction of this snippet of the HTML page and recorded the injection site such as <span style="font-family: terminal, monaco; font-size: 8pt;">${dynamic_data}</span> and its associated context (JS STRING inside HTML SCRIPT TAG). Since we do not care about the taintedness of dynamic_data, we didn't need to track all paths that could lead to a defect (XSS here), and that's where what we did is very different from our XSS checker.</p><p>Note that we still needed to properly track parts of the HTML page that's being constructed to properly compute the context. This is however part of our context-aware global data flow analysis...</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>For SQL related queries, we essentially needed to do the same thing, but we also needed to track the parameters being inserted in a query using a parameterized notation: remember, we needed to find all dynamic data that could eventually go into a query.</p><p>That's why the following code:</p><!--[CodeBlockStart:50204734-dcc1-40ce-b02d-0efcb4b16da1][excluded]--><pre class="java" name="code">
String sql = "select foo, bar from table where 1=1";
if (cond1)
&nbsp; sql += " and user='" + user_name + "'"; // context ::= {SQL_STRING}
if (cond2)
&nbsp; sql += " and password=?"; // context ::= {SQL_DATA_VALUE}
</pre><!--[CodeBlockEnd:50204734-dcc1-40ce-b02d-0efcb4b16da1]--><div style="display:none;"></div><p>has 2 interesting injection sites for the experiment, and we didn't need to understand the full abstract string (an eventual set of 4 possible strings) from this piece of code.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Note that if there is this fairly common construct:</p><!--[CodeBlockStart:35d1cc14-45f7-43e4-8b83-87cfd755339c][excluded]--><pre class="java" name="code">
String sql1 = "select foo, bar from table where ";
String and_beg = " and (";
String and_end = " ) ";
sql1 += and_beg + "user = '" + user_name + "'" + and_end;
sql1 += sql2; // `sql2` is another part of the query coming
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // from a different procedure or so
</pre><!--[CodeBlockEnd:35d1cc14-45f7-43e4-8b83-87cfd755339c]--><div style="display:none;"></div><p>we will still properly track the contexts even if all parts (sql1, and_beg, etc.) are inter-procedurally created.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h3>Limitations</h3><p>I will quickly explain this during the talk, but essentially tracking HTML contexts on a global data flow analysis is not a trivial thing. Moreover, considering the impact of some JavaScript code on the resulting web page (and therefore where the HTML contexts could potentially be transformed at runtime) is an even more complex problem. We did not analyze JavaScript.</p></div><!-- [DocumentBodyEnd:20c7d4d0-61ce-456e-873b-bcbb158ae129] -->security-research-laboratoryhtmltalkWed, 27 Feb 2013 23:12:31 GMThttps://communities.coverity.com/blogs/security/2013/02/27/rsa-2013-speaking-sessionRomain Gaucher2013-02-27T23:12:31Z2 years, 5 months ago0https://communities.coverity.com/blogs/security/comment/rsa-2013-speaking-sessionhttps://communities.coverity.com/blogs/security/feeds/comments?blogPost=1283Fixing XSS: A practical guide for developershttps://communities.coverity.com/blogs/security/2013/02/26/fixing-xss-a-practical-guide-for-developers
<!-- [DocumentBodyStart:374494e9-fa68-4831-a392-96a87bee350d] --><div class="jive-rendered-content"><p>I'm happy to announce a new document we just made available: <a class="jive-link-external-small" href="http://www.coverity.com/srl/a-guide-to-fixing-xss-for-devs.html">Fixing XSS: a practical guide for developers</a>. If you're currently at the RSA conference, you should come to Coverity's booth (#1759) and either get a hardcopy or a USB stick with this document on it.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>As the title suggests, this document is a guide for developers on how to handle dynamic data in various locations and common constructs in HTML. We leveraged the data we got from our research for our talk at RSA to come up with some of the most <a class="jive-link-external-small" href="http://www.coverity.com/srl/a-guide-to-fixing-xss-for-devs.html#nested-contexts-will-blow-your-mind">common HTML contexts and nested contexts</a>, and improved the <a class="jive-link-external-small" href="https://github.com/coverity/coverity-security-library">Coverity Security Library</a> to have a solution for all of these cases.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Looking at the documentation available for XSS, several things strike us:</p><ol><li>It often talks about how to exploit an XSS and not how to fix this issue.</li><li>The HTML contexts information is always lacking precision and often makes the documentation complex to read (we're also guilty of this in some previous blog posts).</li><li>The fixes are limited or too restrictive (i.e., not applicable for developers).</li></ol><p>That's mostly why we decided to create our own document for developers.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The first release of this document contains <strong>13 common HTML constructs</strong>, and we plan on adding more to it. We also describe what HTML contexts are and why it's important to think about them when outputting dynamic data in a web page. However, we also want to create collateral that gives more complete information about HTML contexts and why it matters for XSS.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>In this document, you can expect to learn what happens when you want to add dynamic data in a HTML context such as <a class="jive-link-external-small" href="http://www.coverity.com/srl/a-guide-to-fixing-xss-for-devs.html#html-inside-javascript-string">HTML snippet inside a JavaScript string</a>:</p><!--[CodeBlockStart:5f932081-eb2a-4a17-89e4-b90f54ca7303][excluded]--><pre class="javascript" name="code">
&lt;div id="forMyContent"&gt;&lt;/div&gt;
&lt;script&gt;
&nbsp; var foo = "&lt;h1&gt;${cov:jsStringEscape(cov:htmlEscape(content))}&lt;/h1&gt;";
&nbsp; $("#forMyContent")
&nbsp; .html(foo);
&lt;/script&gt;
</pre><!--[CodeBlockEnd:5f932081-eb2a-4a17-89e4-b90f54ca7303]--><div style="display:none;"></div><p>and why you need to first use an HTML escaper, then a JavaScript string escaper.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>You'll also see the usage of a newly introduced function <span style="font-family: terminal, monaco; font-size: 8pt;">asUrl</span> from CSL that helps writing <a class="jive-link-external-small" href="http://www.coverity.com/srl/a-guide-to-fixing-xss-for-devs.html#url-inside-html-attribute">fully dynamic URLs inside an HTML attribute</a> such as:</p><!--[CodeBlockStart:bfc5afc4-c5c0-48e6-bf51-aff5afbd8850][excluded]--><pre class="javascript" name="code">
&lt;a href="${cov:htmlEscape(cov:asURL(content))}"&gt;
&nbsp; Click me
&lt;/a&gt;
</pre><!--[CodeBlockEnd:bfc5afc4-c5c0-48e6-bf51-aff5afbd8850]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The current document uses the Java Expression Language (EL) notation to show the dynamic data (here <span style="font-family: terminal, monaco; font-size: 8pt;">${content}</span>), but all functions are also available directly from Java when using CSL.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Whether you develop web applications, have developers, or do security review, you should read and share this document. We're also happy to receive any feedback to keep improving this document.</p></div><!-- [DocumentBodyEnd:374494e9-fa68-4831-a392-96a87bee350d] -->coverity-security-librarysecurity-research-laboratorysecurityhtmlxssweb-securityTue, 26 Feb 2013 18:59:48 GMThttps://communities.coverity.com/blogs/security/2013/02/26/fixing-xss-a-practical-guide-for-developersRomain Gaucher2013-02-26T18:59:48Z2 years, 5 months ago20https://communities.coverity.com/blogs/security/comment/fixing-xss-a-practical-guide-for-developershttps://communities.coverity.com/blogs/security/feeds/comments?blogPost=1288Announcing Coverity Security Library v1.1.1https://communities.coverity.com/blogs/security/2013/02/26/coverity-security-library-v12
<!-- [DocumentBodyStart:d70f9f71-c303-49c9-b4f7-13507d71c27b] --><div class="jive-rendered-content"><p>We've released a new version of our <a class="jive-link-external-small" href="https://github.com/coverity/coverity-security-library/">Coverity Security Library on Github</a> and Maven Central, and I'd like to talk a bit about the addition I made of a new class called <span style="font-family: terminal, monaco; font-size: 8pt;">Filter</span>. I would also like to note that you should not use v1.1 due to an issue described later. Some of the implementation decisions I made are arguable, so I would really like to hear the community's thoughts on these. So if you're at RSA, feel free to swing by Booth #1759 at RSA on Tuesday to grill me or the rest of SRL about it.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The implementation of this Filter class is located in <a class="jive-link-external-small" href="https://github.com/coverity/coverity-security-library/blob/develop/coverity-escapers/src/main/java/com/coverity/security/Filter.java">coverity-escapers/src/main/java/com/coverity/security/Filter.java</a></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The Filter class contains a few methods which are not technically escapers, but serve a very similar purpose, namely the main methods we have added are:</p><ul><li><span style="font-family: terminal, monaco; font-size: 8pt;">Filter.asURL</span></li><li><span style="font-family: terminal, monaco; font-size: 8pt;">Filter.asNumber</span></li><li><span style="font-family: terminal, monaco; font-size: 8pt;">Filter.asCssColor</span></li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>They have been added since these are the most common contexts we have seen that do not have a defined escaper. To give a clearer picture of what I mean, have a look at this code snippet which shows some potential usage (via Java EL):</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:adf10bd0-4df8-4afa-b23c-7caeb6aa425b][excluded]--><pre class="java" name="code">
&lt;%@ taglib uri="http://coverity.com/security" prefix="cov" %&gt;
&lt;iframe src="${cov:htmlEscape(asURL(param.taintedURL))}"&gt; &lt;/iframe&gt;
&lt;script type="text/javascript"&gt;
&nbsp;&nbsp;&nbsp; var x = ${cov:asNumber(param.taintedNumber)};
&lt;/script&gt;
&lt;style&gt;
.user {
&nbsp;&nbsp;&nbsp; background-color: ${cov:asCssColor(param.taintedColor)};
}
&lt;/style&gt;</pre><!--[CodeBlockEnd:adf10bd0-4df8-4afa-b23c-7caeb6aa425b]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>These three contexts present different problems, but essentially, there is obviously no way to turn an arbitrary string into a number of valid CSS color, and URLs face their own problems we'll get into a little bit later.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>asNumber / asCssColor</h2><p>These two functions validate the string passed is a valid number or CSS color. If the string does not pass that validation, then instead of throwing an exception we return a default value.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>For <span style="font-family: terminal, monaco; font-size: 8pt;">asCssColor</span>, our choice for a default is slightly hacky, since we chose to return the string <span style="font-family: terminal, monaco; font-size: 8pt;">invalid</span>. I specifically chose this string, since it is an invalid CSS color, but one that we know is safe, and seems somewhat descriptive in the HTML output. The reason for choosing an invalid CSS color as the default string is that the CSS parser will simply ignore this single directive, and continue parsing the remaining CSS as if it had never encountered the invalid directive.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The main contender for an alternative was <span style="font-family: terminal, monaco; font-size: 8pt;">inherit</span>, which is the default value when specifying the text color in CSS. However the default value for <span style="font-family: terminal, monaco; font-size: 8pt;">background-color</span> directive is <span style="font-family: terminal, monaco; font-size: 8pt;">transparent</span> instead of <span style="font-family: terminal, monaco; font-size: 8pt;">inherit</span>, so choosing one or the other would lead to slightly (more) broken pages.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The default for <span style="font-family: terminal, monaco; font-size: 8pt;">asNumber</span> is 0. The other alternatives considered were <span style="font-family: terminal, monaco; font-size: 8pt;">null</span> and <span style="font-family: terminal, monaco; font-size: 8pt;">NaN</span>, but since we couldn't be sure what context <span style="font-family: terminal, monaco; font-size: 8pt;">asNumber</span> would be called for (e.g. JavaScript, CSS, HTML attribute), we decided it would be more correct to simply choose a number that should not have a huge effect.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Since these values are potentially contentious, we have also provided a version of these functions where you can specify your own default value (check out the <span style="font-family: terminal, monaco; font-size: 8pt;">Filter</span> and <span style="font-family: terminal, monaco; font-size: 8pt;">FilterEL</span> classes).</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The other potentially contentious thing I have implemented in <span style="font-family: terminal, monaco; font-size: 8pt;">asNumber</span> is removing support for octal numbers. In JavaScript, the following will alert the value 511:</p><!--[CodeBlockStart:49140b35-4004-4944-a34b-d59863557ac6][excluded]--><pre class="java" name="code">
&lt;script&gt;
&nbsp; alert(0777);
&lt;/script&gt;</pre><!--[CodeBlockEnd:49140b35-4004-4944-a34b-d59863557ac6]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>This makes some sense for integer constants that a programmer has written, since they may want the octal notation. However since this is unexpected behavior for most users and not consistent across HTML/CSS, I decided to strip leading 0s from octal numbers. I think this is not only correct, but an improvement over just doing validation.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>If you have examples of where these decisions would break applications or make these filters unusable, I would love to heard about it, so we can make improvements for a later release.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>asURL / asFlexibleURL</h2><p>The main use for these functions is when you want to generate URLs that are going to be used for links and iframes, or other scenarios where <span style="font-family: terminal, monaco; font-size: 8pt;">javascript:</span>, <span style="font-family: terminal, monaco; font-size: 8pt;">data:</span>, and <span style="font-family: terminal, monaco; font-size: 8pt;">vbscript:</span> are dangerous. The main reason we have written this function is that trying to create a validation routine is quite difficult due to all the decoding that the browser does, e.g. this link will show a JavaScript alert:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:546aa678-33df-44fe-8ee1-50d60987d86c][excluded]--><pre class="plain" name="code">
&lt;a href="
jaVa
&amp;#115; cript&amp;#58; alert(1)"&gt;encoding&lt;/a&gt;</pre><!--[CodeBlockEnd:546aa678-33df-44fe-8ee1-50d60987d86c]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>On top of this, HTML is not the only context URLs will be written into, JavaScript is a big contender:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:5cfb2e99-2423-4853-a418-9430018b9d2c][excluded]--><pre class="plain" name="code">
&lt;script&gt;
document.location = "jaVascr ipt\
\x3aalert(1)";
&lt;/script&gt;</pre><!--[CodeBlockEnd:5cfb2e99-2423-4853-a418-9430018b9d2c]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Note that in both those cases the whitespaces are tabs, not spaces, otherwise those examples will not work.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Anyway, the point is that trying to create a blacklist that will catch all these variants, across different contexts, without false positives, is really tricky.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>We can say that any URLs starting with the following strings are safe:</p><ul><li><span style="font-family: terminal, monaco; font-size: 8pt;">/</span> (a path that is anchored at the domain root or is scheme-relative, i.e. <span style="font-family: terminal, monaco; font-size: 8pt;">//google.com/</span>)</li><li><span style="font-family: terminal, monaco; font-size: 8pt;">\\</span> (a path to a UNC share)</li><li><span style="font-family: terminal, monaco; font-size: 8pt;">http:</span></li><li><span style="font-family: terminal, monaco; font-size: 8pt;">https:</span></li><li><span style="font-family: terminal, monaco; font-size: 8pt;">ftp:</span></li><li><span style="font-family: terminal, monaco; font-size: 8pt;">mailto:</span></li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The problem with specifying such a restrictive whitelist is that you need to ask yourself what to do with any rejected URLs.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><span>One approach that we have seen in other projects, that we have taken some inspiration from, is assuming that if it is not a string with a clearly defined and well known protocol, you can rewrite it with the current web directory as a base path, e.g. on this page java/test.html <span style="font-family: terminal, monaco; font-size: 8pt;">javascript:alert(1)</span> would become </span><a class="" href="https://communities.coverity.com/blogs/security/javascript:alert(1">https://communities.coverity.com/blogs/security/javascript:alert(1</a><span>) essentially neutralising the string, but not changing the semantics of URLs such as <span style="font-family: terminal, monaco; font-size: 8pt;">java/test.html</span> (which would be rewritten as </span><a class="" href="https://communities.coverity.com/blogs/security/java\test.html">https://communities.coverity.com/blogs/security/java/test.html</a><span>).</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>During some brain storming about how to gain access to the current directory to do this rewriting, I realized that we do not actually need to know what the current URL is, since we can let the browser work it out by simply using <span style="font-family: terminal, monaco; font-size: 8pt;">./</span> as our prefix instead of the real URL. The browser will interpret this as a URL relative to the current page directory, which is exactly what the browser would have been doing before.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>So, that is the crux of our implementation of <span style="font-family: terminal, monaco; font-size: 8pt;">asURL</span>, if we can determine that this is a safe URL that is not relative to the current directory, we let it go through as is, otherwise we prepend <span style="font-family: terminal, monaco; font-size: 8pt;">./</span> effectively forcing it to be.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>However, while we think this will be ok for almost all web applications, we feel like this might be an issue for mobile, or other application scenarios where custom URL protocols are relatively common. When you actually want users to provide links to them, you can use the horribly named <span style="font-family: terminal, monaco; font-size: 8pt;">asFlexibleURL</span>.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><span style="font-family: terminal, monaco; font-size: 8pt;">asFlexibleURL</span> utilises the same approach of prepending <span style="font-family: terminal, monaco; font-size: 8pt;">./</span> to make URLs safe, but it uses a blacklist on the scheme names to decide whether it should do so. Now, as we showed above, a blacklist is a very risky thing to try and construct for every possible context, so we have taken a fairly careful approach:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><ul><li>First, we have some special case handling for URLs that start with <span style="font-family: terminal, monaco; font-size: 8pt;">/</span> or <span style="font-family: terminal, monaco; font-size: 8pt;">\\</span> since they do not have a scheme, and should not be forced to be directory-relative</li><li>Next, we find the first non-scheme character (i.e. not <span style="font-family: terminal, monaco; font-size: 8pt;">a-zA-Z0-9\.+-</span>), then if this character is a colon (<span style="font-family: terminal, monaco; font-size: 8pt;">:</span>), we convert the preceding string to lower case and check it against out blacklist (<span style="font-family: terminal, monaco; font-size: 8pt;">javascript</span>, <span style="font-family: terminal, monaco; font-size: 8pt;">data</span>, <span style="font-family: terminal, monaco; font-size: 8pt;">vbscript</span>, <span style="font-family: terminal, monaco; font-size: 8pt;">about</span>), and if it does not match the blacklist, we allow it through</li><li>In all other cases, we prepend the URL with <span style="font-family: terminal, monaco; font-size: 8pt;">./</span></li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The assumption this relies on is that you cannot do any encoding or parsing tricks with only the scheme characters, so if they are immediately followed by a colon, then we are parsing the scheme the same way a browser would. So far this seems quite safe to us, but we would appreciate feedback.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>Is this even the right approach?</h2><p>I'm pretty confident in this approach for <span style="font-family: terminal, monaco; font-size: 8pt;">asURL</span>, however there is definitely an argument to be made that number and CSS validation should be done in the general business logic validation. <span style="font-size: 10pt; line-height: 1.5em;">However, I believe in trying to fix security bugs as close the 'sink' as possible, where the sink for XSS is the document creation, since this makes being certain that you do not have any vulnerabilities much easier, and adding these functions in addition to business logic validation would work juts as well.</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>There is also the question of whether default values are the right thing, another option is to raise an exception, however this seems like an ugly solution, since small amounts of malformed input would simply break pages in the application. There is an argument to be made that these exceptions give the developer a way to notice when malformed input is being supplied and not validated, but this could just as easily be achieved by logging validation failures.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>Upgrade to version 1.1.1 not 1.1</h2><p>We pushed out a version of CSL on Friday night that contained a vulnerability in <span style="font-family: terminal, monaco; font-size: 8pt;">asFlexibleURL</span>; if an attacker were to specify a blacklisted URL that wasn't completely in lower case, the function would let it through, e.g. <span style="font-family: terminal, monaco; font-size: 8pt;">jaVascript:alert(1)</span>.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>I have changed the implementation so that the scheme validation function only ever sees lower case URLs and does not have to worry about case issues in the <span style="font-size: 10pt; line-height: 1.5em;">future.</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>I have also modified <span style="font-family: terminal, monaco; font-size: 8pt;">asURL</span> to allow mixed case URLs such as <span style="font-family: terminal, monaco; font-size: 8pt;">hTtP://www.coverity.com/</span> so that users hopefully encounter less unexpected behavior.</p></div><!-- [DocumentBodyEnd:d70f9f71-c303-49c9-b4f7-13507d71c27b] -->coverity-security-libraryTue, 26 Feb 2013 16:19:48 GMThttps://communities.coverity.com/blogs/security/2013/02/26/coverity-security-library-v12Alex Kouzemtchenko2013-02-26T16:19:48Z2 years, 5 months ago0https://communities.coverity.com/blogs/security/comment/coverity-security-library-v12https://communities.coverity.com/blogs/security/feeds/comments?blogPost=1286Interesting Links 2/19/2013https://communities.coverity.com/blogs/security/2013/02/19/interesting-links-2182013
<!-- [DocumentBodyStart:886d4455-fe40-4630-b54f-56a3f676948b] --><div class="jive-rendered-content"><p>Interesting Links has been on a bit of a hiatus, but the interesting links have just kept coming, so we're bringing this back for the moment.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>1) The last few weeks have been a pretty terrible time to be a ruby on rails admin with the vulnerabilities just pouring down, but <a class="jive-link-external-small" href="http://www.phenoelit.org/blog/archives/2013/02/05/mysql_madness_and_rails/index.html">this vulnerability found by joernchen of Phenoelit</a> is potentially the most interesting. It has what could be the makings of a new bug class for dynamically typed languages if MySQL doesn't change it's behaviour. My current conspiracy theory on where this is going to crop up next is apps in dynamically typed languages which explicitly parse JSON (or similar) and put the results into parameterised queries.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>2) Rich Lundeen continued to beat up <a class="jive-link-external-small" href="http://webstersprodigy.net/2013/02/14/mvc-antiforgery/">ASP.NET MVC's CSRF protection</a> and tease us with content for his BlackHat EU talk that I'm definitely looking forward to.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>3) Mathew Green made a post about <a class="jive-link-external-small" href="http://blog.cryptographyengineering.com/2013/02/why-i-hate-cbc-mac.html">why he hates CBC-MAC</a>, which taught me some new crypto tricks for breaking systems that use CBC-MAC. It's amazing how much real cryptographers actually know about cryptography <img height="16px" src="https://communities.coverity.com/5.0.2/images/emoticons/wink.gif" width="16px"/></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>5) The Azimuth Security blog made a comeback with two posts dissecting phone jailbreaks, with <a class="jive-link-external-small" href="http://blog.azimuthsecurity.com/2013/02/from-usr-to-svc-dissecting-evasi0n.html">Tarjei Mandt on the evasi0n jailbreak</a> for iPhones and <a class="jive-link-external-small" href="http://blog.azimuthsecurity.com/2013/02/re-visiting-exynos-memory-mapping-bug.html">Dan Rosenberg on the Framaroot jailbreak</a> for some Android handsets.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>6) While Java was the new hotness a few weeks ago a <a class="jive-link-external-small" href="http://immunityproducts.blogspot.com/2013/02/keep-calm-and-run-this-applet.html">few</a> <a class="jive-link-external-small" href="http://tyranidslair.blogspot.co.uk/">people</a> published a lot of interesting research on attacking the JVM from an Applet context, but <a class="jive-link-external-small" href="http://www.security-explorations.com/materials/se-2012-01-report.pdf">one particular report</a> from Security Explorations caught my eye for section 3.4 Remote, Server-Side Code Execution which is a pretty short read and worthwhile for anyone hacking Java code.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>7) While rooting around Mozilla's wiki I found that they're currently prototyping a client-side <a class="jive-link-external-small" href="https://wiki.mozilla.org/Security/Features/XSS_Filter">XSS Filter for Firefox</a>. This is obviously a tricky and dangerous path, but hopefully they will learn from the mistakes of other browsers and have an easier time implementing it.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>8) On the topic of browser XSS filters, Gareth Heyes has a post about about about <a class="jive-link-external-small" href="http://www.thespanner.co.uk/2013/02/19/bypassing-xss-auditor/">some bypasses he and Mario Heiderich found</a> in Chrome's XSS Auditor.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>9) Julien Tinnes sent an email to oss-sec containing an <a class="jive-link-external-small" href="http://seclists.org/oss-sec/2013/q1/326">exploit for a linux kernel race condition</a> that seems pretty neat</p></div><!-- [DocumentBodyEnd:886d4455-fe40-4630-b54f-56a3f676948b] -->linksinterestingTue, 19 Feb 2013 21:10:57 GMThttps://communities.coverity.com/blogs/security/2013/02/19/interesting-links-2182013Alex Kouzemtchenko2013-02-19T21:10:57Z2 years, 5 months ago0https://communities.coverity.com/blogs/security/comment/interesting-links-2182013https://communities.coverity.com/blogs/security/feeds/comments?blogPost=1284A New Patent on False Path Pruninghttps://communities.coverity.com/blogs/security/2013/02/05/a-new-patent-on-false-path-pruning
<!-- [DocumentBodyStart:bd34f486-cbcd-4d02-8542-76a2783be69e] --><div class="jive-rendered-content"><p><span style="font-size: 10pt; font-family: Arial; color: #454545;">I'm proud to announce Coverity has been issued a new patent <strong><em>Methods for Selectively Pruning False Paths in Graphs That Use High-Precision State Information</em></strong>.&nbsp; The patent covers techniques that apply modern solvers such as SAT and SMT to the problem of eliminating false paths in programs.&nbsp; False paths are one of the main causes of false positives in static analysis results - in our measurements of open source software, the techniques in this patent eliminates 1/3 of all false positives.</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><span style="font-size: 10pt; font-family: Arial; color: #454545;">The naive way of leveraging solvers in false path pruning analyzes only one path at a time, or converts a whole function at a time into a constraint problem.&nbsp; Both of these approaches fail on larger code bases. Real-world programs have an exponentially large number of paths, even within single functions.&nbsp; And converting entire functions doesn't scale when interprocedural analysis is needed.&nbsp; Worse, these methods don't play well with existing analysis infrastructure that is closer to dataflow analysis. The techniques in this patent address these concerns by generalizing from proofs provided by SAT/SMT solvers that certain paths are infeasible.&nbsp; The proofs isolate the core contradictions that occur between path conditions, which can then be quickly tested for on other paths.&nbsp; This can rule out an exponentially large number of infeasible paths without invoking the solver on large numbers of redundant constraint sets.</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><span style="font-size: 10pt; font-family: Arial; color: #454545;">This technology has been in Coverity's product for a few years now.&nbsp; All modern versions of Coverity Quality Advisor include this technology under the --enable-constraint-fpp option.&nbsp; It's all part of our ongoing efforts to continually improve our analysis results using the latest technologies.</span></p></div><!-- [DocumentBodyEnd:bd34f486-cbcd-4d02-8542-76a2783be69e] -->Wed, 06 Feb 2013 00:16:33 GMThttps://communities.coverity.com/blogs/security/2013/02/05/a-new-patent-on-false-path-pruningAndy Chou2013-02-06T00:16:33Z2 years, 5 months ago0https://communities.coverity.com/blogs/security/comment/a-new-patent-on-false-path-pruninghttps://communities.coverity.com/blogs/security/feeds/comments?blogPost=1278Looking for a summer intern!https://communities.coverity.com/blogs/security/2013/01/25/looking-for-a-summer-intern
<!-- [DocumentBodyStart:c0a6fa5f-b2d7-4e54-bc15-df18dcf51db6] --><div class="jive-rendered-content"><p>Alright, this is a bit of a different post. Summer approaches, and we are looking for an intern.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>If you're interested in security and program analysis, and have a good background in one of the two fields, then please reach out to us (I believe you can send DM on this blog, but otherwise, you can contact me at <a class="jive-link-email-small" href="mailto:rgaucher@coverity.com">rgaucher@coverity.com</a>).</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>We have several ideas that could be developed based on the skills of the individual:</p><ul><li>Pushing the limits of our dynamic whitebox sanitization fuzzer</li><li><span style="font-size: 10pt; line-height: 1.5em;">Improvement of generation and placement of remediation advices</span></li><li><span style="font-size: 10pt; line-height: 1.5em;">Identifying string constraints on tainted input for some set of sinks</span></li><li><span style="font-size: 10pt; line-height: 1.5em;">E</span><span style="font-size: 10pt; line-height: 1.5em;">tc.</span></li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Also, if you have a cool idea (related to program analysis &amp; security obviously) that you'd want to work on for a couple of months, we're happy to hear it.</p></div><!-- [DocumentBodyEnd:c0a6fa5f-b2d7-4e54-bc15-df18dcf51db6] -->internshipFri, 25 Jan 2013 20:34:34 GMThttps://communities.coverity.com/blogs/security/2013/01/25/looking-for-a-summer-internRomain Gaucher2013-01-25T20:34:34Z2 years, 6 months ago0https://communities.coverity.com/blogs/security/comment/looking-for-a-summer-internhttps://communities.coverity.com/blogs/security/feeds/comments?blogPost=1276A Tale of Two Parsershttps://communities.coverity.com/blogs/security/2013/01/24/a-tale-of-two-parsers
<!-- [DocumentBodyStart:96a1d41c-7957-49be-9740-f14b5cecd1ed] --><div class="jive-rendered-content"><p>We have been doing research to ensure our current XSS checker can accurately find and give remediation guidance for XSS defects. For this research we have been examining parsers involved in rendering a HTML page in more detail so that our analysis knows what is and isn't safe in a given context. In addition, this knowledge has become the backbone of the <a class="jive-link-external-small" href="https://github.com/coverity/coverity-security-library">Coverity Security Library</a> that we have open sourced</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>I gave a lightning talk last month at <a class="jive-link-external-small" href="http://technet.microsoft.com/en-us/security/cc261637.aspx">Bluehat v12</a> to help shed some light on the quirks we've been finding, and received a significant amount of feedback indicating that most of this knowledge wasn't really well known beforehand, so we've decided to publish that information here so that the community can be better informed about some unexpected results.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>Javascript String Escapers</h2><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Jon Passki already blogged about one of the issues <a class="jive-link-blog-small" data-containerId="1151" data-containerType="37" data-objectId="1266" data-objectType="38" href="https://communities.coverity.com/blogs/security/2012/11/16/did-i-do-that-html-5-js-escapers-3">here</a>, and you should read that post if you haven't already, but I feel like he left out one particularly interesting case for potential XSS defects, if you don't have time to read that, try to imagine what would happen if a browser were to parse this HTML:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:93544146-a278-488e-96f7-5cdffdfb9d46][excluded]--><pre class="java" name="code">
&lt;script&gt;
var foo = "&lt;!--&lt;script&gt;";
&lt;/script&gt;
&lt;a href="&lt;/script&gt;&lt;script&gt;alert('hax')&lt;/script&gt;"&gt;link&lt;/a&gt;
</pre><!--[CodeBlockEnd:93544146-a278-488e-96f7-5cdffdfb9d46]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>If you save this as a html file and browse to it, you'll see that an alert saying hax fires, as per Jon's blog post. And if you have a look at your browser's developer tools (press F12 in Chrome or IE), you can have a look at what the DOM looks like and you will see that the block from the first script tag to the first closing script tag inside the href attribute is one single script block:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><a href="https://communities.coverity.com/servlet/JiveServlet/showImage/38-1272-1364/double_parse.png"><img alt="double_parse.png" class="jive-image" height="193" src="https://communities.coverity.com/servlet/JiveServlet/downloadImage/38-1272-1364/612-193/double_parse.png" width="612"/></a></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>This is due to the "Script data double escaped state" that Jon mentions in his blog post, that we can force the browser into by opening a HTML comment and a new script tag.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>So how is this relevant from a security perspective? If we look back at another one of Jon's blog posts <a class="jive-link-blog-small" data-containerId="1151" data-containerType="37" data-objectId="1264" data-objectType="38" href="https://communities.coverity.com/blogs/security/2012/11/13/the-way-you-do-the-things-you-do">here</a>, we'll see that Spring, Apache, and most definitely other javascript string escapers avoid someone specifying the typical &lt;/script&gt;&lt;script&gt;alert(1)&lt;/script&gt; payload by replacing / with \/ They do nothing to escape the characters &lt; or &gt;.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>So, going back to the code example up the top, if you imagine the two parts highlighted in blue as attacker controlled, then we can see that these javascript string escapers will allow us to insert the first part of our attack <span style="color: #0000ff;">&lt;!--&lt;script&gt;</span> and now we just need to insert the second part.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>So, in our example above, injecting &lt;/script&gt;&lt;script&gt; into an attribute is actually "safe" by itself, since it does not break out of the href tag, however it's not very likely for this to exist since the most common way to secure an injection into a tag is to html encode it. My pick for this to be actually exploitable is to find a textarea tag that follows, since one of the common ways to fix this is to filter the closing &lt;/textarea&gt; tag.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>While we are currently working with Spring through <a class="jive-link-external-small" href="https://jira.springsource.org/browse/SPR-9983">SPR-9983</a> to address this issue, this is something you should check your own escapers for, since this is not an uncommon model for escaping JavaScript.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>CSS String Escapers</h2><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>In some cases developers want to let users control the contents of a CSS string, maybe to control a URL or a CSS selector. To get an example of what this would look like, consider this style tag:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:5a3d868d-fc9a-4600-8589-f8cc4c8b0eb8][excluded]--><pre class="java" name="code">
&lt;style&gt;
span[id="TAINTED_DATA_HERE"] {
&nbsp;&nbsp;&nbsp; background-color: #ff00ff;
}
&lt;/style&gt;
</pre><!--[CodeBlockEnd:5a3d868d-fc9a-4600-8589-f8cc4c8b0eb8]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>As part of our investigation of what a CSS string escaper needs to do, we took note of the most obvious examples of needing to escape ' and " as string delimeters and \ as the escaping character, but we also noticed a series of characters that needed to be escaped because they would otherwise cause parse errors.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>In particular, according to the CSS spec, any of the following characters can potentially cause parse errors:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><ul><li>Line Feed (U+000A)</li><li>Form Feed (U+000C)</li><li>Carriage Return (U+000D)</li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>In practice, this turned out to be true for Chrome, but false for Firefox and IE.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>In any case, parse errors, particularly in CSS are not obviously security issues by themselves, however if you have a look at the <a class="jive-link-external-small" href="http://www.w3.org/TR/CSS21/syndata.html#parsing-errors">CSS spec</a> you will find that CSS is somewhat unique in that parse errors are not actually fatal and a compliant CSS parser will attempt to recover and re-sync with the CSS stream and begin parsing CSS again. This essentially allows us to escape the quoted string context and jump into the CSS data context and specify arbitrary CSS, like this chrome-only example which sets the background of the entire page to red:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><!--[CodeBlockStart:ed6906a9-b2ae-40e4-8547-8e87d356147e][excluded]--><pre class="java" name="code">
&lt;style&gt;
&nbsp; span[id="
{} body { background-color: red; }"] {
&nbsp; background-color: #ff00ff;
&nbsp; }
&lt;/style&gt;
</pre><!--[CodeBlockEnd:ed6906a9-b2ae-40e4-8547-8e87d356147e]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Having demonstrated that we can use these characters to escape the string context the obvious question becomes what can we do with this in Google Chrome? We haven't delved too deeply into this topic at Coverity, and chrome doesn't seem to have an obvious way to directly execute javascript, however there has been quite a bit of work done by other researchers on conducting JavaScript-less attacks that can still steal your data, <a class="jive-link-external-small" href="http://www.nds.rub.de/media/emma/veroeffentlichungen/2012/08/16/scriptlessAttacks-ccs2012.pdf">this recent paper</a> in particular is a has a good survey of what can be done with CSS.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>One additional thing to note is that the parse error recovery behaviour has implications for CSS validators such as HTMLPurifier or AntiSamy since they need to be aware of this behaviour to ensure their parsing of CSS is the same as a browser's.</p></div><!-- [DocumentBodyEnd:96a1d41c-7957-49be-9740-f14b5cecd1ed] -->xsssecurityinjectionhtml5specificationhtmljavascriptcssweb-securityThu, 24 Jan 2013 22:09:25 GMThttps://communities.coverity.com/blogs/security/2013/01/24/a-tale-of-two-parsersAlex Kouzemtchenko2013-01-24T22:09:25Z2 years, 6 months ago10https://communities.coverity.com/blogs/security/comment/a-tale-of-two-parsershttps://communities.coverity.com/blogs/security/feeds/comments?blogPost=1272A new look into the HTML 5 tokenizer specificationhttps://communities.coverity.com/blogs/security/2013/01/23/a-new-look-into-the-html-5-tokenizer-specification
<!-- [DocumentBodyStart:3640bda5-70be-4edb-9797-7993585ffd51] --><div class="jive-rendered-content"><p>Over the past year or so, the <a class="jive-link-external-small" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html">HTML 5 specification</a> has been a non-friendly but necessary reference to me (/us). Indeed, this is the only place that really explains how an HTML 5 document gets tokenized (a necessary step before parsing).</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>If you're doing research related to XSS or HTML contexts, and you never had a look at this document, I suggest you go ahead and dive into it. That's mostly the key to finding something like the <a class="jive-link-blog-small" data-containerId="1151" data-containerType="37" data-objectId="1266" data-objectType="38" href="https://communities.coverity.com/blogs/security/2012/11/16/did-i-do-that-html-5-js-escapers-3">script data double escaped state</a> as described by Jon.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>However, if you had a serious look into it, I'm sure you had one of these reactions:</p><blockquote class="jive-quote">
<p><em>Where am I know? </em></p>
<p><em>How did I end up here?</em></p>
</blockquote><p>So, just for the sake of making our life easier, I created a small visualization page for the spec. I mostly scraped the tokenizer spec, and generated a graph for it.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The result is a self-contained HTML document that helps you navigate through the tokenization specification, and lets you click on states and remembers where you're coming from. It's really just to make our life easier:</p><p><a href="http://www.coverity.com/srl/html5-grammar-visualization.html"><img alt="sshot.png" class="jive-image-thumbnail jive-image" height="345" src="https://communities.coverity.com/servlet/JiveServlet/downloadImage/38-1275-1373/620-345/sshot.png" style="display: block; margin-left: auto; margin-right: auto;" width="620"/></a></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>This document is available here: <a class="jive-link-external-small" href="http://www.coverity.com/srl/html5-grammar-visualization.html">HTML5 tokenization visualization</a>.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>If you're interested in how to get the data, we published the script that generates a JSON or DOT file on Github: <a class="jive-link-external-small" href="https://github.com/coverity/security/tree/master/html5-tokenizer-extraction">security/html5-tokenizer-extraction at master &middot; coverity/security &middot; GitHub</a></p></div><!-- [DocumentBodyEnd:3640bda5-70be-4edb-9797-7993585ffd51] -->html5tokenizationspecificationwhatwgWed, 23 Jan 2013 19:02:20 GMThttps://communities.coverity.com/blogs/security/2013/01/23/a-new-look-into-the-html-5-tokenizer-specificationRomain Gaucher2013-01-23T19:02:20Z2 years, 6 months ago0https://communities.coverity.com/blogs/security/comment/a-new-look-into-the-html-5-tokenizer-specificationhttps://communities.coverity.com/blogs/security/feeds/comments?blogPost=1275Did I Do That? HTML 5 + JS Escapers != <3https://communities.coverity.com/blogs/security/2012/11/16/did-i-do-that-html-5-js-escapers-3
<!-- [DocumentBodyStart:6881897b-1c86-450a-adf4-1f030cff2675] --><div class="jive-rendered-content"><p>When writing the last <a class="jive-link-blog-small" data-containerId="1151" data-containerType="37" data-objectId="1264" data-objectType="38" href="https://communities.coverity.com/blogs/security/2012/11/13/the-way-you-do-the-things-you-do">blog post</a>, I swear the HTML 5 <a class="jive-link-external-small" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html">tokenizer spec</a> had a <a class="jive-link-external-small" href="http://en.wikipedia.org/wiki/Steve_Urkel">Steve Urkel</a> moment with me. Well, not with me, but with a lot of existing JavaScript escapers out there. Why is that?</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>HTML 5 tokenizer introduces a handful of new HTML states that only exist within the <a class="jive-link-external-small" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#script-data-state">Script data state</a> (e.g. in a &lt;script&gt; tag). Some of these are really interesting.</p><ul><li><a class="jive-link-external-small" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#script-data-escaped-dash-dash-state">Script data escaped dash dash state</a></li><li><a class="jive-link-external-small" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#script-data-escaped-state">Script data escaped state</a></li><li><a class="jive-link-external-small" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#script-data-double-escaped-state">Script data double escaped state</a></li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Here's a mocked up &lt;script&gt; block with the states:</p><blockquote class="jive-quote">
<p>&lt;script type="text/javascript"&gt;</p>
<p>&nbsp;&nbsp; &lt;!-- That second dash to the left is the Script data escaped dash dash state</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This is script data escaped state</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script&gt; This is script data double escaped state</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/script&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This is script data escaped state</p>
<p>&nbsp;&nbsp;&nbsp; --&gt;</p>
<p>&lt;/script&gt;</p>
</blockquote><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><a class="jive-link-external-small" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#restrictions-for-contents-of-script-elements">Here's</a> ABNF formatting of the above in case state machines aren't your thing.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><strong>Boring you say.</strong></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Not at all I say <img height="16px" src="https://communities.coverity.com/5.0.2/images/emoticons/happy.gif" width="16px"/> What's interesting about these states is that the current JavaScript is also in play. "What?" I hear from you.</p><blockquote class="jive-quote">
<p>&lt;script type="text/javascript&gt;</p>
<p>var foo = "&lt;!-- &lt;script&gt; guess what state I'm in!";</p>
<p>&lt;/script&gt;</p>
<p>... rest of document</p>
</blockquote><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Normally, the JavaScript state would be in double quoted string, within the Script data state. (Check out the previous <a class="jive-link-blog-small" data-containerId="1151" data-containerType="37" data-objectId="1264" data-objectType="38" href="https://communities.coverity.com/blogs/security/2012/11/13/the-way-you-do-the-things-you-do">blog</a> for a rundown of ECMAScript and String literals.) Now, the JavaScript state is in a double quoted string, within the Script data double escaped state. And the wheels start turning <img height="16px" src="https://communities.coverity.com/5.0.2/images/emoticons/wink.gif" width="16px"/></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Well, what does that mean? Given the above, the state transitions back to Script data escaped state when the original closing script tag (i.e. &lt;/script&gt;) is consumed. Let's say there isn't a "--&gt;" for the remainder of the document. Then the tokenizer ought to get to the end of file (EOF). If so, this is a parse error. The state ought to be switched to data state, and then the document is rendered, albeit not much.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><blockquote class="jive-quote">
<p>&lt;script type="text/javascript&gt;</p>
<p>var foo = "&lt;!-- &lt;script&gt; guess what state I'm in!";</p>
<p>&lt;/script&gt;</p>
<p>... some of the document</p>
<p>&lt;!-- Remember to remove this code for the next version --&gt;</p>
<p><span style="font-family: 'Lucida Grande', Arial, Helvetica, sans-serif; background-color: #ffffff;">... remainder of the document</span></p>
</blockquote><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Again, following the tokenizer spec, the tokenizer ought to be at the Script data escaped state when it encounters the less-than sign "&lt;". It then transitions to the <a class="jive-link-external-small" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#script-data-escaped-less-than-sign-state">Script data escaped less-than sign state</a>. But it doesn't care about the exclamation point "!" here and switches back to Script data escaped. I'm hand waving the next couple state transitions until it gets to that "--&gt;". At that point, it'll go through the following:</p><ul><li><a class="jive-link-external-small" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#script-data-escaped-dash-state">Script data escaped dash state.</a></li><li><a class="jive-link-external-small" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#script-data-escaped-dash-dash-state">Script data escaped dash dash state.</a></li><li>And then Script data state when the "&gt;" is consumed.</li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><strong>OK... what does <em>that</em> mean?</strong></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Remember the previous JavaScript context the page was in? Double quoted string literal. We're now back to that point in the script nesting. So, our string is this document text, except string literals cannot contain new line characters. A syntax error ought to be thrown by the browser's JavaScript parser.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Now what did HTML 5 do? It made ineffective a lot of Java-based JavaScript escapers. Many escapers don't care about "&lt;", "!", "-" or "&gt;". <a class="jive-link-external-small" href="https://github.com/coverity/coverity-security-library/blob/develop/coverity-escapers/src/main/java/com/coverity/security/Escape.java#L459">Coverity Security Library</a> (CSL) does care about "&lt;" and "&gt;" so it's not affected.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><strong>What are the risks?</strong></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Well, unfortunately it depends.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>If you're not using HTML 5 (i.e. &lt;!DOCTYPE html&gt; isn't at the top of your template), then you're OK. If you are using HTML 5 and your escaper doesn't escape those characters, I politely recommend giving CSL a spin. If you can't change escapers, then it depends upon where the injection occurs and here's where there be dragons.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>foo.jsp</p><!--[CodeBlockStart:651f08d0-67f9-4856-bef7-bd8e9f0e8748][excluded]--><pre class="java" name="code">
&lt;script type="text/javascript&gt;
var foo = "${some:JsEscaper(param.foo)}";
&lt;%-- no other injection points --%&gt;
&lt;/script&gt;
&lt;%-- ... no more script blocks --%&gt;
</pre><!--[CodeBlockEnd:651f08d0-67f9-4856-bef7-bd8e9f0e8748]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>If the above is your code, then the worse that can occur is the remainder of the document is not rendered by the browser. There's no direct risk for XSS. If that's acceptable, then huzzah. Although you still have a defect <img height="16px" src="https://communities.coverity.com/5.0.2/images/emoticons/wink.gif" width="16px"/></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>mightbebad.jsp</p><!--[CodeBlockStart:6b1b1bc5-cacf-44ae-b3b9-0df0d84ab824][excluded]--><pre class="java" name="code">
&lt;script type="text/javascript&gt;
// totally contrived
var isBarSafe = true;
&lt;/script&gt;
&lt;script type="text/javascript&gt;
var foo = "${some:JsEscaper(param.foo)}";
var bar = "${some:JsEscaper(param.bar)}";
isBarSafe = testBar(bar);
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script type="text/javascript&gt;
if (isBarSafe) {
eval(${some:JsEscaper(param.bar)});
//...
</pre><!--[CodeBlockEnd:6b1b1bc5-cacf-44ae-b3b9-0df0d84ab824]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Yes, the above is contrived. It's just illustrating where the wheels came come off the JavaScripting bus. An attacker could inject <span style="font-family: 'andale mono', times; font-size: 8pt;">&lt;!--&lt;script&gt;</span> via the <span style="font-family: 'andale mono', times; font-size: 8pt;">foo</span> parameter and a <span style="font-family: 'andale mono', times; font-size: 8pt;">--&gt;</span> via the <span style="font-size: 8pt; font-family: 'andale mono', times;">bar</span> parameter. This ought to cause the aforementioned syntax error above, nullifying anything in that second script block. The fail open scenario leaves the site at risk for XSS.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>seriouslybad.jsp</p><!--[CodeBlockStart:bf6294ef-1f2a-4fd4-8ac6-402c31d84512][excluded]--><pre class="java" name="code">
&lt;script type="text/javascript&gt;
&lt;!-- &lt;script&gt; some example ${some:JsEscaper(param.example)} &lt;/script&gt; --&gt;
&lt;/script&gt;
</pre><!--[CodeBlockEnd:bf6294ef-1f2a-4fd4-8ac6-402c31d84512]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The above is a nasty location to inject tainted data. Injecting <span style="font-family: 'andale mono', times; font-size: 8pt;">--&gt;</span> ends the Script data escaped state, which leaves us at... Script data state. We're now in global JavaScript land with full XSS potential.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><strong>Where else could this be an issue?</strong></p><ul><li>Possibly in frame busting code that injects tainted data.</li><li>Possibly in JSON directly inserted into a script context.</li><li>???</li></ul><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>It's probably not worth the cycles to see if the defect is exploitable when there are reasonable remedies out there. If CSL isn't your cup of tea, bother your current vendor on patching their escaper. But if you haven't tried out CSL, I recommend it! And if you're using Maven, it's just <a class="jive-link-external-small" href="https://github.com/coverity/coverity-security-library/tree/develop/coverity-escapers#using-maven">one dependency away</a>.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><h2>Update</h2><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><a class="jive-link-external-small" href="https://twitter.com/0x6D6172696F">@0x6D6172696F</a> (.mario) had a <a class="jive-link-external-small" href="https://twitter.com/0x6D6172696F/status/240028495042981888">conversation on Twitter</a> back in August with <a class="jive-link-external-small" href="https://twitter.com/mathias">@mathias</a> regarding HTML 5 comments in JS. The WHATWG JavaScript section on <a class="jive-link-external-small" href="http://javascript.spec.whatwg.org/#comment-syntax">Comments</a> goes into better detail on what should or shouldn't be honor. This makes more sense than the trial and error testing I did above. These comments ought to be treated as single line comments. Therefore breaking them up across lines changes the meaning in JS. Thanks Mario!</p></div><!-- [DocumentBodyEnd:6881897b-1c86-450a-adf4-1f030cff2675] -->javascriptjavacoverity-security-libraryescaperinjectionxssFri, 16 Nov 2012 11:29:01 GMThttps://communities.coverity.com/blogs/security/2012/11/16/did-i-do-that-html-5-js-escapers-3Jon Passki2012-11-16T11:29:01Z2 years, 8 months ago0https://communities.coverity.com/blogs/security/comment/did-i-do-that-html-5-js-escapers-3https://communities.coverity.com/blogs/security/feeds/comments?blogPost=1266The Way You Do The Things You Dohttps://communities.coverity.com/blogs/security/2012/11/13/the-way-you-do-the-things-you-do
<!-- [DocumentBodyStart:d0092fbc-0a86-447b-b22e-aa92000bb7c1] --><div class="jive-rendered-content"><p>While researching and developing the remediation advice for the cross-site scripting checker for <a class="jive-link-external-small" href="http://www.coverity.com/products/security-advisor.html">Security Advisor</a>, <a class="jive-link-blog-small" data-containerId="17" data-containerType="-2" data-objectId="1151" data-objectType="37" href="https://communities.coverity.com/blogs/security">we</a> noticed some idiosyncrasies with some popular escapers for HTML, XML, and JavaScript contexts. <a class="jive-link-profile-small" data-containerId="-1" data-containerType="-1" data-objectId="2169" data-objectType="3" href="https://communities.coverity.com/people/rgaucher">Romain</a> and <a class="jive-link-profile-small" data-containerId="-1" data-containerType="-1" data-objectId="2170" data-objectType="3" href="https://communities.coverity.com/people/achou">Andy</a> <a class="jive-link-blog-small" data-containerId="1151" data-containerType="37" data-objectId="1263" data-objectType="38" href="https://communities.coverity.com/blogs/security/2012/11/05/using-the-coverity-security-library-with-guidance-from-security-advisor">have</a> <a class="jive-link-blog-small" data-containerId="1151" data-containerType="37" data-objectId="1261" data-objectType="38" href="https://communities.coverity.com/blogs/security/2012/10/26/coverity-security-library-different-escapers-for-different-html-contexts">gone</a> <a class="jive-link-blog-small" data-containerId="1151" data-containerType="37" data-objectId="1262" data-objectType="38" href="https://communities.coverity.com/blogs/security/2012/10/26/the-coverity-security-library">into</a> the <a class="jive-link-external-small" href="https://github.com/coverity/coverity-security-library">Coverity Security Library</a> (CSL), which encapsulates some of this research.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>JavaScript escapers, like Spring's <a class="jive-link-external-small" href="http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/web/util/JavaScriptUtils.html#javaScriptEscape(java.lang.String)">JavaScriptUtils.javaScriptEscape()</a> escape the forward slash (/) character. Spring mentions a reference to the Mozilla Core JavaScript guide, which has an interesting section on <a class="jive-link-external-small" href="https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Values,_variables,_and_literals#String_literals">String literals</a>. However, that section makes no mention of the forward slash. JavaScript is a dialect of the ECMAScript, defined currently in <a class="jive-link-external-small" href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMA 262</a>. Looking at the current (as of this blog post) revision of 5.1, ECMAScript defines String Literals in section 7.8.4. The Grammar Section in Annex A at the end of the document also is a good spot to read up on the syntax rules. To summarize, a String Literal can be anything between a single-quote (') or double-quote (") character except that quote character and Line Terminators. Drilling into the spec more, there's no obvious reason why the forward slash is escaped.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Now you could be saying to yourself, it's to escape someone from inserting a comment. Since the escaper escapes the quote characters, and a String Literal can contain a forward slash, there's no obvious way this would end the quoted context and start a new single-line comment context. So that's probably not it. And looking into the escapers, they're not trying to do anything with regular expressions, so that doesn't seem to be it.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Spring isn't alone here. The Apache Commons <a class="jive-link-external-small" href="http://commons.apache.org/lang/api-release/org/apache/commons/lang3/StringEscapeUtils.html#escapeEcmaScript(java.lang.String)">StringEscapeUtils.escapeEcmaScript()</a> escaper also escapes the forward slash. Huh. So something is going on here. Now I don't know exactly why they do the things they do, but I can speculate <img height="16px" src="https://communities.coverity.com/5.0.2/images/emoticons/happy.gif" width="16px"/>.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>A reasonable explanation starts with assuming these escapers are used in JSPs or templates. (Spring's escaper is used via their JSP tag library, e.g. spring:message.) If the developer inserts attacker-controlled tainted data into a JavaScript string context within this template, one could assume it's probably occurring between <span style="font-family: 'andale mono', times; font-size: 8pt;">&lt;script&gt;</span> tags. While it could occur within an HTML attribute context, let's go with the <span style="font-family: 'andale mono', times; font-size: 8pt;">&lt;script&gt;</span> tags. <a class="jive-link-external-small" href="http://www.w3.org/TR/html5/">HTML 5</a> ought not change the state from "<a class="jive-link-external-small" href="http://dev.w3.org/html5/spec/tokenization.html#script-data-state">script data state</a>" until a less-than sign (&lt;) occurs. Then if the next character is a forward slash, the state ought to change to the "<a class="jive-link-external-small" href="http://dev.w3.org/html5/spec/tokenization.html#script-data-end-tag-open-state">script data end tag open state</a>". And here's the ahah moment. Since these escapers JavaScript backslash escape the forward slash character and the injected data contained <span style="font-family: 'andale mono', times; font-size: 8pt;">&lt;/script&gt;</span>, the new escaped text should be <span style="font-family: 'andale mono', times; font-size: 11px;">&lt;\/script&gt;</span>. An HTML 5 tokenizer like your browser ought to change back to the script data state. This prevents an attacker from injecting a <span style="font-family: 'andale mono', times; font-size: 11px;">&lt;/script&gt;</span> tag, closing the JavaScript script context, and starting whatever next context the attacker chooses.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Let's say the JSP wasn't using an escaper. Here's a snippet from somefile.jsp:</p><!--[CodeBlockStart:a992428c-6e3c-4f69-8f6b-b5e040db4d31][excluded]--><pre class="java" name="code">
&lt;script type="text/javascript"&gt;
&nbsp; var foo = "${param.foo}";
&lt;/script&gt;
</pre><!--[CodeBlockEnd:a992428c-6e3c-4f69-8f6b-b5e040db4d31]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Then if the following vector was passed to the application: <span style="font-family: 'andale mono', times; font-size: 8pt;">?foo=&lt;/script&gt;&lt;script&gt;var foo=1;//</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The JSP ought to return the following HTML:</p><blockquote class="jive-quote">
<p>&lt;script type="text/javascript"&gt;</p>
<p>&nbsp; var foo = "&lt;/script&gt;&lt;script&gt;var foo=1;//";</p>
<p>&lt;/script&gt;</p>
</blockquote><p>The browser's JavaScript parser ought to register a syntax error within the first block and ignore it. The second block's foo ought to be respected, resulting in a value of 1. User-controlled data has changed the intent of the JavaScript. And this could result in an <a class="jive-link-external-small" href="https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)">XSS</a> attack.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Now, let's say it was. Here's somefile.jsp updated:</p><!--[CodeBlockStart:f146d26e-1b2b-4364-81e4-375ace47ae07][excluded]--><pre class="java" name="code">
&lt;%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%&gt;
...
&nbsp;&nbsp;&nbsp; &lt;script type='text/javascript'&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var foo = "&lt;spring:message javaScriptEscape="true" text="${param.foo}" /&gt;";
&nbsp;&nbsp;&nbsp; &lt;/script&gt;
</pre><!--[CodeBlockEnd:f146d26e-1b2b-4364-81e4-375ace47ae07]--><div style="display:none;"></div><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Using the same vector, the JSP ought to return the following HTML:</p><blockquote class="jive-quote">
<p>&lt;script type="text/javascript"&gt;</p>
<p>&nbsp; var foo = "&lt;\/script&gt;&lt;script&gt;var foo=1;\/\/";</p>
<p>&lt;/script&gt;</p>
</blockquote><p>This ought to be parsed as a normal double-quoted string by the browser. No XSS here.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>In case you're wondering, the CSL <a class="jive-link-external-small" href="https://github.com/coverity/coverity-security-library/blob/develop/coverity-escapers/src/main/java/com/coverity/security/Escape.java#L413">conservatively escapes</a> characters that could cause context transitions like these. If any are not obvious, please let us know on the GitHub page.</p></div><!-- [DocumentBodyEnd:d0092fbc-0a86-447b-b22e-aa92000bb7c1] -->security-research-laboratorysecurity_research_laboratorycoverity-security-libraryescaperxssTue, 13 Nov 2012 18:54:14 GMThttps://communities.coverity.com/blogs/security/2012/11/13/the-way-you-do-the-things-you-doJon Passki2012-11-13T18:54:14Z2 years, 8 months ago10https://communities.coverity.com/blogs/security/comment/the-way-you-do-the-things-you-dohttps://communities.coverity.com/blogs/security/feeds/comments?blogPost=1264Using the Coverity Security Library with guidance from Security Advisorhttps://communities.coverity.com/blogs/security/2012/11/05/using-the-coverity-security-library-with-guidance-from-security-advisor
<!-- [DocumentBodyStart:e1240ffa-db91-4e13-a882-9eff4d625a23] --><div class="jive-rendered-content"><p>Getting the right HTML context is not always easy to say the least. It&#8217;s often easy to forget to apply some escaping, such as for one of the parent HTML contexts. That&#8217;s where <a class="jive-link-external-small" href="http://www.coverity.com/products/security-advisor.html">Coverity Security Advisor</a> comes into play. Our static analysis for cross-site scripting is HTML context aware, and will provide very accurate remediation advices on what escaper(s) to use or sanitization to leverage.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>I want to emphasize that there is no dependency between the <a class="jive-link-external-small" href="https://github.com/coverity/coverity-security-library">Coverity Security Library</a> (CSL) escapers we provide and the Coverity products. We developed these escapers because there is no simple and good solution available for most java web developers. Also, we found it easier to mention these escapers in the remediation advices from Security Advisor when appropriate.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>To illustrate the relation between CSL and Security Advisor, here is an example of what you can get out of it, and how the remediation advice really helps fixing the defects. The application is very simple and uses Spring MVC 3, JPA, JSP and EL; a very common web application stack.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>In this case, I told the analysis not to trust the database, which is not our default trust model.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>In the application, I first have a Spring MVC entry point that makes a query based on the title of a blog entry and returns a list of candidate (approximate search based on supplied title). I select the first one (line 53), extract the title, and add it to the model (line 56) under the name <span style="font-family: terminal, monaco; font-size: 8pt;">found_title</span>. If you&#8217;re not familiar with Spring MVC, the model variable will essentially be added to the request attribute, and be available from expression language (EL).</p><p style="text-align: justify;"><a href="https://communities.coverity.com/servlet/JiveServlet/showImage/38-1263-1342/simple-blog-add-to-model.png"><img alt="simple-blog-add-to-model.png" class="jive-image-thumbnail jive-image" height="213" src="https://communities.coverity.com/servlet/JiveServlet/downloadImage/38-1263-1342/623-213/simple-blog-add-to-model.png" width="623"/></a></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Then the entry point dispatches to a JSP file (entry.jsp):</p><p style="text-align: justify;"><a href="https://communities.coverity.com/servlet/JiveServlet/showImage/38-1263-1343/simple-blog-display-nested-context.png"><img alt="simple-blog-display-nested-context.png" class="jive-image-thumbnail jive-image" height="256" src="https://communities.coverity.com/servlet/JiveServlet/downloadImage/38-1263-1343/654-256/simple-blog-display-nested-context.png" width="654"/></a></p><p style="text-align: justify;"></p><p>The <span style="font-family: terminal, monaco; font-size: 8pt;">${found_title}</span> EL variable is the title that we retrieved from the database (and it is considered tainted as this is what I instructed the analysis to do).&nbsp; Some tests are done to see if we should display or not a banner. We take the true branch in the test and consider the body of the <span style="font-family: terminal, monaco; font-size: 8pt;">&lt;c:if&gt;</span> tag (line 7) to be displayed.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>This is where we have a stored cross-site scripting defect that requires a non-trivial fix due to nested HTML contexts. In this case, the tainted value <span style="font-family: terminal, monaco; font-size: 8pt;">${found_title}</span> is appended in a jQuery selector (approximated to a JavaScript string by our current HTML context parser), which is inside the <span style="font-family: terminal, monaco; font-size: 8pt;">onclick</span> DOM event.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The analysis reports the stack of HTML contexts that are associated with this tainted data:</p><ol><li>HTML_ATTR_VAL_DQ: HTML double quoted attribute value</li><li>JS_STRING_SQ: JavaScript single quoted string</li></ol><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Also, the analysis reports the appropriate remediation pointing in this case to the <a class="jive-link-external-small" href="https://github.com/coverity/coverity-security-library">Coverity Security Library</a> and the JSTL: the fix is to actually use the EL construct <span style="font-family: terminal, monaco; font-size: 8pt;">${fn:escapeXml(cov:jsStringEscape(found_title))}</span> instead of using directly the <span style="font-family: terminal, monaco; font-size: 8pt;">${found_title}</span> variable.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The recommendation is to:</p><ol><li>Use an escaper for the JavaScript string so that the value of <span style="font-family: terminal, monaco; font-size: 8pt;">found_title</span> cannot escape out of the JavaScript string: the EL Coverity escaper <span style="font-family: terminal, monaco; font-size: 8pt;">cov:jsStringEscape</span></li><li>Use an HTML escaper to ensure that the HTML attribute (outer context) cannot be escaped out: the JSTL HTML escaper <span style="font-family: terminal, monaco; font-size: 8pt;">fn:escapeXml</span></li></ol><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Et voila! That's what I call enabling good code.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Note: Writing this post, I realized that in the events we report "Cross-site script (XSS) injection (XSS)" which is quite incorrect; this is has been corrected since.</p></div><!-- [DocumentBodyEnd:e1240ffa-db91-4e13-a882-9eff4d625a23] -->security-advisorcoverity-security-librarysecurityjavajavascriptjspxssMon, 05 Nov 2012 16:02:52 GMThttps://communities.coverity.com/blogs/security/2012/11/05/using-the-coverity-security-library-with-guidance-from-security-advisorRomain Gaucher2012-11-05T16:02:52Z2 years, 9 months ago0https://communities.coverity.com/blogs/security/comment/using-the-coverity-security-library-with-guidance-from-security-advisorhttps://communities.coverity.com/blogs/security/feeds/comments?blogPost=1263The Coverity Security Libraryhttps://communities.coverity.com/blogs/security/2012/10/26/the-coverity-security-library
<!-- [DocumentBodyStart:66ef0099-c0db-4879-88b0-11a4df1c1f0b] --><div class="jive-rendered-content"><p>Today we're launching the <a class="jive-link-external-small" href="https://github.com/coverity/coverity-security-library">Coverity Security Library</a>.&nbsp; We built it because when we tried to develop remediation guidance for security defects (especially XSS), we couldn't do it in a concise way.&nbsp; For me, this really highlighted why developers end up doing crazy things in their code to try to "fix" XSS defects.&nbsp; The rules are just too arcane.&nbsp; There are no convenient, easy to use, and freely available libraries that take care of the problem.&nbsp; Being a busy developer, writing up a custom regex or hacked up escaper to do a quick fix is highly tempting under time pressure.&nbsp; If we want developers to do the right thing, we need to make the path of least resistance the right thing to do.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>That's the design philosophy behind the Coverity Security Library.&nbsp; Some might find it embarrassingly small to be called a "library".&nbsp; To some extent that's because we're naming it looking forward to what it will become.&nbsp; But its simplicity and small size is also by design.&nbsp; It has no external dependencies so it's easy to incorporate and keep up to date.&nbsp; The functions perform escaping in a straightforward way, making the code easy to understand and review.&nbsp; Need HTML escaping?&nbsp; Just do this:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><span style="font-family: 'andale mono', times; font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp; Escape.html(data)</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>JavaScript string escaping?&nbsp; Try this:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><span style="font-family: 'andale mono', times; font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp; Escape.jsString(data)</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>The class is named Escape, so the method names specify what kind of escaping.&nbsp; Less typing, no stuttering! The functions are static, taking a string and returning a string.&nbsp; No complexity to instantiate or use.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>We take it a little further by providing EL hooks, so the escapers can be used in JSPs in a natural way.&nbsp; For example:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p><span style="font-family: 'andale mono', times; font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp; ${cov:htmlEscape(data)}</span></p><p><span style="font-family: 'andale mono', times; font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp; ${cov:jsStringEscape(data)}</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>That's convenience.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Why yet another security library?&nbsp; Many existing libraries were incomplete.&nbsp; The complete ones were complex and inefficient.&nbsp; There wasn't a freely available library we felt comfortable recommending to users who got remediation advice from our products.&nbsp; So we created one.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>We'll be expanding this library going forward, and we also welcome contributions from the community.&nbsp; We'll be carefully vetting changes, running them through a battery of tests and also static analysis, fuzzing, and manual code review.&nbsp; We hope to earn the trust of our users and believe that making this library available under a liberal BSD-like open source license helps increases the transparency that results in trust.&nbsp; We hope to earn that trust over time as we continue to improve this library.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&nbsp;</p><p>Get it today from <a class="jive-link-external-small" href="https://github.com/coverity/coverity-security-library">GitHub</a>.</p></div><!-- [DocumentBodyEnd:66ef0099-c0db-4879-88b0-11a4df1c1f0b] -->coverity-security-librarysecuritysecurity-research-laboratoryweb-securityopen-sourceFri, 26 Oct 2012 16:52:53 GMThttps://communities.coverity.com/blogs/security/2012/10/26/the-coverity-security-libraryAndy Chou2012-10-26T16:52:53Z2 years, 9 months ago0https://communities.coverity.com/blogs/security/comment/the-coverity-security-libraryhttps://communities.coverity.com/blogs/security/feeds/comments?blogPost=1262