Back

Prevent possible XSS attack in RadEditor using malicious content in IE

It is possible to conduct a successful XSS attack by injecting a specific malicious content in the RadEditor content. This attack targets Internet explorer browsers. It takes advantage of a security vulnerability related to the CSS expression rule in Legacy IE browsers, where arbitrary JavaScript code embedded in the style attribute of a DOM element can be run on the page.

There is a workaround that is strongly recommended to be used in order to make such attack attempts unsuccessful. The idea is to strip the expression declaration from the style attribute value of DOM elements in the RadEditor Content. Following is a sample implementation

Usage:

protected void Page_Load(object sender, EventArgs e)
{
var sanitizer = new CssExpressionSanitizer();
theEditor.Content = sanitizer.Sanitize(theEditor.Content);
}




Content of the CssExpressionSanitizer class:

public class CssExpressionSanitizer
{
private static readonly Regex expressionPattern = new Regex(@"<[a-zA-Z0-9]+[^>]*?style=['""]?.*?(?<cssRule>[^;""]+: expression(?<bracket>\())", RegexOptions.Compiled);

public string Sanitize(string input)
{
var matches = expressionPattern.Matches(input);
for (int i = matches.Count - 1; i >= 0; i--)
{
input = SanitizeExpression(input, matches[i]);
}

return input;
}

private string SanitizeExpression(string input, Match m)
{
var cssRuleIndex = m.Groups["cssRule"].Index;
var expressionIndex = m.Groups["bracket"].Index;

input = StripMatchingBracketsWithContent(input, expressionIndex);
input = input.Remove(cssRuleIndex, expressionIndex - cssRuleIndex);

if (input[cssRuleIndex] == ';')
{
input = input.Remove(cssRuleIndex, 1);
}

return input;
}

private string StripMatchingBracketsWithContent(string input, int startIndex)
{
var openBrackets = 0;
do
{
char currentChar = input[startIndex];
if (currentChar == '"' || currentChar == '\'' || currentChar == '/')
{ //strip within quotation marks making sure brackets appearing in string constructs do not interfere with the counting
var parser = new InPairStringParser(currentChar);
input = parser.Sanitize(input, startIndex);

currentChar = input[startIndex];
}
input = input.Remove(startIndex, 1);

if (currentChar == '(')
openBrackets++;
else if (currentChar == ')')
openBrackets--;
}
while (openBrackets > 0 && input.Length > startIndex);

return input;
}

public class InPairStringParser
{
public InPairStringParser(char pairChar)
{
this.pattern = new Regex(String.Format("{0}.*?(?<!\\\\){0}", pairChar));
}

public string Sanitize(string input, int startIndex)
{
var subinput = input.Substring(startIndex);

return input.Substring(0, startIndex) + pattern.Replace(subinput, "", 1);
}

private readonly Regex pattern;
}
}

Attachments (1)

    
» Post Comment

Comments (2)

 
No comments, yet. Be the first!

Post Comment

Your Comment :
Commenting is disabled when the portal is unlicensed.
Select...