title: How to remove dangerous characters(ie script tags)?
body: <p>I am wondering is there any sort of C# class or 3rd party library that removes dangerous characters such as script tags?</p>
  
  <p>I know you can use regex but I also know people can write their script tags so many ways that you can fool the regex into thinking it is OK.</p>
  
  <p>I also heard that <a href="http://htmlagilitypack.codeplex.com/" rel="noreferrer">HTML Agility Pack</a> is good so I am wondering is there any script removal class made for it?</p>
  
  <p><strong>Edit</strong></p>
  
  <p><a href="http://htmlagilitypack.codeplex.com/Thread/View.aspx?ThreadId=24346" rel="noreferrer">http://htmlagilitypack.codeplex.com/Thread/View.aspx?ThreadId=24346</a></p>
  
  <p>I found this on their forms. However I am not sure if this is complete solution as the guy does not have any tests to back it up and it would be nicer if this was on some site where tons of people where using this script every day to test to see if anything gets by.</p>
  
  <blockquote>
    <p>Great example (almost), Thanks!  A few
    ways to make it stronger that I saw,
    though:</p>
    
    <p>1) Use case-insensitive search when
    looking for links with "javascript:",
    "vbscript:", "jscript:".  For example,
    the original example would not remove
    the HTML:</p>
  
  <pre><code>&lt;a href="JAVAscRipt:alert('hi')"&gt;click&gt; me&lt;/a&gt;
  </code></pre>
    
    <p>2) Remove any style attributes that
    contain an expression rule.  Internet
    Explorer evaluates the CSS rule
    express as script.  For example, the
    following would product a message box:</p>
  
  <pre><code>&lt;div style="width:expression(alert('hi'));"&gt;bad&gt; code&lt;/div&gt;
  </code></pre>
    
    <p>3) Also remove  tags</p>
    
    <p>I honestly have no idea why
    "expression" has not been removed from
    IE - major flaw in my opinion. (Try
    the div example in internet explorer
    and you'll see why - even IE8.)  I
    just wish there was an easier/standard
    way to clean-up html input from a
    user.</p>
  </blockquote>
  
  <p>Here's the code updated with these improvements.  Let me know if you see anything wrong:</p>
  
  <pre><code>    public string ScrubHTML(string html)
      {
          HtmlDocument doc = new HtmlDocument();
          doc.LoadHtml(html);
  
          //Remove potentially harmful elements
          HtmlNodeCollection nc = doc.DocumentNode.SelectNodes("//script|//link|//iframe|//frameset|//frame|//applet|//object|//embed");
          if (nc != null)
          {
              foreach (HtmlNode node in nc)
              {
                  node.ParentNode.RemoveChild(node, false);
  
              }
          }
  
          //remove hrefs to java/j/vbscript URLs
          nc = doc.DocumentNode.SelectNodes("//a[starts-with(translate(@href, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'javascript')]|//a[starts-with(translate(@href, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'jscript')]|//a[starts-with(translate(@href, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'vbscript')]");
          if (nc != null)
          {
  
              foreach (HtmlNode node in nc)
              {
                  node.SetAttributeValue("href", "#");
              }
          }
  
  
          //remove img with refs to java/j/vbscript URLs
          nc = doc.DocumentNode.SelectNodes("//img[starts-with(translate(@src, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'javascript')]|//img[starts-with(translate(@src, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'jscript')]|//img[starts-with(translate(@src, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'vbscript')]");
          if (nc != null)
          {
              foreach (HtmlNode node in nc)
              {
                  node.SetAttributeValue("src", "#");
              }
          }
  
          //remove on&lt;Event&gt; handlers from all tags
          nc = doc.DocumentNode.SelectNodes("//*[@onclick or @onmouseover or @onfocus or @onblur or @onmouseout or @ondoubleclick or @onload or @onunload]");
          if (nc != null)
          {
              foreach (HtmlNode node in nc)
              {
                  node.Attributes.Remove("onFocus");
                  node.Attributes.Remove("onBlur");
                  node.Attributes.Remove("onClick");
                  node.Attributes.Remove("onMouseOver");
                  node.Attributes.Remove("onMouseOut");
                  node.Attributes.Remove("onDoubleClick");
                  node.Attributes.Remove("onLoad");
                  node.Attributes.Remove("onUnload");
              }
          }
  
          // remove any style attributes that contain the word expression (IE evaluates this as script)
          nc = doc.DocumentNode.SelectNodes("//*[contains(translate(@style, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'expression')]");
          if (nc != null)
          {
              foreach (HtmlNode node in nc)
              {
                  node.Attributes.Remove("stYle");
              }
          }
  
          return doc.DocumentNode.WriteTo();
      } 
  </code></pre>