Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h1>Update:</h1> <p><strong>Warning:</strong> Some parts of the code in the original answer (below) were removed and marked as OBSOLETE.</p> <h3>Latest source code in Microsoft site (has syntax highlighting):</h3> <blockquote> <p><a href="http://referencesource.microsoft.com/#System.Web/CrossSiteScriptingValidation.cs" rel="nofollow noreferrer">http://referencesource.microsoft.com/#System.Web/CrossSiteScriptingValidation.cs</a></p> </blockquote> <p>After checking the newest code you will probably agree that what <a href="https://stackoverflow.com/a/2233249/146513">Travis Illig explained</a> are the only validations used now in 2018 (and seems to have no changes since 2014 when the source was released <a href="https://github.com/Microsoft/referencesource/blob/master/System.Web/CrossSiteScriptingValidation.cs" rel="nofollow noreferrer">in GitHub</a>). But the old code below may still be relevant if you use an older version of the framework.</p> <hr> <h1>Original Answer:</h1> <p>Using Reflector, I did some browsing. Here's the raw code. When I have time I will translate this into some meaningful rules:</p> <p>The <code>HttpRequestValidationException</code> is thrown by only a single method in the <code>System.Web</code> namespace, so it's rather isolated. Here is the method:</p> <pre><code>private void ValidateString(string s, string valueName, string collectionName) { int matchIndex = 0; if (CrossSiteScriptingValidation.IsDangerousString(s, out matchIndex)) { string str = valueName + "=\""; int startIndex = matchIndex - 10; if (startIndex &lt;= 0) { startIndex = 0; } else { str = str + "..."; } int length = matchIndex + 20; if (length &gt;= s.Length) { length = s.Length; str = str + s.Substring(startIndex, length - startIndex) + "\""; } else { str = str + s.Substring(startIndex, length - startIndex) + "...\""; } throw new HttpRequestValidationException(HttpRuntime.FormatResourceString("Dangerous_input_detected", collectionName, str)); } } </code></pre> <p>That method above makes a call to the <code>IsDangerousString</code> method in the <code>CrossSiteScriptingValidation</code> class, which validates the string against a series of rules. It looks like the following:</p> <pre><code>internal static bool IsDangerousString(string s, out int matchIndex) { matchIndex = 0; int startIndex = 0; while (true) { int index = s.IndexOfAny(startingChars, startIndex); if (index &lt; 0) { return false; } if (index == (s.Length - 1)) { return false; } matchIndex = index; switch (s[index]) { case 'E': case 'e': if (IsDangerousExpressionString(s, index)) { return true; } break; case 'O': case 'o': if (!IsDangerousOnString(s, index)) { break; } return true; case '&amp;': if (s[index + 1] != '#') { break; } return true; case '&lt;': if (!IsAtoZ(s[index + 1]) &amp;&amp; (s[index + 1] != '!')) { break; } return true; case 'S': case 's': if (!IsDangerousScriptString(s, index)) { break; } return true; } startIndex = index + 1; } } </code></pre> <p>That <code>IsDangerousString</code> method appears to be referencing a series of validation rules, which are outlined below:</p> <pre><code>private static bool IsDangerousExpressionString(string s, int index) { if ((index + 10) &gt;= s.Length) { return false; } if ((s[index + 1] != 'x') &amp;&amp; (s[index + 1] != 'X')) { return false; } return (string.Compare(s, index + 2, "pression(", 0, 9, true, CultureInfo.InvariantCulture) == 0); } </code></pre> <p>-</p> <pre><code>private static bool IsDangerousOnString(string s, int index) { if ((s[index + 1] != 'n') &amp;&amp; (s[index + 1] != 'N')) { return false; } if ((index &gt; 0) &amp;&amp; IsAtoZ(s[index - 1])) { return false; } int length = s.Length; index += 2; while ((index &lt; length) &amp;&amp; IsAtoZ(s[index])) { index++; } while ((index &lt; length) &amp;&amp; char.IsWhiteSpace(s[index])) { index++; } return ((index &lt; length) &amp;&amp; (s[index] == '=')); } </code></pre> <p>-</p> <pre><code>private static bool IsAtoZ(char c) { return (((c &gt;= 'a') &amp;&amp; (c &lt;= 'z')) || ((c &gt;= 'A') &amp;&amp; (c &lt;= 'Z'))); } </code></pre> <p>-</p> <pre><code>private static bool IsDangerousScriptString(string s, int index) { int length = s.Length; if ((index + 6) &gt;= length) { return false; } if ((((s[index + 1] != 'c') &amp;&amp; (s[index + 1] != 'C')) || ((s[index + 2] != 'r') &amp;&amp; (s[index + 2] != 'R'))) || ((((s[index + 3] != 'i') &amp;&amp; (s[index + 3] != 'I')) || ((s[index + 4] != 'p') &amp;&amp; (s[index + 4] != 'P'))) || ((s[index + 5] != 't') &amp;&amp; (s[index + 5] != 'T')))) { return false; } index += 6; while ((index &lt; length) &amp;&amp; char.IsWhiteSpace(s[index])) { index++; } return ((index &lt; length) &amp;&amp; (s[index] == ':')); } </code></pre> <p>So there you have it. It's not pretty to decipher, but it's all there.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload