Skip to content

Instantly share code, notes, and snippets.

@kkurni
Last active December 25, 2015 20:39
Show Gist options
  • Save kkurni/7036312 to your computer and use it in GitHub Desktop.
Save kkurni/7036312 to your computer and use it in GitHub Desktop.
AntiXSS validator for public API. This will allow special characters but will block XSS attacks. allow < ; | () but block any attacks from these list https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SEEK.Employment.Profile.API.Validation;
public class AntiXssValidator : IAntiXssValidator
{
public static string[] XSSTagStringsForDoubleOpening = {"iframe",
"script",
"style",
"input"
};
/// <summary>
/// Validate the words which contains potential XSS Attack.
/// This will compare the encoded with sanitize html fragments, if it finds any differences means that it contains unsafe html tags.
/// Here is the least of potential XSS attacks
/// https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
/// </summary>
/// <param name="words"></param>
/// <returns></returns>
public bool Validate(string words)
{
if (string.IsNullOrEmpty(words))
{
return false;
}
//this will protect all this script attack list https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
var sanitizedWords = Sanitizer.GetSafeHtmlFragment(words);
var sanitizedWordsDecoded = HttpUtility.HtmlDecode(sanitizedWords);
//compare the sanitizedWord to check whether there is invalid tag
if (sanitizedWordsDecoded != words)
{
return true;
}
//except this one, we should protect againts Double open angle brackets
var checkWords = words.ToLower().Trim().Replace(" ", ""); //take out all space to protect < iframe
return XSSTagStringsForDoubleOpening.Any(tag => checkWords.Contains("<" + tag));
}
}
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SEEK.Employment.Profile.API.Validation;
[TestClass]
public class MaliciousCharactersValidatorTests
{
private IAntiXssValidator validator;
[TestMethod]
public void Validate_WithMaliciousCharacters_ReturnsTrue()
{
string wordsToValidate = "<script>";
validator = new AntiXssValidator();
bool result = validator.Validate(wordsToValidate);
Assert.IsTrue(result);
}
[TestMethod]
public void Validate_WithoutMaliciousCharacters_ReturnsFalse()
{
string wordsToValidate = "abcdefghijklomnopqrstuvwxyz0123456789~!@#$%*()";
validator = new AntiXssValidator();
bool result = validator.Validate(wordsToValidate);
Assert.IsFalse(result);
}
[TestMethod]
public void Validate_WithNullString_ReturnsFalse()
{
string wordsToValidate = null;
validator = new AntiXssValidator();
bool result = validator.Validate(wordsToValidate);
Assert.IsFalse(result);
}
[TestMethod]
public void Validate_WithEmptyString_ReturnsFalse()
{
string wordsToValidate = string.Empty;
validator = new AntiXssValidator();
bool result = validator.Validate(wordsToValidate);
Assert.IsFalse(result);
}
[TestMethod]
public void Validate_ShouldAllowLessAndGreaterThanCharacter()
{
string wordsToValidate = "managing < 5 people";
validator = new AntiXssValidator();
bool result = validator.Validate(wordsToValidate);
Assert.IsFalse(result);
}
[TestMethod]
public void Validate_ShouldBlockDoubleOpeningMaliciousTag()
{
string wordsToValidate = "<iframe script <";
validator = new AntiXssValidator();
bool result = validator.Validate(wordsToValidate);
Assert.IsTrue(result);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment