OWASP O2 Platform Blog

Fixing/Encoding .NET code in real time (in this case Response.Write)

Here is a example of what we should be doing on Dev’s environments in order to make security invisible/automatic to them.

This script will automatically add an Encoding function to Response.Write so that it is always encoded. In this case the patch is done in real time, but it could also be done behind the scenes or on code check in (note that if you are a developer there is no way to avoid it, since the code patch happens automatically).

The script is called “Fixing Response.Write.h2” and here is a video of it in action:

This is how it works:

1) when the script executes you will have two code windows:  on the left is the original code, on the right is the patched code (initially they both look the same)

2) make  a change on the left window  (look in line 21 on the left and line 18 on the right) and note that both windows code is syncronized

3) Unless you type Response.Write, nothing major happens to the code. Note how the Response.End() we just wrote was not changed (line 21 on left, line 18 on right), but on the previous line, the Response.Write was protected with a call to AntiXss.HtmlEncode (line 20 on left and line 17 on on right):

4) Now type on line 20 the Response.Write command (maybe with an XSS payload) and see how it is automatically wrapped in AntiXss.HtmlEncode (it is pretty cool to do this in real time 🙂  )

How does this work?

This was done using O2’s .NET Static Analysis engine which provices easy access to the code’s structure and exposes a number of helper methods to create refactored code:

//panel.clear();
//var topPanel = panel;
var topPanel = O2Gui.open<Panel>("Fixing Response.Write",1000,500);
var controls = topPanel.add_1x1("Original Code", "Patched Code");
var originalCode = controls[0].add_SourceCodeEditor();
var patchedCode = controls[1].add_SourceCodeEditor();</pre>
&nbsp;

originalCode.eDocumentDataChanged+= (text)=>
{
if (text.valid())
{
var csharpAst = text.csharpAst();
//show.info(csharpAst.CompilationUnit.iNodes<InvocationExpression>());

foreach(var invocationExpression in csharpAst.CompilationUnit.iNodes<InvocationExpression>())
{
var memberReference = invocationExpression.TargetObject as MemberReferenceExpression;
if (memberReference.notNull() && memberReference.MemberName == "Write")
{
var className = "AntiXss";
var methodName = "HtmlEncode";
var newMemberReference = new MemberReferenceExpression(new IdentifierExpression(className),methodName );
var newInvocationExpression = new InvocationExpression(newMemberReference);
newInvocationExpression.Arguments.AddRange(invocationExpression.Arguments);
invocationExpression.Arguments.Clear();
invocationExpression.Arguments.Add(newInvocationExpression );
}
csharpAst.CompilationUnit.add_Using("Microsoft.Security.Application");
}

var patchedCSharpCode = csharpAst.CompilationUnit.csharpCode();
patchedCSharpCode = @"//O2Ref:AntiXSSLibrary.dll".line() + patchedCSharpCode; // so that it compiles OK
var patchedCSharpFile = patchedCSharpCode.saveWithExtension(".cs");
patchedCode.open(patchedCSharpFile);
}
};

var originalFile = @"Request.Write.cs".local();
originalCode.open(originalFile);

//using ICSharpCode.NRefactory.Parser
//using ICSharpCode.NRefactory.Ast
//using ICSharpCode.NRefactory
//using O2.API.AST.CSharp;
//using O2.API.AST.ExtensionMethods;
//using O2.API.AST.ExtensionMethods.CSharp;
//O2Ref:O2_API_AST.dll

November 7, 2011 Posted by | .NET, Fixing Code, videos, XSS | | Leave a comment