From 7784c1a45c0a1402eec0179df710b97c10dd2bec Mon Sep 17 00:00:00 2001 From: "Jackson.Bruce" Date: Sat, 21 Mar 2020 23:03:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9B=B4=E5=A4=9A=E7=9B=AE?= =?UTF-8?q?=E6=A0=87=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AntiXssUF.Mvc/AntiXssUF.Mvc.csproj | 74 - .../resources/antixss-policy-Default.config | 2417 ---------------- .../resources/antixss-policy-Default.json | 2015 ------------- .../resources/antixss-policy-Default.xml | 2417 ---------------- .../antixss-policy-antisamy-anythinggoes.xml | 2573 ----------------- .../antixss-policy-antisamy-ebay.xml | 2385 --------------- .../antixss-policy-antisamy-myspace.xml | 2558 ---------------- .../antixss-policy-antisamy-slashdot.xml | 176 -- .../antixss-policy-antisamy-test.xml | 862 ------ .../resources/antixss-policy-antisamy.xml | 2572 ---------------- AntiXssUF.Mvc/resources/antixss-policy.xsd | 154 - AntiXssUF.TestSite/AntiXssUF.TestSite.csproj | 6 +- .../Controllers/HomeController.cs | 91 +- AntiXssUF.TestSite/Startup.cs | 2 +- AntiXssUF.TestSite/Views/Home/Index.cshtml | 28 +- AntiXssUF.sln | 12 +- AntiXssUF/AntiXssUF.csproj | 179 +- .../AntiXssUFServiceCollectionExtensions.cs | 14 +- AntiXssUF/AntisamyPolicy.cs | 48 +- AntiXssUF/Configures.cs | 24 + AntiXssUF/Configures.net461.cs | 32 + AntiXssUF/Configures.netstandard.cs | 19 + AntiXssUF/CssFilter.cs | 42 +- AntiXssUF/ExtensionMethods.cs | 57 +- AntiXssUF/FilterPolicyBuilder.cs | 17 +- AntiXssUF/FilterPolicyException.cs | 20 + AntiXssUF/FilterPolicyFactory.cs | 38 +- AntiXssUF/FilterPolicyOptions.cs | 30 +- AntiXssUF/FilterPolicyProvider.cs | 54 +- AntiXssUF/FilterPolicyProvider.net461.cs | 38 + AntiXssUF/FilterPolicyProvider.netstandard.cs | 39 + AntiXssUF/FilterRegExp.cs | 25 +- AntiXssUF/HtmlFilter.cs | 53 +- AntiXssUF/ICssFilter.cs | 8 + AntiXssUF/IFilterPolicy.cs | 33 +- AntiXssUF/IFilterPolicyFactory.cs | 28 + AntiXssUF/IFilterPolicyProvider.cs | 29 + AntiXssUF/IHtmlFilter.cs | 8 + AntiXssUF/IXssSchemeName.net461.cs | 22 + .../IXssSchemeName.netcoreapp.cs | 8 + AntiXssUF/JsonFilterPolicy.cs | 83 +- AntiXssUF/JsonFilterPolicy.net461.cs | 81 + AntiXssUF/JsonFilterPolicy.netstandard.cs | 78 + AntiXssUF/PolicyAttribute.cs | 20 +- AntiXssUF/PolicyCssProperty.cs | 10 + AntiXssUF/PolicyHtmlAttribute.cs | 10 + AntiXssUF/PolicyHtmlTag.cs | 17 +- AntiXssUF/PolicyHtmlTagAction.cs | 3 + AntiXssUF/RichText.cs | 39 +- AntiXssUF/RichTextBinder.net461.cs | 49 + .../RichTextBinder.netcoreapp.cs | 9 +- .../RichTextBinderProvider.netcoreapp.cs | 8 + AntiXssUF/XssFilterBuilder.cs | 74 +- AntiXssUF/XssSchemeNameAttribute.net461.cs | 34 + .../XssShemeNameAttribute.netcoreapp.cs | 15 +- AntiXssUF/resources/DefaultPolicy.json | 2014 +++++-------- Framework461Test/Framework461Test.csproj | 84 + Framework461Test/Properties/AssemblyInfo.cs | 20 + Framework461Test/UnitTest1.cs | 203 ++ Framework461Test/app.config | 11 + Framework461Test/packages.config | 8 + 61 files changed, 2366 insertions(+), 19711 deletions(-) delete mode 100644 AntiXssUF.Mvc/AntiXssUF.Mvc.csproj delete mode 100644 AntiXssUF.Mvc/resources/antixss-policy-Default.config delete mode 100644 AntiXssUF.Mvc/resources/antixss-policy-Default.json delete mode 100644 AntiXssUF.Mvc/resources/antixss-policy-Default.xml delete mode 100644 AntiXssUF.Mvc/resources/antixss-policy-antisamy-anythinggoes.xml delete mode 100644 AntiXssUF.Mvc/resources/antixss-policy-antisamy-ebay.xml delete mode 100644 AntiXssUF.Mvc/resources/antixss-policy-antisamy-myspace.xml delete mode 100644 AntiXssUF.Mvc/resources/antixss-policy-antisamy-slashdot.xml delete mode 100644 AntiXssUF.Mvc/resources/antixss-policy-antisamy-test.xml delete mode 100644 AntiXssUF.Mvc/resources/antixss-policy-antisamy.xml delete mode 100644 AntiXssUF.Mvc/resources/antixss-policy.xsd create mode 100644 AntiXssUF/Configures.cs create mode 100644 AntiXssUF/Configures.net461.cs create mode 100644 AntiXssUF/Configures.netstandard.cs create mode 100644 AntiXssUF/FilterPolicyProvider.net461.cs create mode 100644 AntiXssUF/FilterPolicyProvider.netstandard.cs create mode 100644 AntiXssUF/IXssSchemeName.net461.cs rename AntiXssUF.Mvc/IXssSchemeName.cs => AntiXssUF/IXssSchemeName.netcoreapp.cs (52%) create mode 100644 AntiXssUF/JsonFilterPolicy.net461.cs create mode 100644 AntiXssUF/JsonFilterPolicy.netstandard.cs create mode 100644 AntiXssUF/RichTextBinder.net461.cs rename AntiXssUF.Mvc/RichTextBinder.cs => AntiXssUF/RichTextBinder.netcoreapp.cs (90%) rename AntiXssUF.Mvc/RichTextBinderProvider.cs => AntiXssUF/RichTextBinderProvider.netcoreapp.cs (78%) create mode 100644 AntiXssUF/XssSchemeNameAttribute.net461.cs rename AntiXssUF.Mvc/XssShemeNameAttribute.cs => AntiXssUF/XssShemeNameAttribute.netcoreapp.cs (68%) create mode 100644 Framework461Test/Framework461Test.csproj create mode 100644 Framework461Test/Properties/AssemblyInfo.cs create mode 100644 Framework461Test/UnitTest1.cs create mode 100644 Framework461Test/app.config create mode 100644 Framework461Test/packages.config diff --git a/AntiXssUF.Mvc/AntiXssUF.Mvc.csproj b/AntiXssUF.Mvc/AntiXssUF.Mvc.csproj deleted file mode 100644 index e432724..0000000 --- a/AntiXssUF.Mvc/AntiXssUF.Mvc.csproj +++ /dev/null @@ -1,74 +0,0 @@ - - - - netcoreapp3.1 - Ufangx.Xss - Jackson.bruce - https://github.com/JacksonBruce/AntiXssUF - https://github.com/JacksonBruce/AntiXssUF.git - git - anti xss mvc model binder policy - anti xss mvc model binder policy - ufangx - Copyright (c) 2020 Jackson.Bruce - https://github.com/JacksonBruce/AntiXssUF/blob/master/README.md - 1.0.0-beta.0 - true - - - - - - - - - - - - - PreserveNewest - true - PreserveNewest - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - diff --git a/AntiXssUF.Mvc/resources/antixss-policy-Default.config b/AntiXssUF.Mvc/resources/antixss-policy-Default.config deleted file mode 100644 index ece8144..0000000 --- a/AntiXssUF.Mvc/resources/antixss-policy-Default.config +++ /dev/null @@ -1,2417 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AntiXssUF.Mvc/resources/antixss-policy-Default.json b/AntiXssUF.Mvc/resources/antixss-policy-Default.json deleted file mode 100644 index 77bc06c..0000000 --- a/AntiXssUF.Mvc/resources/antixss-policy-Default.json +++ /dev/null @@ -1,2015 +0,0 @@ -{ - "Directives": { - "omitxmldeclaration": "true", - "omitdoctypedeclaration": "true", - "maxinputsize": "200000", - "usexhtml": "true", - "formatoutput": "true", - "embedstylesheets": "false", - "connectiontimeout": "5000", - "maxstylesheetimports": "3" - }, - "CommonRegularExpressions": { - "colornameorcode": "(#[0-9a-fA-F]{6}|[a-zA-Z]{1,20})", - "number": "[0-9]+", - "anything": ".*", - "numberorpercent": "(\\d)+(%{0,1})", - "paragraph": "([\\p{L}\\p{N},'\\.\\s\\-_\\(\\)]|&[0-9]{2};)*", - "htmlid": "[a-zA-Z0-9-_]+", - "htmltitle": "[\\p{L}\\p{N}\\s-_',:\\[\\]!\\./\\\\\\(\\)]*", - "htmlclass": "[a-zA-Z0-9\\s,-_]+", - "onsiteurl": "([\\p{L}\\p{N}\\\\/\\.\\?=\\#&;\\-_~]+|\\#(\\w)+)", - "offsiteurl": "(\\s)*((ht|f)tp(s?)://|mailto:)[\\p{L}\\p{N}]+[~\\p{L}\\p{N}\\p{Zs}\\-_\\.@#$%&;:,\\?=/\\+!]*(\\s)*", - "boolean": "(true|false)", - "singleprintable": "[a-zA-Z0-9]{1}", - "csselementselector": "[a-zA-Z0-9-_]+|\\*", - "cssclassselector": "\\.[a-zA-Z0-9-_]+", - "cssidselector": "#[a-zA-Z0-9-_]+", - "csspseudoelementselector": ":[a-zA-Z0-9\\-_]+", - "cssattributeselector": "\\[[a-zA-Z0-9\\-_]+((=|~=|\\|=){1}[a-zA-Z0-9\\-_]+){1}\\]", - "cssonsiteuri": "url\\(([\\p{L}\\p{N}\\\\/\\.\\?=\\#&;\\-_~]+|\\#(\\w)+)\\)", - "cssoffsiteuri": "url\\((\\s)*((ht|f)tp(s?)://)[\\p{L}\\p{N}]+[~\\p{L}\\p{N}\\p{Zs}\\-_\\.@#$%&;:,\\?=/\\+!]*(\\s)*\\)", - "csscommenttext": "[\\p{L}\\p{N}-_,\\/\\\\\\.\\s\\(\\)!\\?\\=\\$#%\\^&:\"']+", - "integer": "(-|\\+)?[0-9]+", - "angle": "(-|\\+)?([0-9]+(.[0-9]+)?)(deg|grads|rad)", - "time": "([0-9]+(.[0-9]+)?)(ms|s)", - "frequency": "([0-9]+(.[0-9]+)?)(hz|khz)", - "length": "((-|\\+)?0|(-|\\+)?([0-9]+(.[0-9]+)?)(em|ex|px|in|cm|mm|pt|pc))", - "percentage": "(-|\\+)?([0-9]+(.[0-9]+)?)%", - "csscolor": "(aqua|black|blue|fuchsia|gray|grey|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)|(^#[0-9a-fA-F]{3,3}$)|(^#[0-9a-fA-F]{6,6}$)|rgba?\\(\\s*([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\\s*,\\s*([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\\s*,\\s*([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])(\\s*,\\s*[1])?\\s*\\)", - "absolute-size": "(xx-small|x-small|small|medium|large|x-large|xx-large)", - "relative-size": "(larger|smaller)" - }, - "CommonAttributes": [ - { - - "AllowedRegExp": [ { "Value": "[a-zA-Z0-9_\\-\\:]+" } ], - "Name": "id", - "Description": "The 'id' of any HTML attribute should not contain anything besides letters and numbers" - }, - { - - "AllowedRegExp": [ { "Name": "htmlClass" } ], - "Name": "class", - "Description": "The 'class' of any HTML attribute is usually a single word, but it can also be a list of class names separated by spaces" - }, - { - - "AllowedRegExp": [ { "Value": "[a-zA-Z]{2,20}" } ], - "Name": "lang", - "Description": "The 'lang' attribute tells the browser what language the element's attribute values and content are written in" - }, - { - - "AllowedRegExp": [ { "Name": "htmlTitle" } ], - "Name": "title", - "Description": "The 'title' attribute provides text that shows up in a 'tooltip' when a user hovers their mouse over the element" - }, - { - - "AllowedRegExp": [ { "Name": "paragraph" } ], - "Name": "alt", - "Description": "The 'alt' attribute provides alternative text to users when its visual representation is not available" - }, - { - - "Name": "style", - "Description": "The 'style' attribute provides the ability for users to change many attributes of the tag's contents using a strict syntax" - }, - { - - "AllowedValues": [ "screen", "tty", "tv", "projection", "handheld", "print", "braille", "aural", "all" ], - "Name": "media" - }, - { - - "AllowedRegExp": [ - { "Name": "onsiteURL" }, - { "Name": "offsiteURL" } - ], - "AllowedValues": [ "javascript:history.go(0)", "javascript:history.go(-1)", "javascript:void(0)", "javascript:location.reload()" ], - "Name": "href" - }, - { - - "AllowedRegExp": [ { "Value": "[a-zA-Z0-9-_\\$]+" } ], - "Name": "name" - }, - { - - "AllowedValues": [ "default", "rect", "circle", "poly" ], - "Name": "shape", - "Description": "The 'shape' attribute defines the shape of the selectable area" - }, - { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "border" - }, - { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "cellpadding" - }, - { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "cellspacing" - }, - { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "colspan" - }, - { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "rowspan" - }, - { - - "AllowedRegExp": [ { "Name": "onsiteURL" } ], - "Name": "background" - }, - { - - "AllowedRegExp": [ { "Name": "colorNameOrCode" } ], - "Name": "bgcolor" - }, - { - - "AllowedRegExp": [ { "Name": "paragraph" } ], - "Name": "abbrev" - }, - { - - "AllowedRegExp": [ { "Value": "[a-zA-Z0-9\\s*]*" } ], - "Name": "headers", - "Description": "The 'headers' attribute is a space-separated list of cell IDs" - }, - { - - "AllowedRegExp": [ { "Value": "numberOrPercent" } ], - "Name": "charoff" - }, - { - - "AllowedRegExp": [ { "Value": ".*{0,1}" } ], - "Name": "char" - }, - { - - "AllowedRegExp": [ { "Value": "[a-zA-Z0-9\\s*,]*" } ], - "Name": "axis", - "Description": "The 'headers' attribute is a comma-separated list of related header cells" - }, - { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "nowrap", - "Description": "The 'nowrap' attribute tells the browser not to wrap text that goes over one line" - }, - { - - "AllowedRegExp": [ { "Name": "numberOrPercent" } ], - "Name": "width" - }, - { - - "AllowedRegExp": [ { "Name": "numberOrPercent" } ], - "Name": "height" - }, - { - - "AllowedValues": [ "center", "middle", "left", "right", "justify", "char" ], - "Name": "align", - "Description": "The 'align' attribute of an HTML element is a direction word, like 'left', 'right' or 'center'" - }, - { - - "AllowedValues": [ "baseline", "bottom", "middle", "top" ], - "Name": "valign", - "Description": "The 'valign' attribute of an HTML attribute is a direction word, like 'baseline','bottom','middle' or 'top'" - }, - { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], - "Name": "onFocus", - "Description": "The 'onFocus' event is executed when the control associated with the tag gains focus" - }, - { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], - "Name": "onBlur", - "Description": "The 'onBlur' event is executed when the control associated with the tag loses focus" - }, - { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], - "Name": "onClick", - "Description": "The 'onClick' event is executed when the control associated with the tag is clicked" - }, - { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], - "Name": "onDblClick", - "Description": "The 'onDblClick' event is executed when the control associated with the tag is clicked twice immediately" - }, - { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], - "Name": "onMouseDown", - "Description": "The 'onMouseDown' event is executed when the control associated with the tag is clicked but not yet released" - }, - { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], - "Name": "onMouseUp", - "Description": "The 'onMouseUp' event is executed when the control associated with the tag is clicked after the button is released" - }, - { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], - "Name": "onMouseOver", - "Description": "The 'onMouseOver' event is executed when the user's mouse hovers over the control associated with the tag" - }, - { - - "AllowedValues": [ "row", "col", "rowgroup", "colgroup" ], - "Name": "scope", - "Description": "The 'scope' attribute defines what's covered by the header cells" - }, - { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "disabled" - }, - { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "readonly" - }, - { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "accesskey" - }, - { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "size" - }, - { - - "AllowedValues": [ "on", "off" ], - "Name": "autocomplete" - }, - { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "rows" - }, - { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "cols" - } - ], - "CssRules": [ - { - "AllowedRegExp": [ { "Name": "angle" } ], - "AllowedValues": [ "left-side", "far-left", "left", "center-left", "center", "center-right", "right", "far-right", "right-side", "behind", "leftwards", "rightwards", "inherit" ], - "Name": "azimuth", - "Description": "This property is most likely to be implemented by mixing the same signal into different channels at differing volumes." - }, - { - "Shorthands": [ "background-color", "background-image", "background-repeat", "background-attachment", "background-position" ], - "AllowedValues": [ "inherit" ], - "Name": "background", - "Description": "The 'background' property is a shorthand property for setting the individual background properties (i.e., 'background-color', 'background-image', 'background-repeat', 'background-attachment' and 'background-position') at the same place in the style sheet." - }, - { - "AllowedValues": [ "scroll", "fixed", "inherit" ], - "Name": "background-attachment", - "Description": "If a background image is specified, this property specifies whether it is fixed with regard to the viewport ('fixed') or scrolls along with the document ('scroll')." - }, - { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "transparent", "inherit" ], - "Name": "background-color", - "Description": "This property sets the background color of an element, either a value or the keyword 'transparent', to make the underlying colors shine through." - }, - { - "AllowedRegExp": [ - { "Name": "cssOffsiteUri" }, - { "Name": "cssOnsiteUri" } - ], - "AllowedValues": [ "none", "inherit" ], - "Name": "background-image", - "Description": "This property sets the background image of an element." - }, - { - "AllowedRegExp": [ - { "Name": "percentage" }, - { "Name": "length" } - ], - "AllowedValues": [ "top", "center", "bottom", "left", "center", "right", "inherit" ], - "Name": "background-position", - "Description": "If a background image has been specified, this property specifies its initial position." - }, - { - "AllowedValues": [ "repeat", "repeat-x", "repeat-y", "no-repeat", "inherit" ], - "Name": "background-repeat", - "Description": "If a background image is specified, this property specifies whether the image is repeated (tiled), and how." - }, - { - "AllowedValues": [ "collapse", "separate", "inherit" ], - "Name": "border-collapse", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "transparent", "inherit" ], - "Name": "border-color", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], - "Name": "border-top-color", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], - "Name": "border-right-color", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], - "Name": "border-bottom-color", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], - "Name": "border-left-color", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "bottom", - "Description": "" - }, - { - "AllowedValues": [ "top", "bottom", "left", "right", "inherit" ], - "Name": "caption-side", - "Description": "" - }, - { - "AllowedValues": [ "none", "left", "right", "both", "inherit" ], - "Name": "clear", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], - "Name": "color", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "cssOffsiteUri" }, - { "Name": "cssOnsiteUri" } - ], - "AllowedValues": [ "none", "inherit" ], - "Name": "cue-after", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "cssOffsiteUri" }, - { "Name": "cssOnsiteUri" } - ], - "AllowedValues": [ "none", "inherit" ], - "Name": "cue-before", - "Description": "" - }, - { - "AllowedValues": [ "ltr", "rtl", "inherit" ], - "Name": "direction", - "Description": "" - }, - { - "AllowedValues": [ "inline", "block", "list-item", "run-in", "compact", "marker", "table", "inline-table", "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group", "table-column", "table-cell", "table-caption", "none", "inherit" ], - "Name": "display", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "angle" } ], - "AllowedValues": [ "below", "level", "above", "higher", "lower", "inherit" ], - "Name": "elevation", - "Description": "" - }, - { - "AllowedValues": [ "show", "hide", "inherit" ], - "Name": "empty-cells", - "Description": "" - }, - { - "AllowedValues": [ "left", "right", "none", "inherit" ], - "Name": "float", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "absolute-size" }, - { "Name": "relative-size" }, - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], - "Name": "font-size", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "number" } ], - "AllowedValues": [ "none", "inherit" ], - "Name": "font-size-adjust", - "Description": "" - }, - { - "AllowedValues": [ "normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded", "inherit" ], - "Name": "font-stretch", - "Description": "" - }, - { - "AllowedValues": [ "normal", "italic", "oblique", "inherit" ], - "Name": "font-style", - "Description": "" - }, - { - "AllowedValues": [ "normal", "small-caps", "inherit" ], - "Name": "font-variant", - "Description": "" - }, - { - "AllowedValues": [ "normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900", "inherit" ], - "Name": "font-weight", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "height", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "left", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "length" } ], - "AllowedValues": [ "normal", "inherit" ], - "Name": "letter-spacing", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "number" }, - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "normal", "inherit" ], - "Name": "line-height", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "cssOffsiteUri" }, - { "Name": "cssOnsiteUri" } - ], - "AllowedValues": [ "none", "inherit" ], - "Name": "list-style-image", - "Description": "" - }, - { - "AllowedValues": [ "inside", "outside", "inherit" ], - "Name": "list-style-position", - "Description": "" - }, - { - "AllowedValues": [ "disc", "circle", "square", "decimal", "decimal-leading-zero", "lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "hebrew", "armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha", "katakana-iroha", "none", "inherit" ], - "Name": "list-style-type", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "length" } ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "marker-offset", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "none", "inherit" ], - "Name": "max-height", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "none", "inherit" ], - "Name": "max-width", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], - "Name": "min-height", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], - "Name": "min-width", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "integer" } ], - "AllowedValues": [ "inherit" ], - "Name": "orphans", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "invert", "inherit" ], - "Name": "outline-color", - "Description": "" - }, - { - "AllowedValues": [ "visible", "hidden", "scroll", "auto", "inherit" ], - "Name": "overflow", - "Description": "" - }, - { - "AllowedValues": [ "auto", "always", "avoid", "left", "right", "inherit" ], - "Name": "page-break-after", - "Description": "" - }, - { - "AllowedValues": [ "auto", "always", "avoid", "left", "right", "inherit" ], - "Name": "page-break-before", - "Description": "" - }, - { - "AllowedValues": [ "avoid", "auto", "inherit" ], - "Name": "page-break-inside", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "time" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], - "Name": "pause-after", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "time" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], - "Name": "pause-before", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "frequency" } ], - "AllowedValues": [ "x-low", "low", "medium", "high", "x-high", "inherit" ], - "Name": "pitch", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "number" } ], - "AllowedValues": [ "inherit" ], - "Name": "pitch-range", - "Description": "" - }, - { - "AllowedValues": [ "static", "inherit" ], - "Name": "position", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "number" } ], - "AllowedValues": [ "inherit" ], - "Name": "richness", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "right", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "length" } ], - "AllowedValues": [ "auto", "portrait", "landscape", "inherit" ], - "Name": "size", - "Description": "" - }, - { - "AllowedValues": [ "normal", "none", "spell-out", "inherit" ], - "Name": "speak", - "Description": "" - }, - { - "AllowedValues": [ "once", "always", "inherit" ], - "Name": "speak-header", - "Description": "" - }, - { - "AllowedValues": [ "digits", "continuous", "inherit" ], - "Name": "speak-numeral", - "Description": "" - }, - { - "AllowedValues": [ "code", "none", "inherit" ], - "Name": "speak-punctuation", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "number" } ], - "AllowedValues": [ "x-slow", "slow", "medium", "fast", "x-fast", "faster", "slower", "inherit" ], - "Name": "speech-rate", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "number" } ], - "AllowedValues": [ "inherit" ], - "Name": "stress", - "Description": "" - }, - { - "AllowedValues": [ "auto", "fixed", "inherit" ], - "Name": "table-layout", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], - "Name": "text-indent", - "Description": "" - }, - { - "AllowedValues": [ "capitalize", "uppercase", "lowercase", "none", "inherit" ], - "Name": "text-transform", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "top", - "Description": "" - }, - { - "AllowedValues": [ "normal", "embed", "bidi-override", "inherit" ], - "Name": "unicode-bidi", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "percentage" }, - { "Name": "length" } - ], - "AllowedValues": [ "baseline", "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom", "inherit" ], - "Name": "vertical-align", - "Description": "" - }, - { - "AllowedValues": [ "visible", "hidden", "collapse", "inherit" ], - "Name": "visibility", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "number" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "silent", "x-soft", "soft", "medium", "loud", "x-loud", "inherit" ], - "Name": "volume", - "Description": "" - }, - { - "AllowedValues": [ "normal", "pre", "nowrap", "inherit" ], - "Name": "white-space", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "integer" } ], - "AllowedValues": [ "inherit" ], - "Name": "widows", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "width", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "length" } ], - "AllowedValues": [ "normal", "inherit" ], - "Name": "word-spacing", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "integer" } ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "z-index", - "Description": "" - }, - { - "AllowedValues": [ "inherit", "none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset" ], - "Name": "border-style", - "Description": "" - }, - { - "AllowedValues": [ "inherit" ], - "Name": "border-top-style", - "Description": "" - }, - { - "Shorthands": [ "border-style" ], - "AllowedValues": [ "inherit" ], - "Name": "border-right-style", - "Description": "" - }, - { - "Shorthands": [ "border-style" ], - "AllowedValues": [ "inherit" ], - "Name": "border-bottom-style", - "Description": "" - }, - { - "Shorthands": [ "border-style" ], - "AllowedValues": [ "inherit" ], - "Name": "border-left-style", - "Description": "" - }, - { - "Shorthands": [ "border-width" ], - "AllowedValues": [ "inherit" ], - "Name": "border-top-width", - "Description": "" - }, - { - "Shorthands": [ "border-width" ], - "AllowedValues": [ "inherit" ], - "Name": "border-right-width", - "Description": "" - }, - { - "Shorthands": [ "border-width" ], - "AllowedValues": [ "inherit" ], - "Name": "border-bottom-width", - "Description": "" - }, - { - "Shorthands": [ "border-width" ], - "AllowedValues": [ "inherit" ], - "Name": "border-left-width", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "length" } ], - "AllowedValues": [ "inherit", "thin", "medium", "thick" ], - "Name": "border-width", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit", "auto" ], - "Name": "margin", - "Description": "" - }, - { - "Shorthands": [ "margin" ], - "AllowedValues": [ "inherit" ], - "Name": "margin-top", - "Description": "" - }, - { - "Shorthands": [ "margin" ], - "AllowedValues": [ "inherit" ], - "Name": "margin-right", - "Description": "" - }, - { - "Shorthands": [ "margin" ], - "AllowedValues": [ "inherit" ], - "Name": "margin-bottom", - "Description": "" - }, - { - "Shorthands": [ "margin" ], - "AllowedValues": [ "inherit" ], - "Name": "margin-left", - "Description": "" - }, - { - "Shorthands": [ "border-style" ], - "AllowedValues": [ "inherit" ], - "Name": "outline-style", - "Description": "" - }, - { - "Shorthands": [ "border-width" ], - "AllowedValues": [ "inherit" ], - "Name": "outline-width", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], - "Name": "padding", - "Description": "" - }, - { - "Shorthands": [ "padding" ], - "AllowedValues": [ "inherit" ], - "Name": "padding-top", - "Description": "" - }, - { - "Shorthands": [ "padding" ], - "AllowedValues": [ "inherit" ], - "Name": "padding-right", - "Description": "" - }, - { - "Shorthands": [ "padding" ], - "AllowedValues": [ "inherit" ], - "Name": "padding-bottom", - "Description": "" - }, - { - "Shorthands": [ "padding" ], - "AllowedValues": [ "inherit" ], - "Name": "padding-left", - "Description": "" - }, - { - "Shorthands": [ "border-width", "border-style" ], - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], - "Name": "border", - "Description": "" - }, - { - "Shorthands": [ "border-top-width", "border-style" ], - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], - "Name": "border-top", - "Description": "" - }, - { - "Shorthands": [ "border-top-width", "border-style" ], - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], - "Name": "border-right", - "Description": "" - }, - { - "Shorthands": [ "border-top-width", "border-style" ], - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], - "Name": "border-bottom", - "Description": "" - }, - { - "Shorthands": [ "border-top-width", "border-style" ], - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], - "Name": "border-left", - "Description": "" - }, - { - "Shorthands": [ "cue-before", "cue-after" ], - "AllowedValues": [ "inherit" ], - "Name": "cue", - "Description": "" - }, - { - "Shorthands": [ "list-style-type", "list-style-position", "list-style-image" ], - "AllowedValues": [ "inherit" ], - "Name": "list-style", - "Description": "" - }, - { - "AllowedValues": [ "crop", "cross", "none", "inherit" ], - "Name": "marks", - "Description": "" - }, - { - "Shorthands": [ "outline-color", "outline-style", "outline-width" ], - "AllowedValues": [ "inherit" ], - "Name": "outline", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "time" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], - "Name": "pause", - "Description": "" - }, - { - "AllowedValues": [ "none", "underline", "overline", "line-through", "blink", "inherit" ], - "Name": "text-decoration", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "length" } ], - "AllowedValues": [ "inherit" ], - "Name": "border-spacing", - "Description": "The lengths specify the distance that separates adjacent cell borders. If one length is specified, it gives both the horizontal and vertical spacing. If two are specified, the first gives the horizontal spacing and the second the vertical spacing. Lengths may not be negative." - }, - { - "AllowedRegExp": [ - { "Name": "cssElementSelector" }, - { "Name": "cssClassSelector" }, - { "Name": "cssIDSelector" }, - { "Name": "cssAttributeSelector" }, - { "Name": "integer" } - ], - "AllowedValues": [ "none", "inherit" ], - "Name": "counter-increment", - "Description": "The 'counter-increment' property accepts one or more names of counters (identifiers), each one optionally followed by an integer." - }, - { - "AllowedRegExp": [ { "Name": "length" } ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "clip", - "Description": "The 'clip' property applies to elements that have a 'overflow' property with a value other than 'visible'." - }, - { - "AllowedRegExp": [ - { "Name": "cssOffsiteUri" }, - { "Name": "cssOnsiteUri" } - ], - "AllowedValues": [ "auto", "inherit", "crosshair", "default", "pointer", "move", "e-resize", "ne-resize", "nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize| text", "wait", "help" ], - "Name": "cursor", - "Description": "This property specifies the type of cursor to be displayed for the pointing device." - }, - { - "AllowedRegExp": [ - { "Name": "cssColor" }, - { "Name": "length" } - ], - "AllowedValues": [ "none", "inherit" ], - "Name": "text-shadow", - "Description": "This property accepts a comma-separated list of shadow effects to be applied to the text of the element." - }, - { - "Shorthands": [ "font-style", "font-variant", "font-weight", "font-size", "line-height", "font-family" ], - "AllowedValues": [ "/", "caption", "icon", "menu", "message-box", "small-caption", "status-bar", "inherit" ], - "Name": "font", - "Description": "The 'font' property is, except as described below, a shorthand property for setting 'font-style', 'font-variant', 'font-weight', 'font-size', 'line-height', and 'font-family', at the same place in the style sheet." - }, - { - "AllowedRegExp": [ { "Value": "[\\w,\\-'\" ]+" } ], - "AllowedValues": [ "serif", "arial", "lucida console", "sans-serif", "cursive", "verdana", "fantasy", "monospace" ], - "Name": "font-family", - "Description": "This property specifies a prioritized list of font family names and/or generic family names." - }, - { - "AllowedRegExp": [ - { "Name": "cssElementSelector" }, - { "Name": "cssClassSelector" }, - { "Name": "cssIDSelector" }, - { "Name": "cssAttributeSelector" } - ], - "AllowedValues": [ "auto" ], - "Name": "page", - "Description": "The 'page' property can be used to specify a particular type of page where an element should be displayed." - }, - { - "AllowedRegExp": [ - { "Name": "cssOffsiteUri" }, - { "Name": "cssOnsiteUri" } - ], - "AllowedValues": [ "mix", "repeat", "none", "auto", "inherit" ], - "Name": "play-during", - "Description": "Similar to the 'cue-before' and 'cue-after' properties, this property specifies a sound to be played as a background while an element's content is spoken." - }, - { - "AllowedValues": [ "left", "right", "center", "justify", "inherit" ], - "Name": "text-align", - "Description": "This property describes how inline content of a block is aligned." - }, - { - "AllowedValues": [ "male", "female", "child", "inherit" ], - "Name": "voice-family", - "Description": "The value is a comma-separated, prioritized list of voice family names (compare with 'font-family')." - } - ], - "GlobalAttributes": [ - { - - "Name": "id" - }, - { - - "Name": "style" - }, - { - - "Name": "title" - }, - { - - "Name": "class" - }, - { - - "Name": "lang" - } - ], - "TagRules": [ - { - - "Action": 2, - "Name": "html" - }, - { - "AllowedAttributes": { - "bgcolor": { - - "Name": "bgcolor" - } - }, - "Action": 2, - "Name": "body" - }, - { - - "Action": 3, - "Name": "meta" - }, - { - - "Action": 2, - "Name": "head" - }, - { - - "Action": 1, - "Name": "title" - }, - { - - "Action": 0, - "Name": "script" - }, - { - - "Action": 2, - "Name": "noscript" - }, - { - - "Action": 0, - "Name": "iframe" - }, - { - - "Action": 0, - "Name": "frameset" - }, - { - - "Action": 0, - "Name": "frame" - }, - { - "AllowedAttributes": { - "for": { - - "AllowedRegExp": [ { "Name": "htmlId" } ], - "Name": "for" - } - }, - "Action": 0, - "Name": "label" - }, - { - "AllowedAttributes": { - "action": { - - "AllowedRegExp": [ - { "Name": "onsiteURL" }, - { "Name": "offsiteURL" } - ], - "Name": "action" - }, - "name": { - - "Name": "name" - }, - "autocomplete": { - - "Name": "autocomplete" - }, - "method": { - - "AllowedValues": [ "post", "get" ], - "Name": "method" - } - }, - "Action": 2, - "Name": "form" - }, - { - "AllowedAttributes": { - "name": { - - "Name": "name" - }, - "value": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "value" - }, - "disabled": { - - "Name": "disabled" - }, - "accesskey": { - - "Name": "accesskey" - }, - "type": { - - "AllowedValues": [ "submit", "reset", "button" ], - "Name": "type" - } - }, - "Action": 2, - "Name": "button" - }, - { - "AllowedAttributes": { - "name": { - - "Name": "name" - }, - "size": { - - "Name": "size" - }, - "maxlength": { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "maxlength" - }, - "autocomplete": { - - "Name": "autocomplete" - }, - "checked": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "checked" - }, - "alt": { - - "Name": "alt" - }, - "src": { - - "AllowedRegExp": [ - { "Name": "onsiteURL" }, - { "Name": "offsiteURL" } - ], - "Name": "src" - }, - "usemap": { - - "AllowedRegExp": [ { "Name": "onsiteURL" } ], - "Name": "usemap" - }, - "type": { - - "AllowedValues": [ "hidden", "text", "password", "radio", "checkbox", "submit", "button", "image", "file", "reset" ], - "Name": "type" - }, - "value": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "value" - }, - "disabled": { - - "Name": "disabled" - }, - "readonly": { - - "Name": "readonly" - }, - "accesskey": { - - "Name": "accesskey" - }, - "border": { - - "Name": "border" - } - }, - "Action": 2, - "Name": "input" - }, - { - "AllowedAttributes": { - "name": { - - "Name": "name" - }, - "disabled": { - - "Name": "disabled" - }, - "multiple": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "multiple" - }, - "size": { - - "Name": "size" - } - }, - "Action": 2, - "Name": "select" - }, - { - "AllowedAttributes": { - "disabled": { - - "Name": "disabled" - }, - "value": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "value" - }, - "label": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "label" - }, - "selected": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "selected" - } - }, - "Action": 2, - "Name": "option" - }, - { - "AllowedAttributes": { - "rows": { - - "Name": "rows" - }, - "cols": { - - "Name": "cols" - }, - "name": { - - "Name": "name" - }, - "disabled": { - - "Name": "disabled" - }, - "readonly": { - - "Name": "readonly" - }, - "accesskey": { - - "Name": "accesskey" - } - }, - "Action": 2, - "Name": "textarea" - }, - { - - "Action": 2, - "Name": "h1" - }, - { - - "Action": 2, - "Name": "h2" - }, - { - - "Action": 2, - "Name": "h3" - }, - { - - "Action": 2, - "Name": "h4" - }, - { - - "Action": 2, - "Name": "h5" - }, - { - - "Action": 2, - "Name": "h6" - }, - { - "AllowedAttributes": { - "align": { - - "Name": "align" - } - }, - "Action": 2, - "Name": "p" - }, - { - - "Action": 2, - "Name": "i" - }, - { - - "Action": 2, - "Name": "b" - }, - { - - "Action": 2, - "Name": "u" - }, - { - - "Action": 2, - "Name": "strong" - }, - { - - "Action": 2, - "Name": "em" - }, - { - - "Action": 2, - "Name": "small" - }, - { - - "Action": 2, - "Name": "big" - }, - { - - "Action": 2, - "Name": "pre" - }, - { - - "Action": 2, - "Name": "code" - }, - { - - "Action": 2, - "Name": "cite" - }, - { - - "Action": 2, - "Name": "samp" - }, - { - - "Action": 2, - "Name": "sub" - }, - { - - "Action": 2, - "Name": "sup" - }, - { - - "Action": 2, - "Name": "strike" - }, - { - - "Action": 2, - "Name": "center" - }, - { - - "Action": 2, - "Name": "blockquote" - }, - { - - "Action": 2, - "Name": "hr" - }, - { - - "Action": 2, - "Name": "br" - }, - { - "AllowedAttributes": { - "color": { - - "AllowedRegExp": [ { "Name": "colorNameOrCode" } ], - "Name": "color" - }, - "face": { - - "AllowedRegExp": [ { "Value": "[\\w;, ]+" } ], - "Name": "face" - }, - "size": { - - "AllowedRegExp": [ { "Value": "(\\+|-){0,1}(\\d)+" } ], - "Name": "size" - } - }, - "Action": 2, - "Name": "font" - }, - { - "AllowedAttributes": { - "href": { - - "Name": "href" - }, - "onfocus": { - - "Name": "onFocus" - }, - "onblur": { - - "Name": "onBlur" - }, - "nohref": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "nohref" - }, - "rel": { - - "AllowedValues": [ "nofollow" ], - "Name": "rel" - }, - "name": { - - "Name": "name" - } - }, - "Action": 2, - "Name": "a" - }, - { - - "Action": 2, - "Name": "map" - }, - { - "AllowedAttributes": { - "type": { - - "AllowedValues": [ "text/css" ], - "Name": "type" - }, - "media": { - - "Name": "media" - } - }, - "Action": 2, - "Name": "style" - }, - { - - "Action": 2, - "Name": "span" - }, - { - "AllowedAttributes": { - "align": { - - "Name": "align" - } - }, - "Action": 2, - "Name": "div" - }, - { - "AllowedAttributes": { - "src": { - "OnInvalid": 2, - "AllowedRegExp": [ - { "Name": "onsiteURL" }, - { "Name": "offsiteURL" } - ], - "Name": "src" - }, - "name": { - - "Name": "name" - }, - "alt": { - - "Name": "alt" - }, - "height": { - - "Name": "height" - }, - "width": { - - "Name": "width" - }, - "border": { - - "Name": "border" - }, - "align": { - - "Name": "align" - }, - "hspace": { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "hspace" - }, - "vspace": { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "vspace" - } - }, - "Action": 2, - "Name": "img" - }, - { - "AllowedAttributes": { - "media": { - - "Name": "media" - }, - "type": { - "OnInvalid": 2, - "AllowedValues": [ "text/css", "application/rss+xml", "image/x-icon" ], - "Name": "type" - }, - "rel": { - - "AllowedValues": [ "stylesheet", "shortcut icon", "search", "copyright", "top", "alternate" ], - "Name": "rel" - } - }, - "Action": 2, - "Name": "link" - }, - { - - "Action": 2, - "Name": "ul" - }, - { - - "Action": 2, - "Name": "ol" - }, - { - - "Action": 2, - "Name": "li" - }, - { - - "Action": 1, - "Name": "dd" - }, - { - - "Action": 1, - "Name": "dl" - }, - { - - "Action": 1, - "Name": "dt" - }, - { - "AllowedAttributes": { - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - } - }, - "Action": 2, - "Name": "thead" - }, - { - "AllowedAttributes": { - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - } - }, - "Action": 2, - "Name": "tbody" - }, - { - "AllowedAttributes": { - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - } - }, - "Action": 2, - "Name": "tfoot" - }, - { - "AllowedAttributes": { - "height": { - - "Name": "height" - }, - "width": { - - "Name": "width" - }, - "border": { - - "Name": "border" - }, - "bgcolor": { - - "Name": "bgcolor" - }, - "cellpadding": { - - "Name": "cellpadding" - }, - "cellspacing": { - - "Name": "cellspacing" - }, - "background": { - - "Name": "background" - }, - "align": { - - "Name": "align" - }, - "noresize": { - - "AllowedValues": [ "noresize" ], - "Name": "noresize" - } - }, - "Action": 2, - "Name": "table" - }, - { - "AllowedAttributes": { - "background": { - - "Name": "background" - }, - "bgcolor": { - - "Name": "bgcolor" - }, - "abbrev": { - - "Name": "abbrev" - }, - "axis": { - - "Name": "axis" - }, - "headers": { - - "Name": "headers" - }, - "scope": { - - "Name": "scope" - }, - "nowrap": { - - "Name": "nowrap" - }, - "height": { - - "Name": "height" - }, - "width": { - - "Name": "width" - }, - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - }, - "colspan": { - - "Name": "colspan" - }, - "rowspan": { - - "Name": "rowspan" - } - }, - "Action": 2, - "Name": "td" - }, - { - "AllowedAttributes": { - "abbrev": { - - "Name": "abbrev" - }, - "axis": { - - "Name": "axis" - }, - "headers": { - - "Name": "headers" - }, - "scope": { - - "Name": "scope" - }, - "nowrap": { - - "Name": "nowrap" - }, - "bgcolor": { - - "Name": "bgcolor" - }, - "height": { - - "Name": "height" - }, - "width": { - - "Name": "width" - }, - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - }, - "colspan": { - - "Name": "colspan" - }, - "rowspan": { - - "Name": "rowspan" - } - }, - "Action": 2, - "Name": "th" - }, - { - "AllowedAttributes": { - "height": { - - "Name": "height" - }, - "width": { - - "Name": "width" - }, - "align": { - - "Name": "align" - }, - "valign": { - - "Name": "valign" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "background": { - - "Name": "background" - } - }, - "Action": 2, - "Name": "tr" - }, - { - "AllowedAttributes": { - "span": { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "span" - }, - "width": { - - "Name": "width" - }, - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - } - }, - "Action": 2, - "Name": "colgroup" - }, - { - "AllowedAttributes": { - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - }, - "span": { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "span" - }, - "width": { - - "Name": "width" - } - }, - "Action": 2, - "Name": "col" - }, - { - - "Action": 2, - "Name": "fieldset" - }, - { - - "Action": 2, - "Name": "legend" - } - ] -} \ No newline at end of file diff --git a/AntiXssUF.Mvc/resources/antixss-policy-Default.xml b/AntiXssUF.Mvc/resources/antixss-policy-Default.xml deleted file mode 100644 index 45c75ca..0000000 --- a/AntiXssUF.Mvc/resources/antixss-policy-Default.xml +++ /dev/null @@ -1,2417 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AntiXssUF.Mvc/resources/antixss-policy-antisamy-anythinggoes.xml b/AntiXssUF.Mvc/resources/antixss-policy-antisamy-anythinggoes.xml deleted file mode 100644 index b3e73f2..0000000 --- a/AntiXssUF.Mvc/resources/antixss-policy-antisamy-anythinggoes.xml +++ /dev/null @@ -1,2573 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AntiXssUF.Mvc/resources/antixss-policy-antisamy-ebay.xml b/AntiXssUF.Mvc/resources/antixss-policy-antisamy-ebay.xml deleted file mode 100644 index 5cbfde5..0000000 --- a/AntiXssUF.Mvc/resources/antixss-policy-antisamy-ebay.xml +++ /dev/null @@ -1,2385 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AntiXssUF.Mvc/resources/antixss-policy-antisamy-myspace.xml b/AntiXssUF.Mvc/resources/antixss-policy-antisamy-myspace.xml deleted file mode 100644 index 1c4ea9d..0000000 --- a/AntiXssUF.Mvc/resources/antixss-policy-antisamy-myspace.xml +++ /dev/null @@ -1,2558 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AntiXssUF.Mvc/resources/antixss-policy-antisamy-slashdot.xml b/AntiXssUF.Mvc/resources/antixss-policy-antisamy-slashdot.xml deleted file mode 100644 index a37485b..0000000 --- a/AntiXssUF.Mvc/resources/antixss-policy-antisamy-slashdot.xml +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AntiXssUF.Mvc/resources/antixss-policy-antisamy-test.xml b/AntiXssUF.Mvc/resources/antixss-policy-antisamy-test.xml deleted file mode 100644 index 631ea28..0000000 --- a/AntiXssUF.Mvc/resources/antixss-policy-antisamy-test.xml +++ /dev/null @@ -1,862 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AntiXssUF.Mvc/resources/antixss-policy-antisamy.xml b/AntiXssUF.Mvc/resources/antixss-policy-antisamy.xml deleted file mode 100644 index 72fe367..0000000 --- a/AntiXssUF.Mvc/resources/antixss-policy-antisamy.xml +++ /dev/null @@ -1,2572 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AntiXssUF.Mvc/resources/antixss-policy.xsd b/AntiXssUF.Mvc/resources/antixss-policy.xsd deleted file mode 100644 index 809f238..0000000 --- a/AntiXssUF.Mvc/resources/antixss-policy.xsd +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/AntiXssUF.TestSite/AntiXssUF.TestSite.csproj b/AntiXssUF.TestSite/AntiXssUF.TestSite.csproj index cec892b..6dfa0d0 100644 --- a/AntiXssUF.TestSite/AntiXssUF.TestSite.csproj +++ b/AntiXssUF.TestSite/AntiXssUF.TestSite.csproj @@ -27,7 +27,11 @@ - + + + + + diff --git a/AntiXssUF.TestSite/Controllers/HomeController.cs b/AntiXssUF.TestSite/Controllers/HomeController.cs index 546c61e..54909c6 100644 --- a/AntiXssUF.TestSite/Controllers/HomeController.cs +++ b/AntiXssUF.TestSite/Controllers/HomeController.cs @@ -20,7 +20,6 @@ namespace AntiXssUF.TestSite.Controllers private StringBuilder html; public HomeController(ILogger logger, IFilterPolicyFactory policyFactory) { - _logger = logger; this.policyFactory = policyFactory; } @@ -29,15 +28,18 @@ namespace AntiXssUF.TestSite.Controllers var clean = filter.Filters(source); return Content(clean); } + StringBuilder stringBuilder = new StringBuilder(); void FilterAttacks(RichText richText, Func fn, [CallerMemberName] string propertyName = null) { - html.Append($"\n==== in {propertyName} ==================================================\n原文:\n{ HttpUtility.HtmlEncode(richText.Source)}\n"); - - html.Append("过滤\n"); - string clean = richText.ToString(); - html.Append(HttpUtility.HtmlEncode(clean)); - html.Append($"\n状态:{fn(clean)}"); + stringBuilder.Append($"\n==== in {propertyName} ==================================================\n原文:\n{richText.Source}\n"); + stringBuilder.Append("过滤\n"); + string clean = richText.ToString(); + stringBuilder.Append(clean); + var isTrue = fn(clean); + + stringBuilder.Append($"\n状态:{isTrue}"); + } void testScriptAttacks() { @@ -56,13 +58,11 @@ namespace AntiXssUF.TestSite.Controllers FilterAttacks("", str => str.IndexOf("", str => str.IndexOf("", - str => str.IndexOf(" str.IndexOf("", str => str.IndexOf("&", StringComparison.OrdinalIgnoreCase) != -1); + FilterAttacks("", str => string.IsNullOrEmpty(str)); - FilterAttacks("javascript:alert('XSS')>", str => str.IndexOf("&", StringComparison.OrdinalIgnoreCase) != -1); - - FilterAttacks("", str => str.IndexOf("&", StringComparison.OrdinalIgnoreCase) != -1); + FilterAttacks("", str => string.IsNullOrEmpty(str)); FilterAttacks("", str => str.IndexOf("alert", StringComparison.OrdinalIgnoreCase) == -1); FilterAttacks(" str.IndexOf("javascript", StringComparison.OrdinalIgnoreCase) == -1); @@ -70,10 +70,9 @@ namespace AntiXssUF.TestSite.Controllers FilterAttacks("", str => str.IndexOf("javascript", StringComparison.OrdinalIgnoreCase) == -1); } - void testHrefAttacks() + + public void testHrefAttacks() { - - FilterAttacks("", str => str.IndexOf("href") == -1); FilterAttacks("", str => str.IndexOf("href") == -1); @@ -120,6 +119,8 @@ namespace AntiXssUF.TestSite.Controllers } + + void testCssAttacks() { FilterAttacks("
", str => str.IndexOf("position") == -1); @@ -127,41 +128,71 @@ namespace AntiXssUF.TestSite.Controllers FilterAttacks("
", str => str.IndexOf("position") == -1); FilterAttacks("", str => str.IndexOf("position") == -1); } + + public IActionResult Index() { - IEnumerable list = null; - if( !(list?.Count()).HasValue) { - - } - //RichText richText = ""; //string ss = richText; - ////var policy = policyFactory.CreatePolicy("json").Result; + ////var policy = policyFactory.CreatePolicy("DefaultPolicy").Result; ////var str = Newtonsoft.Json.JsonConvert.SerializeObject(new ////{ //// policy.Directives, //// policy.CommonRegularExpressions, - //// CommonAttributes = policy.CommonAttributes.Select(e => e.Value), - //// CssRules = policy.CssRules.Select(e => e.Value), - //// GlobalAttributes = policy.GlobalAttributes.Values, - //// TagRules = policy.TagRules.Values + //// CommonAttributes = policy.CommonAttributes.Values.Select(e => new + //// { + //// e.Name, + //// OnInvalid = e.OnInvalid == default(PolicyHtmlAttributeOnInvalid) ? null : e.OnInvalid.ToString(), + //// AllowedRegExp = e.AllowedRegExp == null || e.AllowedRegExp.Length == 0 ? null : e.AllowedRegExp, + //// AllowedValues = e.AllowedValues == null || e.AllowedValues.Length == 0 ? null : e.AllowedValues, + //// Description = string.IsNullOrEmpty(e.Description) ? null : e.Description, + //// }), + //// CssRules = policy.CssRules.Values.Select(e => new + //// { + //// e.Name, + //// Shorthands = e.Shorthands == null || e.Shorthands.Length == 0 ? null : e.Shorthands, + //// AllowedRegExp = e.AllowedRegExp == null || e.AllowedRegExp.Length == 0 ? null : e.AllowedRegExp, + //// AllowedValues = e.AllowedValues == null || e.AllowedValues.Length == 0 ? null : e.AllowedValues, + //// Description = string.IsNullOrEmpty(e.Description) ? null : e.Description, + //// }), + //// GlobalAttributes = policy.GlobalAttributes.Values.Select(e => new + //// { + //// e.Name, + //// OnInvalid = e.OnInvalid == default(PolicyHtmlAttributeOnInvalid) ? null : e.OnInvalid.ToString(), + //// AllowedRegExp = e.AllowedRegExp == null || e.AllowedRegExp.Length == 0 ? null : e.AllowedRegExp, + //// AllowedValues = e.AllowedValues == null || e.AllowedValues.Length == 0 ? null : e.AllowedValues, + //// Description = string.IsNullOrEmpty(e.Description) ? null : e.Description, + //// }), + //// TagRules = policy.TagRules.Values.Select(tag => new + //// { + //// Action = tag.Action == default(PolicyHtmlTagAction) ? null : tag.Action.ToString(), + //// tag.Name, + //// AllowedAttributes = tag.AllowedAttributes == null || tag.AllowedAttributes.Values.Count == 0 ? null : + //// tag.AllowedAttributes.Values.Select(e => new + //// { + //// e.Name, + //// OnInvalid = e.OnInvalid == default(PolicyHtmlAttributeOnInvalid) ? null : e.OnInvalid.ToString(), + //// AllowedRegExp = e.AllowedRegExp == null || e.AllowedRegExp.Length == 0 ? null : e.AllowedRegExp, + //// AllowedValues = e.AllowedValues == null || e.AllowedValues.Length == 0 ? null : e.AllowedValues, + //// Description = string.IsNullOrEmpty(e.Description) ? null : e.Description, + //// }), + + //// }) ////}, new Newtonsoft.Json.JsonSerializerSettings() { NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore }); - // + ////// Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - html = new StringBuilder(); FilterAttacks("", str => str.IndexOf("opt.DefaultSchemeName= "test") + services.AddXssFilter(opt=>opt.DefaultSchemeName= "DefaultPolicy") .AddScheme("antisamy", () => File.ReadAllTextAsync(Path.Combine(HostEnvironment.ContentRootPath, "resources/antisamy.xml"))) .AddScheme("anythinggoes", () => File.ReadAllTextAsync(Path.Combine(HostEnvironment.ContentRootPath, "resources/antisamy-anythinggoes.xml"))) .AddScheme("ebay", () => File.ReadAllTextAsync(Path.Combine(HostEnvironment.ContentRootPath, "resources/antisamy-ebay.xml"))) diff --git a/AntiXssUF.TestSite/Views/Home/Index.cshtml b/AntiXssUF.TestSite/Views/Home/Index.cshtml index 33e44b1..66ce47a 100644 --- a/AntiXssUF.TestSite/Views/Home/Index.cshtml +++ b/AntiXssUF.TestSite/Views/Home/Index.cshtml @@ -2,30 +2,4 @@ ViewData["Title"] = "测试"; } -
- -
- -
-
+ @Html.Raw(Html.Encode(ViewBag.Test).Replace(" ", "
")) diff --git a/AntiXssUF.sln b/AntiXssUF.sln index 96e24bc..882554e 100644 --- a/AntiXssUF.sln +++ b/AntiXssUF.sln @@ -16,7 +16,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution appveyor.yml = appveyor.yml EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AntiXssUF.Mvc", "AntiXssUF.Mvc\AntiXssUF.Mvc.csproj", "{0252B16F-E2CA-4CC9-BA5E-52701D90EB49}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Framework461Test", "Framework461Test\Framework461Test.csproj", "{AFDE17BE-9067-44B7-9AED-8184ABB57E5C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -32,10 +32,10 @@ Global {313AE160-70B2-4A7C-9E1A-F00353C0A75A}.Debug|Any CPU.Build.0 = Debug|Any CPU {313AE160-70B2-4A7C-9E1A-F00353C0A75A}.Release|Any CPU.ActiveCfg = Release|Any CPU {313AE160-70B2-4A7C-9E1A-F00353C0A75A}.Release|Any CPU.Build.0 = Release|Any CPU - {0252B16F-E2CA-4CC9-BA5E-52701D90EB49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0252B16F-E2CA-4CC9-BA5E-52701D90EB49}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0252B16F-E2CA-4CC9-BA5E-52701D90EB49}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0252B16F-E2CA-4CC9-BA5E-52701D90EB49}.Release|Any CPU.Build.0 = Release|Any CPU + {AFDE17BE-9067-44B7-9AED-8184ABB57E5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AFDE17BE-9067-44B7-9AED-8184ABB57E5C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AFDE17BE-9067-44B7-9AED-8184ABB57E5C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AFDE17BE-9067-44B7-9AED-8184ABB57E5C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -43,7 +43,7 @@ Global GlobalSection(NestedProjects) = preSolution {1F7B7964-68FC-4AC9-BE42-EC8294F779E6} = {D658E57D-27C2-439A-8D75-C0C4FBB1F6E1} {313AE160-70B2-4A7C-9E1A-F00353C0A75A} = {0676D379-1AB7-4009-8E06-6D5D05B11D06} - {0252B16F-E2CA-4CC9-BA5E-52701D90EB49} = {0676D379-1AB7-4009-8E06-6D5D05B11D06} + {AFDE17BE-9067-44B7-9AED-8184ABB57E5C} = {D658E57D-27C2-439A-8D75-C0C4FBB1F6E1} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2A023FAF-6AAB-40ED-984D-E961234DDC13} diff --git a/AntiXssUF/AntiXssUF.csproj b/AntiXssUF/AntiXssUF.csproj index 279cd6a..da3314f 100644 --- a/AntiXssUF/AntiXssUF.csproj +++ b/AntiXssUF/AntiXssUF.csproj @@ -1,20 +1,24 @@ - + - netstandard2.1 + net461;netstandard2.0;netstandard2.1;netcoreapp2.1;netcoreapp3.1 AntiXssUF Ufangx.Xss true xss anit policy filter Jackson.bruce ufangx - Copyright (c) 2020 Jackson.Bruce + Copyright (c) 2020-$([System.DateTime]::Now.Year) Jackson.Bruce https://github.com/JacksonBruce/AntiXssUF https://github.com/JacksonBruce/AntiXssUF.git Anti Xss .NETStandard https://github.com/JacksonBruce/AntiXssUF/blob/master/README.md git + bin\$(Configuration)\$(TargetFramework)\AntiXssUF.xml + false + 2.0.0 + @@ -31,11 +35,172 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + + + + + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + + + + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + + + + + + + + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + 3.1.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AntiXssUF/AntiXssUFServiceCollectionExtensions.cs b/AntiXssUF/AntiXssUFServiceCollectionExtensions.cs index efdde09..033ea2c 100644 --- a/AntiXssUF/AntiXssUFServiceCollectionExtensions.cs +++ b/AntiXssUF/AntiXssUFServiceCollectionExtensions.cs @@ -5,17 +5,23 @@ using Ufangx.Xss; namespace Microsoft.Extensions.DependencyInjection { + /// + /// 服务扩展方法 + /// public static class AntiXssUFServiceCollectionExtensions { + /// + /// 添加Xss过滤器 + /// + /// + /// + /// public static XssFilterBuilder AddXssFilter(this IServiceCollection services, Action configureOptions=null) { if (services is null) { throw new ArgumentNullException(nameof(services)); } - if (configureOptions != null) - { - services.Configure(configureOptions); - } + new Configures(services).Options(configureOptions); services.AddSingleton(); services.AddTransient(); return XssFilterBuilder.Builder ?? new XssFilterBuilder(services); diff --git a/AntiXssUF/AntisamyPolicy.cs b/AntiXssUF/AntisamyPolicy.cs index a0bd225..c05cc3a 100644 --- a/AntiXssUF/AntisamyPolicy.cs +++ b/AntiXssUF/AntisamyPolicy.cs @@ -6,6 +6,9 @@ using System.Web; namespace Ufangx.Xss { + /// + /// OwaspAntisamy配置策略 + /// [Serializable] public class AntisamyPolicy: IFilterPolicy { @@ -14,23 +17,43 @@ namespace Ufangx.Xss Dictionary tagRules; Dictionary cssRules; private string name; - + /// + /// 策略名称 + /// public string Name => name; - + /// + /// 公用正则表达式 + /// public Dictionary CommonRegularExpressions =>commonRegularExpressions; - + /// + /// 控制设置 + /// public Dictionary Directives => directives; - + /// + /// 公用属性 + /// public Dictionary CommonAttributes => commonAttributes; - + /// + /// 全局属性白名单 + /// public Dictionary GlobalAttributes =>globalAttributes; - + /// + /// html标签白名单 + /// public Dictionary TagRules => tagRules; - + /// + /// 样式表规则白名单 + /// public Dictionary CssRules =>cssRules; - + /// + /// 是否已经初始化 + /// public bool Initialized { get; private set; } - + /// + /// 初始化策略 + /// + /// XML配置文档 + /// 策略名称 public void Init(string config,string name) { if (Initialized) return; @@ -42,7 +65,6 @@ namespace Ufangx.Xss { throw new ArgumentException("message", nameof(name)); } - this.name = name; XDocument doc; try { @@ -51,10 +73,12 @@ namespace Ufangx.Xss catch (Exception x) { throw new FilterPolicyException("无效的XSSAttacks过滤策略。", x); } try { - Init(doc); + Init(doc); + Initialized = true; + this.name = name; } catch (Exception x) { throw new FilterPolicyException("XSSAttacks策略文档不是一个有效的架构。", x); } - Initialized = true; + } diff --git a/AntiXssUF/Configures.cs b/AntiXssUF/Configures.cs new file mode 100644 index 0000000..14a26bd --- /dev/null +++ b/AntiXssUF/Configures.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ufangx.Xss +{ + internal partial class Configures + { + private readonly IServiceCollection services; + + public Configures(IServiceCollection services) + { + this.services = services; + } + public void Options(Action configure,string name=null) where TOptions : class, new() { + + _Options(configure,name); + } + partial void _Options(Action configure,string name) where TOptions : class, new(); + } +} diff --git a/AntiXssUF/Configures.net461.cs b/AntiXssUF/Configures.net461.cs new file mode 100644 index 0000000..d83f807 --- /dev/null +++ b/AntiXssUF/Configures.net461.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; + +namespace Ufangx.Xss +{ + internal partial class Configures + { + static Dictionary> _options = new Dictionary>(); + partial void _Options(Action configure, string name) where TOptions : class, new() + { + + var key = typeof(TOptions); + if (!_options.ContainsKey(key)) _options.Add(key, new List()); + if (configure != null) { _options[key].Add(configure); } + + + services.AddTransient(provider => { + + var opt = new TOptions(); + var list = _options[key]; + foreach (var item in list) + { + if (item is Action conf) { + conf(opt); + } + } + return opt; + }); + } + } +} diff --git a/AntiXssUF/Configures.netstandard.cs b/AntiXssUF/Configures.netstandard.cs new file mode 100644 index 0000000..43a523a --- /dev/null +++ b/AntiXssUF/Configures.netstandard.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ufangx.Xss +{ + internal partial class Configures + { + partial void _Options(Action configure, string name) where TOptions : class, new() + { + if (configure == null) return; + if (string.IsNullOrEmpty(name)) services.Configure(configure); + else services.Configure(name, configure); + } + } +} diff --git a/AntiXssUF/CssFilter.cs b/AntiXssUF/CssFilter.cs index d14f1c7..35d70db 100644 --- a/AntiXssUF/CssFilter.cs +++ b/AntiXssUF/CssFilter.cs @@ -12,18 +12,36 @@ using System.Threading.Tasks; namespace Ufangx.Xss { + /// + /// 样式过滤器 + /// public class CssFilter : ICssFilter { #region 构造 + /// + /// 创建样式过滤器 + /// + /// public CssFilter(IFilterPolicy policy) { Policy = policy ?? throw new ArgumentNullException(nameof(policy)); EmbedStyleSheets = policy.Directive("embedStyleSheets"); } #endregion + /// + /// 过滤策略 + /// protected virtual IFilterPolicy Policy { get; } + /// + /// 验证规则 + /// protected virtual bool EmbedStyleSheets { get; set; } + /// + /// 验证规则 + /// + /// + /// protected virtual bool Validate(ICssProperty attr) { if (attr == null) return false; @@ -32,7 +50,11 @@ namespace Ufangx.Xss return Policy.ValidateAttribute(property, attr.Value) || (property.Shorthands?.Any(shorthandPropertyName => Policy.ValidateAttribute(Policy.CssProperty(shorthandPropertyName), attr.Value)) ?? false); } - + /// + /// 过滤规则 + /// + /// + /// protected virtual string Filters(ICssStyleSheet cssStyleSheet) { if (cssStyleSheet == null || cssStyleSheet.Rules.Length == 0) return string.Empty; @@ -46,7 +68,11 @@ namespace Ufangx.Xss } return cssStyleSheet.ToCss(); } - + /// + /// 验证规则 + /// + /// + /// protected virtual bool Validate(ICssRule rule) { if (rule is ICssStyleRule styleRule) @@ -77,6 +103,11 @@ namespace Ufangx.Xss return false; } + /// + /// 验证规则 + /// + /// + /// protected virtual bool Validate(ICssStyleDeclaration styles) { if (styles == null) return false; @@ -92,6 +123,11 @@ namespace Ufangx.Xss return styles.Length > 0; } + /// + /// 过滤样式 + /// + /// + /// public string Filters(string code) { if (string.IsNullOrWhiteSpace(code)) return string.Empty; @@ -114,7 +150,7 @@ namespace Ufangx.Xss } catch (Exception ex) { - throw; + throw ex; } return Filters(styleSheet); diff --git a/AntiXssUF/ExtensionMethods.cs b/AntiXssUF/ExtensionMethods.cs index 0bc1d27..9b34b16 100644 --- a/AntiXssUF/ExtensionMethods.cs +++ b/AntiXssUF/ExtensionMethods.cs @@ -7,11 +7,15 @@ using System.Linq; namespace Ufangx.Xss { + /// + /// 过滤策略扩展方法 + /// public static class ExtensionMethods { /// /// 验证属性的值是否有效 /// + /// /// /// /// @@ -34,7 +38,7 @@ namespace Ufangx.Xss if (attr.AllowedRegExp != null) { - ///验证是否符合指定的正则表达式 + //验证是否符合指定的正则表达式 foreach (var regx in attr.AllowedRegExp) { if (string.IsNullOrWhiteSpace(regx.Name) && string.IsNullOrWhiteSpace(regx.Value)) continue; @@ -59,30 +63,74 @@ namespace Ufangx.Xss static T Get(IDictionary collection, string key)where T:class { return key == null || collection == null || !collection.ContainsKey(key = key.ToLower()) ? null : collection[key]; } + /// + /// 获取标签策略 + /// + /// + /// + /// public static PolicyHtmlTag Tag(this IFilterPolicy policy, string tagName) { return Get(policy?.TagRules, tagName); } + /// + /// 获取样式属性过滤策略 + /// + /// + /// + /// public static PolicyCssProperty CssProperty(this IFilterPolicy policy, string name) { return Get(policy?.CssRules, name); } + /// + /// 获取通用属性过滤策略 + /// + /// + /// + /// public static PolicyHtmlAttribute CommonHtmlAttribute(this IFilterPolicy policy, string name) { return Get(policy?.CommonAttributes, name); } + /// + /// 获取全局属性过滤策略 + /// + /// + /// + /// public static PolicyHtmlAttribute GlobalHtmlAttribute(this IFilterPolicy policy, string name) { return Get(policy?.GlobalAttributes, name); } + /// + /// 获取通用正则表达式 + /// + /// + /// + /// public static string RegularExpression(this IFilterPolicy policy, string name) { return Get(policy?.CommonRegularExpressions, name); } + /// + /// + /// + /// + /// + /// public static string Directive(this IFilterPolicy policy, string name) { return Get(policy?.Directives, name); } + /// + /// + /// + /// + /// + /// + /// + /// public static T Directive(this IFilterPolicy policy, string name,T @default=default(T)) where T : struct { string v = Directive(policy,name); @@ -109,6 +157,13 @@ namespace Ufangx.Xss } return @default; } + /// + /// 获取属性过滤策略 + /// + /// + /// + /// + /// public static PolicyHtmlAttribute AllowedAttribute(this IFilterPolicy policy,string name, PolicyHtmlTag tag) { var tagAttr = tag.AllowedAttributes.ContainsKey(name) ? tag.AllowedAttributes[name] : null; diff --git a/AntiXssUF/FilterPolicyBuilder.cs b/AntiXssUF/FilterPolicyBuilder.cs index 3e77175..f685e38 100644 --- a/AntiXssUF/FilterPolicyBuilder.cs +++ b/AntiXssUF/FilterPolicyBuilder.cs @@ -5,14 +5,29 @@ using System.Threading.Tasks; namespace Ufangx.Xss { + /// + /// 策略生成器 + /// public class FilterPolicyBuilder { + /// + /// 创建策略生成器 + /// + /// public FilterPolicyBuilder(string Name) { this.Name = Name; } - + /// + /// 策略名称 + /// public string Name { get; } + /// + /// 策略类型 + /// public Type PolicyType { get; set; } + /// + /// 获取策略配置方法 + /// public Func> GetConfig { get; set; } } diff --git a/AntiXssUF/FilterPolicyException.cs b/AntiXssUF/FilterPolicyException.cs index fe69108..99f7e0a 100644 --- a/AntiXssUF/FilterPolicyException.cs +++ b/AntiXssUF/FilterPolicyException.cs @@ -6,11 +6,31 @@ using System.Text; namespace Ufangx.Xss { + /// + /// 策略异常 + /// public class FilterPolicyException:Exception { + /// + /// 创建策略异常 + /// public FilterPolicyException() { } + /// + /// + /// + /// public FilterPolicyException(string message) : base(message) { } + /// + /// + /// + /// + /// public FilterPolicyException(string message, Exception innerException) : base(message, innerException) { } + /// + /// + /// + /// + /// public FilterPolicyException(SerializationInfo info, StreamingContext context) : base(info, context) { } } } diff --git a/AntiXssUF/FilterPolicyFactory.cs b/AntiXssUF/FilterPolicyFactory.cs index 8725fe7..c0d0d80 100644 --- a/AntiXssUF/FilterPolicyFactory.cs +++ b/AntiXssUF/FilterPolicyFactory.cs @@ -1,5 +1,4 @@ -using Microsoft.Extensions.Caching.Distributed; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Text; @@ -7,14 +6,25 @@ using System.Threading.Tasks; namespace Ufangx.Xss { + /// + /// 过滤策略工厂 + /// public class FilterPolicyFactory : IFilterPolicyFactory { private readonly IFilterPolicyProvider provider; - + /// + /// 创建过滤策略工厂 + /// + /// public FilterPolicyFactory(IFilterPolicyProvider provider) { this.provider = provider; } + /// + /// 创建过滤策略 + /// + /// + /// public async Task CreatePolicy(string name = null) { FilterPolicyBuilder builder; @@ -41,14 +51,32 @@ namespace Ufangx.Xss } return policy; } + /// + /// 创建html过滤器 + /// + /// + /// public async Task CreateHtmlFilter(string policyName = null) => await CreateHtmlFilter(await CreatePolicy(policyName)); + /// + /// 创建Css过滤器 + /// + /// + /// public async Task CreateCssFilter(string policyName=null) => await CreateCssFilter(await CreatePolicy(policyName)); - + /// + /// 创建html过滤器 + /// + /// + /// public Task CreateHtmlFilter(IFilterPolicy policy) => Task.FromResult(new HtmlFilter(policy)); - + /// + /// 创建Css过滤器 + /// + /// + /// public Task CreateCssFilter(IFilterPolicy policy) => Task.FromResult(new CssFilter(policy)); } diff --git a/AntiXssUF/FilterPolicyOptions.cs b/AntiXssUF/FilterPolicyOptions.cs index 381b6d2..7c9bd5e 100644 --- a/AntiXssUF/FilterPolicyOptions.cs +++ b/AntiXssUF/FilterPolicyOptions.cs @@ -5,12 +5,25 @@ using System.Threading.Tasks; namespace Ufangx.Xss { + /// + /// + /// public class FilterPolicyOptions { private readonly IList _schemes = new List(); - + /// + /// 策略集合 + /// public IEnumerable Schemes => _schemes; + /// + /// 策略字典集合 + /// public IDictionary SchemeMap { get; } = new Dictionary(StringComparer.Ordinal); + /// + /// 添加策略 + /// + /// + /// public void AddScheme(string name, Action configureBuilder) { if (name == null) @@ -30,18 +43,33 @@ namespace Ufangx.Xss _schemes.Add(builder); SchemeMap[name] = builder; } + /// + /// 添加策略 + /// + /// + /// + /// public void AddScheme(string name, string config) where TPolicyType : IFilterPolicy => AddScheme(name, b => { b.GetConfig = () => Task.FromResult(config); b.PolicyType = typeof(TPolicyType); }); + /// + /// 添加策略 + /// + /// + /// + /// public void AddScheme(string name, Func> config) where TPolicyType : IFilterPolicy => AddScheme(name, b => { b.GetConfig = config; b.PolicyType = typeof(TPolicyType); }); + /// + /// 默认过滤策略 + /// public string DefaultSchemeName { get; set; } } } diff --git a/AntiXssUF/FilterPolicyProvider.cs b/AntiXssUF/FilterPolicyProvider.cs index 46ed156..52691ba 100644 --- a/AntiXssUF/FilterPolicyProvider.cs +++ b/AntiXssUF/FilterPolicyProvider.cs @@ -1,5 +1,4 @@ -using Microsoft.Extensions.Options; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -7,27 +6,11 @@ using System.Threading.Tasks; namespace Ufangx.Xss { - public class FilterPolicyProvider : IFilterPolicyProvider + /// + /// 策略管理提供者 + /// + public partial class FilterPolicyProvider : IFilterPolicyProvider { - public FilterPolicyProvider(IOptions options) - : this(options, new Dictionary(StringComparer.OrdinalIgnoreCase)) - { - } - - protected FilterPolicyProvider(IOptions options, IDictionary schemes) - { - _options = options.Value; - - _schemes = schemes ?? throw new ArgumentNullException(nameof(schemes)); - _requestHandlers = new List(); - - foreach (var builder in _options.Schemes) - { - ///var scheme = builder.Build(); - AddScheme(builder); - } - } - private readonly FilterPolicyOptions _options; private readonly IDictionary _schemes; @@ -35,7 +18,11 @@ namespace Ufangx.Xss private readonly object _lock = new object(); private FilterPolicyBuilder[] _requestHandlersCopy; private FilterPolicyBuilder[] _schemesCopy; - + /// + /// 尝试添加策略方案 + /// + /// + /// public virtual bool TryAddScheme(FilterPolicyBuilder scheme) { if (_schemes.ContainsKey(scheme.Name)) @@ -58,6 +45,10 @@ namespace Ufangx.Xss return true; } } + /// + /// 添加策略方案 + /// + /// public virtual void AddScheme(FilterPolicyBuilder scheme) { if (_schemes.ContainsKey(scheme.Name)) @@ -72,6 +63,10 @@ namespace Ufangx.Xss } } } + /// + /// 移除策略方案 + /// + /// public virtual void RemoveScheme(string name) { if (!_schemes.ContainsKey(name)) @@ -92,12 +87,25 @@ namespace Ufangx.Xss } } } + /// + /// 获取策略 + /// + /// + /// public virtual Task GetSchemeAsync(string name) => Task.FromResult(_schemes.ContainsKey(name) ? _schemes[name] : null); + /// + /// 获取默认策略 + /// + /// public virtual Task GetDefaultSchemeAsync() => _options.DefaultSchemeName != null ? GetSchemeAsync(_options.DefaultSchemeName) : Task.FromResult(null); + /// + /// 返回所有策略方案 + /// + /// public virtual async Task> GetSchemesAsync() => await Task.FromResult(_requestHandlersCopy); } diff --git a/AntiXssUF/FilterPolicyProvider.net461.cs b/AntiXssUF/FilterPolicyProvider.net461.cs new file mode 100644 index 0000000..8b55f6b --- /dev/null +++ b/AntiXssUF/FilterPolicyProvider.net461.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ufangx.Xss +{ + public partial class FilterPolicyProvider : IFilterPolicyProvider + { + /// + /// 创建策略方案提供者 + /// + /// + public FilterPolicyProvider(FilterPolicyOptions options) + : this(options, new Dictionary(StringComparer.OrdinalIgnoreCase)) + { + } + /// + /// 创建策略方案提供者 + /// + /// + /// + protected FilterPolicyProvider(FilterPolicyOptions options, IDictionary schemes) + { + _options = options; + + _schemes = schemes ?? throw new ArgumentNullException(nameof(schemes)); + _requestHandlers = new List(); + + foreach (var builder in _options.Schemes) + { + AddScheme(builder); + } + } + + } +} diff --git a/AntiXssUF/FilterPolicyProvider.netstandard.cs b/AntiXssUF/FilterPolicyProvider.netstandard.cs new file mode 100644 index 0000000..436157b --- /dev/null +++ b/AntiXssUF/FilterPolicyProvider.netstandard.cs @@ -0,0 +1,39 @@ +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ufangx.Xss +{ + public partial class FilterPolicyProvider : IFilterPolicyProvider + { + /// + /// 创建策略方案提供者 + /// + /// + public FilterPolicyProvider(IOptions options) + : this(options, new Dictionary(StringComparer.OrdinalIgnoreCase)) + { + } + /// + /// 创建策略方案提供者 + /// + /// + /// + protected FilterPolicyProvider(IOptions options, IDictionary schemes) + { + _options = options.Value; + + _schemes = schemes ?? throw new ArgumentNullException(nameof(schemes)); + _requestHandlers = new List(); + + foreach (var builder in _options.Schemes) + { + AddScheme(builder); + } + } + + } +} diff --git a/AntiXssUF/FilterRegExp.cs b/AntiXssUF/FilterRegExp.cs index e27b496..adece39 100644 --- a/AntiXssUF/FilterRegExp.cs +++ b/AntiXssUF/FilterRegExp.cs @@ -4,15 +4,32 @@ using System.Text; namespace Ufangx.Xss { - + /// + /// 过滤正则表达式 + /// [Serializable] public class FilterRegExp { + /// + /// 表达式名称 + /// public string Name { get; set; } + /// + /// 正则表达式 + /// public string Value { get; set; } } + /// + /// 正则表达式比较器 + /// public class FilterRegExpComparer : IEqualityComparer { + /// + /// + /// + /// + /// + /// public bool Equals(FilterRegExp x, FilterRegExp y) { if (ReferenceEquals(x, y)||x==null&&y==null) return true; @@ -20,7 +37,11 @@ namespace Ufangx.Xss return string.Equals(x.Name, y.Name, StringComparison.OrdinalIgnoreCase) && string.Equals(x.Value, y.Value, StringComparison.OrdinalIgnoreCase); } - + /// + /// + /// + /// + /// public int GetHashCode(FilterRegExp obj) { return (obj.Name ?? string.Empty).GetHashCode() ^ (obj.Value ?? string.Empty).GetHashCode(); diff --git a/AntiXssUF/HtmlFilter.cs b/AntiXssUF/HtmlFilter.cs index 81f5956..ab75367 100644 --- a/AntiXssUF/HtmlFilter.cs +++ b/AntiXssUF/HtmlFilter.cs @@ -11,21 +11,39 @@ using System.Xml; using Microsoft.Extensions.DependencyInjection; namespace Ufangx.Xss { + /// + /// html过滤器 + /// public class HtmlFilter : IHtmlFilter { #region 构造 + /// + /// 创建html过滤器 + /// + /// + /// public HtmlFilter(IFilterPolicy policy, ICssFilter cssFilter) { Policy = policy ?? throw new ArgumentNullException(nameof(policy)); _cssFilter = cssFilter; } + /// + /// 创建html过滤器 + /// + /// public HtmlFilter(IFilterPolicy policy):this(policy,null) { } #endregion #region 属性 + /// + /// 当前过滤策略 + /// protected virtual IFilterPolicy Policy { get; } ICssFilter _cssFilter; + /// + /// 当前css过滤器 + /// protected virtual ICssFilter CssFilter { get { if (_cssFilter == null) { @@ -38,7 +56,11 @@ namespace Ufangx.Xss #endregion #region 公共方法 - + /// + /// 过滤html + /// + /// + /// public virtual string Filters(string html) { if (html == null || html.Length == 0) @@ -111,26 +133,31 @@ namespace Ufangx.Xss switch (actoin) { case PolicyHtmlTagAction.Filter: - ///删除当前节点,但保留其有效的子节点 + //删除当前节点,但保留其有效的子节点 PromoteChildren(node); return; case PolicyHtmlTagAction.Validate: - ///过滤当前元素的属性与及子节点 + //过滤当前元素的属性与及子节点 ValidateAction(node, nodeName, tag); return; case PolicyHtmlTagAction.Truncate: - ///删除当前节点的所有属性以及子节点,但保留文本和备注节点。 + //删除当前节点的所有属性以及子节点,但保留文本和备注节点。 TruncateAction(node); return; default: - ///将当前节点从父节点中删除。 + //将当前节点从父节点中删除。 var parentNode = node.Parent; parentNode.RemoveChild(node); break; } } - + /// + /// 验证html标签 + /// + /// + /// + /// protected virtual void ValidateAction(IElement node, string tagName, PolicyHtmlTag tag) { var parentNode = node.Parent; @@ -169,6 +196,10 @@ namespace Ufangx.Xss try { attribute.Value = CssFilter.Filters(_value); + if (string.IsNullOrWhiteSpace(attribute.Value)) { + node.RemoveAttribute(name); + currentAttributeIndex--; + } } catch { @@ -178,7 +209,7 @@ namespace Ufangx.Xss continue; } #endregion - ///如果未能通过验证,将执行指定的操作 + //如果未能通过验证,将执行指定的操作 if (!Policy.ValidateAttribute(attr, _value)) { switch (attr.OnInvalid) @@ -188,7 +219,7 @@ namespace Ufangx.Xss parentNode.RemoveChild(node); return; case PolicyHtmlAttributeOnInvalid.FilterTag: - ///删除当前节点,但保留其有效的子节点 + //删除当前节点,但保留其有效的子节点 PromoteChildren(node); return; default: @@ -201,7 +232,7 @@ namespace Ufangx.Xss } } #endregion - ///过滤当前元素的子节点 + //过滤当前元素的子节点 FiltersTags(node.ChildNodes); } @@ -258,11 +289,11 @@ namespace Ufangx.Xss /// protected virtual void PromoteChildren(IElement node) { - ///过滤子节点 + //过滤子节点 FiltersTags(node.ChildNodes); var nodeList = node.ChildNodes; var parent = node.Parent; - ///将它的所有子节点往上移到父节点的前面 + //将它的所有子节点往上移到父节点的前面 while (nodeList.Length > 0) { var removeNode = node.RemoveChild(nodeList[0]); diff --git a/AntiXssUF/ICssFilter.cs b/AntiXssUF/ICssFilter.cs index fd358aa..18810b6 100644 --- a/AntiXssUF/ICssFilter.cs +++ b/AntiXssUF/ICssFilter.cs @@ -1,7 +1,15 @@ namespace Ufangx.Xss { + /// + /// Css过滤器 + /// public interface ICssFilter { + /// + /// 过滤css + /// + /// + /// string Filters(string code); } } \ No newline at end of file diff --git a/AntiXssUF/IFilterPolicy.cs b/AntiXssUF/IFilterPolicy.cs index 5c61d0d..d1bac81 100644 --- a/AntiXssUF/IFilterPolicy.cs +++ b/AntiXssUF/IFilterPolicy.cs @@ -2,17 +2,48 @@ namespace Ufangx.Xss { + /// + /// 过滤策略 + /// public interface IFilterPolicy { - + /// + /// 策略名称 + /// string Name { get; } + /// + /// 初始化策略 + /// + /// 配置文档 + /// 策略名称 void Init(string config, string name); + /// + /// 是否已经初始化 + /// bool Initialized { get; } + /// + /// 公用正则表达式 + /// Dictionary CommonRegularExpressions { get; } + /// + /// 控制设置 + /// Dictionary Directives { get; } + /// + /// 公用属性 + /// Dictionary CommonAttributes { get; } + /// + /// 全局属性白名单 + /// Dictionary GlobalAttributes { get; } + /// + /// html标签白名单 + /// Dictionary TagRules { get; } + /// + /// 样式表规则白名单 + /// Dictionary CssRules { get; } } } \ No newline at end of file diff --git a/AntiXssUF/IFilterPolicyFactory.cs b/AntiXssUF/IFilterPolicyFactory.cs index 51c905d..c89ef6c 100644 --- a/AntiXssUF/IFilterPolicyFactory.cs +++ b/AntiXssUF/IFilterPolicyFactory.cs @@ -2,12 +2,40 @@ namespace Ufangx.Xss { + /// + /// 过来策略工厂 + /// public interface IFilterPolicyFactory { + /// + /// 创建过滤策略 + /// + /// + /// Task CreatePolicy(string name = null); + /// + /// 创建html过滤器 + /// + /// + /// Task CreateHtmlFilter(string policyName = null); + /// + /// 创建css过滤器 + /// + /// + /// Task CreateCssFilter(string policyName = null); + /// + /// 创建html过滤器 + /// + /// + /// Task CreateHtmlFilter(IFilterPolicy policy); + /// + /// 创建css过滤器 + /// + /// + /// Task CreateCssFilter(IFilterPolicy policy); } } \ No newline at end of file diff --git a/AntiXssUF/IFilterPolicyProvider.cs b/AntiXssUF/IFilterPolicyProvider.cs index 24f1ecf..5659ea9 100644 --- a/AntiXssUF/IFilterPolicyProvider.cs +++ b/AntiXssUF/IFilterPolicyProvider.cs @@ -3,13 +3,42 @@ using System.Threading.Tasks; namespace Ufangx.Xss { + /// + /// 策略提供者接口 + /// public interface IFilterPolicyProvider { + /// + /// 添加策略方案 + /// + /// void AddScheme(FilterPolicyBuilder scheme); + /// + /// 获取默认策略方案 + /// + /// Task GetDefaultSchemeAsync(); + /// + /// 获取策略方案 + /// + /// + /// Task GetSchemeAsync(string name); + /// + /// 返回所有策略方案 + /// + /// Task> GetSchemesAsync(); + /// + /// 移除策略方案 + /// + /// void RemoveScheme(string name); + /// + /// 尝试添加策略 + /// + /// + /// bool TryAddScheme(FilterPolicyBuilder scheme); } } \ No newline at end of file diff --git a/AntiXssUF/IHtmlFilter.cs b/AntiXssUF/IHtmlFilter.cs index 73f3e93..6dc301f 100644 --- a/AntiXssUF/IHtmlFilter.cs +++ b/AntiXssUF/IHtmlFilter.cs @@ -1,7 +1,15 @@ namespace Ufangx.Xss { + /// + /// html过滤器 + /// public interface IHtmlFilter { + /// + /// 过滤html + /// + /// + /// string Filters(string html); } } \ No newline at end of file diff --git a/AntiXssUF/IXssSchemeName.net461.cs b/AntiXssUF/IXssSchemeName.net461.cs new file mode 100644 index 0000000..690797e --- /dev/null +++ b/AntiXssUF/IXssSchemeName.net461.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Web; + +namespace Ufangx.Xss +{ + /// + /// + /// + public interface IXssSchemeName + { + /// + /// + /// + /// + /// + Task GetSchemeName(HttpContextBase httpContext); + } +} diff --git a/AntiXssUF.Mvc/IXssSchemeName.cs b/AntiXssUF/IXssSchemeName.netcoreapp.cs similarity index 52% rename from AntiXssUF.Mvc/IXssSchemeName.cs rename to AntiXssUF/IXssSchemeName.netcoreapp.cs index c80b421..07daa7c 100644 --- a/AntiXssUF.Mvc/IXssSchemeName.cs +++ b/AntiXssUF/IXssSchemeName.netcoreapp.cs @@ -3,8 +3,16 @@ using System.Threading.Tasks; namespace Ufangx.Xss { + /// + /// + /// public interface IXssSchemeName { + /// + /// + /// + /// + /// Task GetSchemeName(HttpContext httpContext); } } \ No newline at end of file diff --git a/AntiXssUF/JsonFilterPolicy.cs b/AntiXssUF/JsonFilterPolicy.cs index 7f7499c..4d0257f 100644 --- a/AntiXssUF/JsonFilterPolicy.cs +++ b/AntiXssUF/JsonFilterPolicy.cs @@ -1,5 +1,4 @@ -using Microsoft.Extensions.Configuration; -using System; +using System; using System.Linq; using System.Collections.Generic; using System.IO; @@ -7,7 +6,10 @@ using System.Text; namespace Ufangx.Xss { - public class JsonFilterPolicy : IFilterPolicy + /// + /// json格式过滤策略配置 + /// + public partial class JsonFilterPolicy : IFilterPolicy { Dictionary commonRegularExpressions, directives; Dictionary commonAttributes, globalAttributes; @@ -15,62 +17,41 @@ namespace Ufangx.Xss Dictionary cssRules; private string name; private bool initialized; - + /// + /// 策略名称 + /// public string Name => name; - + /// + /// 是否已经初始化 + /// public bool Initialized => initialized; - + /// + /// 公用正则表达式 + /// public Dictionary CommonRegularExpressions => commonRegularExpressions; - + /// + /// 控制设置 + /// public Dictionary Directives => directives; - + /// + /// 公用属性 + /// public Dictionary CommonAttributes => commonAttributes; - + /// + /// 全局属性白名单 + /// public Dictionary GlobalAttributes => globalAttributes; - + /// + /// html标签白名单 + /// public Dictionary TagRules => tagRules; - + /// + /// 样式表规则白名单 + /// public Dictionary CssRules => cssRules; - Dictionary GetPolicyHtmlAttributes(IEnumerable sections) - => sections.Select(e => new PolicyHtmlAttribute(e.GetValue("Name")) - { - AllowedRegExp = e.GetSection("AllowedRegExp").Get(), - AllowedValues = e.GetSection("AllowedValues").Get(), - Description = e.GetValue("Description"), - OnInvalid = e.GetValue("OnInvalid") - }).ToDictionary(e => e.Name, e => e, StringComparer.OrdinalIgnoreCase); - public void Init(IConfigurationRoot configuration, string name) { - if (Initialized) return; - if (configuration is null) - { - throw new ArgumentNullException(nameof(configuration)); - } - initialized = true; - this.name = name; - commonRegularExpressions = new Dictionary(configuration.GetSection("CommonRegularExpressions").Get>(),StringComparer.OrdinalIgnoreCase); - directives =new Dictionary(configuration.GetSection("Directives").Get< Dictionary>(), StringComparer.OrdinalIgnoreCase); - commonAttributes = GetPolicyHtmlAttributes(configuration.GetSection("CommonAttributes").GetChildren()); - globalAttributes = GetPolicyHtmlAttributes(configuration.GetSection("GlobalAttributes").GetChildren()); - cssRules = configuration.GetSection("CssRules").GetChildren().Select(e => - new PolicyCssProperty(e.GetValue("Name")) - { - AllowedRegExp = e.GetSection("AllowedRegExp").Get(), - AllowedValues = e.GetSection("AllowedValues").Get(), - Description = e.GetValue("Description"), - Shorthands = e.GetSection("Shorthands").Get() - }).ToDictionary(e => e.Name, e => e, StringComparer.OrdinalIgnoreCase); - tagRules = configuration.GetSection("TagRules").GetChildren().Select(e => - new PolicyHtmlTag(GetPolicyHtmlAttributes(e.GetSection("AllowedAttributes").GetChildren())) - { - Name = e.GetValue("Name"), - Action = e.GetValue("Action") - } - ).ToDictionary(e => e.Name, e => e, StringComparer.OrdinalIgnoreCase); - } - public void Init(string config, string name) - => Init(Initialized?null:new MemoryStream(Encoding.UTF8.GetBytes(config), false), name); - public void Init(Stream config, string name) - => Init(Initialized ? null : new ConfigurationBuilder().AddJsonStream(config ?? throw new ArgumentNullException(nameof(config))).Build(), null); + + + diff --git a/AntiXssUF/JsonFilterPolicy.net461.cs b/AntiXssUF/JsonFilterPolicy.net461.cs new file mode 100644 index 0000000..0680223 --- /dev/null +++ b/AntiXssUF/JsonFilterPolicy.net461.cs @@ -0,0 +1,81 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Linq; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace Ufangx.Xss +{ + /// + /// json格式过滤策略配置 + /// + public partial class JsonFilterPolicy : IFilterPolicy + { + Dictionary GetPolicyHtmlAttributes(IEnumerable sections) + => sections?.Select(e => new PolicyHtmlAttribute(e.Value("Name")) + { + AllowedRegExp = e.SelectToken("AllowedRegExp")?.ToObject(), + AllowedValues = e.SelectToken("AllowedValues")?.ToObject(), + Description = e.Value("Description"), + OnInvalid = GetValue(e.SelectToken("OnInvalid")) + }).ToDictionary(e => e.Name, e => e, StringComparer.OrdinalIgnoreCase); + + TEnum GetValue(JToken token,TEnum @default=default(TEnum)) where TEnum : struct + => token is JValue jValue && Enum.TryParse(jValue.ToString(), true, out TEnum value) ? value : @default; + /// + /// 初始化策略 + /// + /// 配置文档 + /// 策略名称 + public void Init(JToken configuration, string name) { + + if (Initialized) return; + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + commonRegularExpressions = new Dictionary(configuration.SelectToken("CommonRegularExpressions").ToObject>(),StringComparer.OrdinalIgnoreCase); + directives =new Dictionary(configuration.SelectToken("Directives").ToObject>(), StringComparer.OrdinalIgnoreCase); + commonAttributes = GetPolicyHtmlAttributes(configuration.SelectToken("CommonAttributes").Children()); + globalAttributes = GetPolicyHtmlAttributes(configuration.SelectToken("GlobalAttributes").Children()); + cssRules = configuration.SelectToken("CssRules").Children().Select(e => + new PolicyCssProperty(e.Value("Name")) + { + AllowedRegExp = e.SelectToken("AllowedRegExp")?.ToObject(), + AllowedValues = e.SelectToken("AllowedValues")?.ToObject(), + Description = e.Value("Description"), + Shorthands = e.SelectToken("Shorthands")?.ToObject() + }).ToDictionary(e => e.Name, e => e, StringComparer.OrdinalIgnoreCase); + tagRules = configuration.SelectToken("TagRules").Children().Select(e => + new PolicyHtmlTag(GetPolicyHtmlAttributes(e.SelectToken("AllowedAttributes")?.Children()??Enumerable.Empty())) + { + Name = e.Value("Name"), + Action =GetValue(e.SelectToken("Action")) + } + ).ToDictionary(e => e.Name, e => e, StringComparer.OrdinalIgnoreCase); + initialized = true; + this.name = name; + } + + /// + /// 初始化策略 + /// + /// json配置文档 + /// 策略名称 + public void Init(string config, string name) + => Init(Initialized ? null : JsonConvert.DeserializeObject(config) as JToken, name); + /// + /// 初始化策略 + /// + /// json配置文档 + /// 策略名称 + public void Init(Stream config, string name) + => Init(Initialized ? null : JsonConvert.DeserializeObject(new StreamReader(config).ReadToEnd()) as JToken, null); + + + + + } +} diff --git a/AntiXssUF/JsonFilterPolicy.netstandard.cs b/AntiXssUF/JsonFilterPolicy.netstandard.cs new file mode 100644 index 0000000..4e5fa15 --- /dev/null +++ b/AntiXssUF/JsonFilterPolicy.netstandard.cs @@ -0,0 +1,78 @@ +using Microsoft.Extensions.Configuration; +using System; +using System.Linq; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace Ufangx.Xss +{ + /// + /// json格式过滤策略配置 + /// + public partial class JsonFilterPolicy : IFilterPolicy + { + Dictionary GetPolicyHtmlAttributes(IEnumerable sections) + => sections.Select(e => new PolicyHtmlAttribute(e.GetValue("Name")) + { + AllowedRegExp = e.GetSection("AllowedRegExp").Get(), + AllowedValues = e.GetSection("AllowedValues").Get(), + Description = e.GetValue("Description"), + OnInvalid = e.GetValue("OnInvalid") + }).ToDictionary(e => e.Name, e => e, StringComparer.OrdinalIgnoreCase); + + /// + /// 初始化策略 + /// + /// 配置文档 + /// 策略名称 + public void Init(IConfigurationRoot configuration, string name) { + if (Initialized) return; + if (configuration is null) + { + throw new ArgumentNullException(nameof(configuration)); + } + commonRegularExpressions = new Dictionary(configuration.GetSection("CommonRegularExpressions").Get>(),StringComparer.OrdinalIgnoreCase); + directives =new Dictionary(configuration.GetSection("Directives").Get< Dictionary>(), StringComparer.OrdinalIgnoreCase); + commonAttributes = GetPolicyHtmlAttributes(configuration.GetSection("CommonAttributes").GetChildren()); + globalAttributes = GetPolicyHtmlAttributes(configuration.GetSection("GlobalAttributes").GetChildren()); + cssRules = configuration.GetSection("CssRules").GetChildren().Select(e => + new PolicyCssProperty(e.GetValue("Name")) + { + AllowedRegExp = e.GetSection("AllowedRegExp").Get(), + AllowedValues = e.GetSection("AllowedValues").Get(), + Description = e.GetValue("Description"), + Shorthands = e.GetSection("Shorthands").Get() + }).ToDictionary(e => e.Name, e => e, StringComparer.OrdinalIgnoreCase); + tagRules = configuration.GetSection("TagRules").GetChildren().Select(e => + new PolicyHtmlTag(GetPolicyHtmlAttributes(e.GetSection("AllowedAttributes").GetChildren())) + { + Name = e.GetValue("Name"), + Action = e.GetValue("Action") + } + ).ToDictionary(e => e.Name, e => e, StringComparer.OrdinalIgnoreCase); + + initialized = true; + this.name = name; + } + + /// + /// 初始化策略 + /// + /// json配置文档 + /// 策略名称 + public void Init(string config, string name) + => Init(Initialized?null:new MemoryStream(Encoding.UTF8.GetBytes(config), false), name); + /// + /// + /// + /// json配置文档 + /// 策略名称 + public void Init(Stream config, string name) + => Init(Initialized ? null : new ConfigurationBuilder().AddJsonStream(config ?? throw new ArgumentNullException(nameof(config))).Build(), null); + + + + + } +} diff --git a/AntiXssUF/PolicyAttribute.cs b/AntiXssUF/PolicyAttribute.cs index 621a5c7..9bd1067 100644 --- a/AntiXssUF/PolicyAttribute.cs +++ b/AntiXssUF/PolicyAttribute.cs @@ -6,29 +6,47 @@ using System.Threading.Tasks; namespace Ufangx.Xss { + /// + /// 属性过滤策略 + /// [Serializable] public class PolicyAttribute { + /// + /// 创建属性过滤策略 + /// + /// public PolicyAttribute(string name) { Name = name; } - + /// + /// 正则表达式白名单 + /// public FilterRegExp[] AllowedRegExp { get; set; } + /// + /// 属性值白名单 + /// public string[] AllowedValues { get; set; } + /// + /// 属性名称 + /// public string Name { get; protected set; } + /// + /// 策略描述 + /// public string Description { get; diff --git a/AntiXssUF/PolicyCssProperty.cs b/AntiXssUF/PolicyCssProperty.cs index 63fd7e2..6c8856c 100644 --- a/AntiXssUF/PolicyCssProperty.cs +++ b/AntiXssUF/PolicyCssProperty.cs @@ -6,10 +6,20 @@ using System.Threading.Tasks; namespace Ufangx.Xss { + /// + /// 样式属性过滤策略 + /// [Serializable] public class PolicyCssProperty : PolicyAttribute { + /// + /// 创建样式属性过滤策略 + /// + /// public PolicyCssProperty(string name) : base(name) { } + /// + /// 样式简短名称列表 + /// public string[] Shorthands { get; set; } } } diff --git a/AntiXssUF/PolicyHtmlAttribute.cs b/AntiXssUF/PolicyHtmlAttribute.cs index 34e2192..48aef52 100644 --- a/AntiXssUF/PolicyHtmlAttribute.cs +++ b/AntiXssUF/PolicyHtmlAttribute.cs @@ -6,14 +6,24 @@ using System.Threading.Tasks; namespace Ufangx.Xss { + /// + /// html标签属性过滤策略 + /// [Serializable] public class PolicyHtmlAttribute : PolicyAttribute { + /// + /// 创建html标签属性过滤策略 + /// + /// public PolicyHtmlAttribute(string name) : base(name) { } + /// + /// 属性值被验证失败后的处理方式,如果当前属性值是无效的,那么是移除属性,还是移除整个标签,或者过滤标签保留内容 + /// public PolicyHtmlAttributeOnInvalid OnInvalid { get; diff --git a/AntiXssUF/PolicyHtmlTag.cs b/AntiXssUF/PolicyHtmlTag.cs index d0c64bd..a7c06f6 100644 --- a/AntiXssUF/PolicyHtmlTag.cs +++ b/AntiXssUF/PolicyHtmlTag.cs @@ -6,11 +6,17 @@ using System.Threading.Tasks; namespace Ufangx.Xss { + /// + ///html标签策略 + /// [Serializable] public class PolicyHtmlTag { private readonly Dictionary allowedAttributes; - + /// + /// 创建html标签策略 + /// + /// public PolicyHtmlTag(Dictionary attributes) { if (attributes != null) @@ -18,12 +24,21 @@ namespace Ufangx.Xss allowedAttributes = attributes; } } + /// + /// 标签白名单 + /// public Dictionary AllowedAttributes => allowedAttributes; + /// + /// 标签的过滤动作 + /// public PolicyHtmlTagAction Action { get; set; } + /// + /// 标签名称 + /// public string Name { get; diff --git a/AntiXssUF/PolicyHtmlTagAction.cs b/AntiXssUF/PolicyHtmlTagAction.cs index ecdd364..b03a05b 100644 --- a/AntiXssUF/PolicyHtmlTagAction.cs +++ b/AntiXssUF/PolicyHtmlTagAction.cs @@ -6,6 +6,9 @@ using System.Threading.Tasks; namespace Ufangx.Xss { + /// + /// 过滤标签的动作 + /// public enum PolicyHtmlTagAction { /// diff --git a/AntiXssUF/RichText.cs b/AntiXssUF/RichText.cs index f0fa414..d2f9629 100644 --- a/AntiXssUF/RichText.cs +++ b/AntiXssUF/RichText.cs @@ -2,20 +2,24 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Web; using Microsoft.Extensions.DependencyInjection; namespace Ufangx.Xss { - public class RichText + /// + /// 富文本 + /// + public partial class RichText { #region 构造 /// /// 实例化一个富文本对象 /// - /// 未被过滤的源文本 - /// 过滤的安全策略,如果不提供将启用默认的安全策略 + /// 未被过滤的源文本 + /// html过滤器 public RichText(string source, IHtmlFilter htmlFilter) { this.source = source; @@ -27,9 +31,14 @@ namespace Ufangx.Xss private readonly IHtmlFilter htmlFilter; string html; - + /// + /// html源码 + /// public string Source => source; - + /// + /// 输出干净的html + /// + /// public override string ToString() { if (html == null) @@ -38,7 +47,23 @@ namespace Ufangx.Xss } return html; } + static IFilterPolicy presupposedPolicy; + /// + /// 内置的过滤策略 + /// + /// + public static IFilterPolicy GetPresupposedPolicy() + { + if (presupposedPolicy == null) + { + var policy = new JsonFilterPolicy(); + policy.Init(Assembly.GetExecutingAssembly().GetManifestResourceStream("Ufangx.Xss.resources.DefaultPolicy.json"), "Presupposed"); + presupposedPolicy = policy; + } + return presupposedPolicy; + + } #region 重载操作符 /// /// 字符串隐式转换为富文本对象 @@ -48,7 +73,7 @@ namespace Ufangx.Xss public static implicit operator RichText(string text) { var factory = XssFilterBuilder.Builder?.ServiceProvider?.GetService(); - return new RichText(text, factory == null ? new HtmlFilter(XssFilterBuilder.GetPresupposedPolicy()) : factory.CreateHtmlFilter().Result); + return new RichText(text, factory == null ? new HtmlFilter(GetPresupposedPolicy()) : factory.CreateHtmlFilter().Result); } /// /// 富文本对象隐式转换为字符串 @@ -102,7 +127,7 @@ namespace Ufangx.Xss } return new RichText(string.Concat(a.source, b.source), a.htmlFilter); } - ///这个是强制转换操作符的重载,在这里不需要了,因为有隐式转换了 + //这个是强制转换操作符的重载,在这里不需要了,因为有隐式转换了 //public static explicit operator string(RichText text) //{ // return text == null ? null : text.ToString(); diff --git a/AntiXssUF/RichTextBinder.net461.cs b/AntiXssUF/RichTextBinder.net461.cs new file mode 100644 index 0000000..443c7c5 --- /dev/null +++ b/AntiXssUF/RichTextBinder.net461.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using Ufangx.Xss; + +namespace Ufangx.Xss +{ + /// + /// 模型绑定器 + /// + public class RichTextBinder : IModelBinder + { + /// + /// + /// + /// + /// + /// + + public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) + { + var modelName = bindingContext.ModelName; + IUnvalidatedValueProvider valueProvider = bindingContext.ValueProvider as IUnvalidatedValueProvider; + var valueProviderResult = valueProvider == null ? bindingContext.ValueProvider.GetValue(modelName) : valueProvider.GetValue(modelName,true); + if (valueProviderResult == null) + { + return null; + } + + bindingContext.ModelState.SetModelValue(modelName, valueProviderResult); + string value = valueProviderResult.AttemptedValue; + if (string.IsNullOrEmpty(value)) + { + return null; + } + IXssSchemeName scheme = bindingContext.ModelMetadata?.ContainerType?.GetProperty(bindingContext.ModelMetadata.PropertyName).GetCustomAttributes(true)?.Cast()?.FirstOrDefault() ?? null; + + if (scheme == null) { + return (RichText)value; + } + + RichText richText = new RichText(value, DependencyResolver.Current.GetService().CreateHtmlFilter(scheme.GetSchemeName(controllerContext.HttpContext).Result).Result); + return richText; + } + } + +} \ No newline at end of file diff --git a/AntiXssUF.Mvc/RichTextBinder.cs b/AntiXssUF/RichTextBinder.netcoreapp.cs similarity index 90% rename from AntiXssUF.Mvc/RichTextBinder.cs rename to AntiXssUF/RichTextBinder.netcoreapp.cs index 0da185b..e2f3780 100644 --- a/AntiXssUF.Mvc/RichTextBinder.cs +++ b/AntiXssUF/RichTextBinder.netcoreapp.cs @@ -9,10 +9,17 @@ using Microsoft.Extensions.DependencyInjection; namespace Ufangx.Xss { + /// + /// + /// public class RichTextBinder : IModelBinder { - + /// + /// + /// + /// + /// public async Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) diff --git a/AntiXssUF.Mvc/RichTextBinderProvider.cs b/AntiXssUF/RichTextBinderProvider.netcoreapp.cs similarity index 78% rename from AntiXssUF.Mvc/RichTextBinderProvider.cs rename to AntiXssUF/RichTextBinderProvider.netcoreapp.cs index 34ecf62..4907da8 100644 --- a/AntiXssUF.Mvc/RichTextBinderProvider.cs +++ b/AntiXssUF/RichTextBinderProvider.netcoreapp.cs @@ -5,8 +5,16 @@ using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; namespace Ufangx.Xss { + /// + /// + /// public class RichTextBinderProvider : IModelBinderProvider { + /// + /// + /// + /// + /// public IModelBinder GetBinder(ModelBinderProviderContext context) { if (context == null) diff --git a/AntiXssUF/XssFilterBuilder.cs b/AntiXssUF/XssFilterBuilder.cs index a38edcf..a6f41be 100644 --- a/AntiXssUF/XssFilterBuilder.cs +++ b/AntiXssUF/XssFilterBuilder.cs @@ -5,32 +5,40 @@ using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Options; namespace Ufangx.Xss { - public class XssFilterBuilder + /// + /// Xss过滤器生成者 + /// + public partial class XssFilterBuilder { internal static XssFilterBuilder Builder { get; private set; } - + + private readonly Configures configures; + internal XssFilterBuilder(IServiceCollection services) { Services = services; Builder = this; + configures = new Configures(services); } + /// + /// 服务注册集合 + /// public virtual IServiceCollection Services { get; } IServiceProvider _serviceProvider; - internal virtual IServiceProvider ServiceProvider => _serviceProvider ??= Services.BuildServiceProvider(); + internal virtual IServiceProvider ServiceProvider => _serviceProvider ?? (_serviceProvider = Services.BuildServiceProvider()); + //partial void configureFilterPolicyOptions(string name, Type PolicyType, Func> configure); private XssFilterBuilder AddSchemeHelper(string name, Func> configure) where TPolicy : class, IFilterPolicy { - Services.Configure(o => - o.AddScheme(name, scheme => { - scheme.PolicyType = typeof(TPolicy); - scheme.GetConfig = configure; - }) - ); + configures.Options(o => o.AddScheme(name, scheme => + { + scheme.PolicyType = typeof(TPolicy); + scheme.GetConfig = configure; + })); Services.AddSingleton(); return this; } @@ -40,37 +48,59 @@ namespace Ufangx.Xss { if (configureOptions != null) { - Services.Configure(name, configureOptions); + configures.Options(configureOptions, name); } return AddSchemeHelper(name, configure); } + /// + /// 添加过滤策略方案 + /// + /// + /// + /// + /// + /// + /// public XssFilterBuilder AddScheme(string name, Func> configure, Action configureOptions) where TOptions : class, new() where TPolicy : class, IFilterPolicy => AddSchemeHelper(name, configure, configureOptions); + /// + /// 添加过滤策略方案 + /// + /// + /// + /// + /// + /// + /// public XssFilterBuilder AddScheme(string name, string configure, Action configureOptions) where TOptions : class, new() where TPolicy : class, IFilterPolicy => AddSchemeHelper(name, () => Task.FromResult(configure), configureOptions); + /// + /// 添加过滤策略方案 + /// + /// + /// + /// + /// public XssFilterBuilder AddScheme(string name, Func> configure) where TPolicy : class, IFilterPolicy => AddSchemeHelper(name, configure); + /// + /// 添加过滤策略方案 + /// + /// + /// + /// + /// public XssFilterBuilder AddScheme(string name, string configure) where TPolicy : class, IFilterPolicy => AddSchemeHelper(name, () => Task.FromResult(configure)); - static IFilterPolicy presupposedPolicy; - public static IFilterPolicy GetPresupposedPolicy() { - if (presupposedPolicy == null) - { - var policy = new JsonFilterPolicy(); - policy.Init(Assembly.GetExecutingAssembly().GetManifestResourceStream("Ufangx.Xss.resources.DefaultPolicy.json"), "Presupposed"); - presupposedPolicy = policy; - } - - return presupposedPolicy; - } + } } diff --git a/AntiXssUF/XssSchemeNameAttribute.net461.cs b/AntiXssUF/XssSchemeNameAttribute.net461.cs new file mode 100644 index 0000000..c16d299 --- /dev/null +++ b/AntiXssUF/XssSchemeNameAttribute.net461.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Web; + +namespace Ufangx.Xss +{ + /// + /// + /// + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] + public class XssSchemeNameAttribute : Attribute, IXssSchemeName + { + private readonly string scheme; + /// + /// + /// + /// + public XssSchemeNameAttribute(string scheme) + { + this.scheme = scheme; + } + /// + /// + /// + /// + /// + public Task GetSchemeName(HttpContextBase httpContext) + => Task.FromResult(scheme); + } + + +} \ No newline at end of file diff --git a/AntiXssUF.Mvc/XssShemeNameAttribute.cs b/AntiXssUF/XssShemeNameAttribute.netcoreapp.cs similarity index 68% rename from AntiXssUF.Mvc/XssShemeNameAttribute.cs rename to AntiXssUF/XssShemeNameAttribute.netcoreapp.cs index b80389a..fc13748 100644 --- a/AntiXssUF.Mvc/XssShemeNameAttribute.cs +++ b/AntiXssUF/XssShemeNameAttribute.netcoreapp.cs @@ -6,17 +6,26 @@ using System.Threading.Tasks; namespace Ufangx.Xss { - + /// + /// + /// [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] public class XssSchemeNameAttribute : Attribute, IXssSchemeName { private readonly string scheme; - + /// + /// + /// + /// public XssSchemeNameAttribute(string scheme) { this.scheme = scheme; } - + /// + /// + /// + /// + /// public Task GetSchemeName(HttpContext httpContext) => Task.FromResult(scheme); } diff --git a/AntiXssUF/resources/DefaultPolicy.json b/AntiXssUF/resources/DefaultPolicy.json index 77bc06c..634a06e 100644 --- a/AntiXssUF/resources/DefaultPolicy.json +++ b/AntiXssUF/resources/DefaultPolicy.json @@ -36,951 +36,809 @@ "frequency": "([0-9]+(.[0-9]+)?)(hz|khz)", "length": "((-|\\+)?0|(-|\\+)?([0-9]+(.[0-9]+)?)(em|ex|px|in|cm|mm|pt|pc))", "percentage": "(-|\\+)?([0-9]+(.[0-9]+)?)%", - "csscolor": "(aqua|black|blue|fuchsia|gray|grey|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)|(^#[0-9a-fA-F]{3,3}$)|(^#[0-9a-fA-F]{6,6}$)|rgba?\\(\\s*([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\\s*,\\s*([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\\s*,\\s*([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])(\\s*,\\s*[1])?\\s*\\)", + "csscolor": "(aqua|black|blue|fuchsia|gray|grey|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)|(^#[0-9a-fA-F]{3,3}$)|(^#[0-9a-fA-F]{6,6}$)|rgba?\\\\(\\\\s*([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\\\\s*,\\\\s*([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\\\\s*,\\\\s*([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])(\\\\s*,\\\\s*[1])?\\\\s*\\\\)", "absolute-size": "(xx-small|x-small|small|medium|large|x-large|xx-large)", "relative-size": "(larger|smaller)" }, "CommonAttributes": [ { - - "AllowedRegExp": [ { "Value": "[a-zA-Z0-9_\\-\\:]+" } ], "Name": "id", + "AllowedRegExp": [ { "Value": "[a-zA-Z0-9_\\-\\:]+" } ], "Description": "The 'id' of any HTML attribute should not contain anything besides letters and numbers" }, { - - "AllowedRegExp": [ { "Name": "htmlClass" } ], "Name": "class", + "AllowedRegExp": [ { "Name": "htmlClass" } ], "Description": "The 'class' of any HTML attribute is usually a single word, but it can also be a list of class names separated by spaces" }, { - - "AllowedRegExp": [ { "Value": "[a-zA-Z]{2,20}" } ], "Name": "lang", + "AllowedRegExp": [ { "Value": "[a-zA-Z]{2,20}" } ], "Description": "The 'lang' attribute tells the browser what language the element's attribute values and content are written in" }, { - - "AllowedRegExp": [ { "Name": "htmlTitle" } ], "Name": "title", + "AllowedRegExp": [ { "Name": "htmlTitle" } ], "Description": "The 'title' attribute provides text that shows up in a 'tooltip' when a user hovers their mouse over the element" }, { - - "AllowedRegExp": [ { "Name": "paragraph" } ], "Name": "alt", + "AllowedRegExp": [ { "Name": "paragraph" } ], "Description": "The 'alt' attribute provides alternative text to users when its visual representation is not available" }, { - "Name": "style", "Description": "The 'style' attribute provides the ability for users to change many attributes of the tag's contents using a strict syntax" }, { - - "AllowedValues": [ "screen", "tty", "tv", "projection", "handheld", "print", "braille", "aural", "all" ], - "Name": "media" + "Name": "media", + "AllowedValues": [ "screen", "tty", "tv", "projection", "handheld", "print", "braille", "aural", "all" ] }, { - + "Name": "href", "AllowedRegExp": [ { "Name": "onsiteURL" }, { "Name": "offsiteURL" } ], - "AllowedValues": [ "javascript:history.go(0)", "javascript:history.go(-1)", "javascript:void(0)", "javascript:location.reload()" ], - "Name": "href" + "AllowedValues": [ "javascript:history.go(0)", "javascript:history.go(-1)", "javascript:void(0)", "javascript:location.reload()" ] }, { - - "AllowedRegExp": [ { "Value": "[a-zA-Z0-9-_\\$]+" } ], - "Name": "name" + "Name": "name", + "AllowedRegExp": [ { "Value": "[a-zA-Z0-9-_\\$]+" } ] }, { - - "AllowedValues": [ "default", "rect", "circle", "poly" ], "Name": "shape", + "AllowedValues": [ "default", "rect", "circle", "poly" ], "Description": "The 'shape' attribute defines the shape of the selectable area" }, { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "border" + "Name": "border", + "AllowedRegExp": [ { "Name": "number" } ] }, { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "cellpadding" + "Name": "cellpadding", + "AllowedRegExp": [ { "Name": "number" } ] }, { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "cellspacing" + "Name": "cellspacing", + "AllowedRegExp": [ { "Name": "number" } ] }, { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "colspan" + "Name": "colspan", + "AllowedRegExp": [ { "Name": "number" } ] }, { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "rowspan" + "Name": "rowspan", + "AllowedRegExp": [ { "Name": "number" } ] }, { - - "AllowedRegExp": [ { "Name": "onsiteURL" } ], - "Name": "background" + "Name": "background", + "AllowedRegExp": [ { "Name": "onsiteURL" } ] }, { - - "AllowedRegExp": [ { "Name": "colorNameOrCode" } ], - "Name": "bgcolor" + "Name": "bgcolor", + "AllowedRegExp": [ { "Name": "colorNameOrCode" } ] }, { - - "AllowedRegExp": [ { "Name": "paragraph" } ], - "Name": "abbrev" + "Name": "abbrev", + "AllowedRegExp": [ { "Name": "paragraph" } ] }, { - - "AllowedRegExp": [ { "Value": "[a-zA-Z0-9\\s*]*" } ], "Name": "headers", + "AllowedRegExp": [ { "Value": "[a-zA-Z0-9\\s*]*" } ], "Description": "The 'headers' attribute is a space-separated list of cell IDs" }, { - - "AllowedRegExp": [ { "Value": "numberOrPercent" } ], - "Name": "charoff" + "Name": "charoff", + "AllowedRegExp": [ { "Value": "numberOrPercent" } ] }, { - - "AllowedRegExp": [ { "Value": ".*{0,1}" } ], - "Name": "char" + "Name": "char", + "AllowedRegExp": [ { "Value": ".*{0,1}" } ] }, { - - "AllowedRegExp": [ { "Value": "[a-zA-Z0-9\\s*,]*" } ], "Name": "axis", + "AllowedRegExp": [ { "Value": "[a-zA-Z0-9\\s*,]*" } ], "Description": "The 'headers' attribute is a comma-separated list of related header cells" }, { - - "AllowedRegExp": [ { "Name": "anything" } ], "Name": "nowrap", + "AllowedRegExp": [ { "Name": "anything" } ], "Description": "The 'nowrap' attribute tells the browser not to wrap text that goes over one line" }, { - - "AllowedRegExp": [ { "Name": "numberOrPercent" } ], - "Name": "width" + "Name": "width", + "AllowedRegExp": [ { "Name": "numberOrPercent" } ] }, { - - "AllowedRegExp": [ { "Name": "numberOrPercent" } ], - "Name": "height" + "Name": "height", + "AllowedRegExp": [ { "Name": "numberOrPercent" } ] }, { - - "AllowedValues": [ "center", "middle", "left", "right", "justify", "char" ], "Name": "align", + "AllowedValues": [ "center", "middle", "left", "right", "justify", "char" ], "Description": "The 'align' attribute of an HTML element is a direction word, like 'left', 'right' or 'center'" }, { - - "AllowedValues": [ "baseline", "bottom", "middle", "top" ], "Name": "valign", + "AllowedValues": [ "baseline", "bottom", "middle", "top" ], "Description": "The 'valign' attribute of an HTML attribute is a direction word, like 'baseline','bottom','middle' or 'top'" }, { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Name": "onFocus", + "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Description": "The 'onFocus' event is executed when the control associated with the tag gains focus" }, { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Name": "onBlur", + "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Description": "The 'onBlur' event is executed when the control associated with the tag loses focus" }, { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Name": "onClick", + "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Description": "The 'onClick' event is executed when the control associated with the tag is clicked" }, { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Name": "onDblClick", + "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Description": "The 'onDblClick' event is executed when the control associated with the tag is clicked twice immediately" }, { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Name": "onMouseDown", + "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Description": "The 'onMouseDown' event is executed when the control associated with the tag is clicked but not yet released" }, { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Name": "onMouseUp", + "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Description": "The 'onMouseUp' event is executed when the control associated with the tag is clicked after the button is released" }, { - - "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Name": "onMouseOver", + "AllowedValues": [ "javascript:void(0)", "javascript:history.go(-1)" ], "Description": "The 'onMouseOver' event is executed when the user's mouse hovers over the control associated with the tag" }, { - - "AllowedValues": [ "row", "col", "rowgroup", "colgroup" ], "Name": "scope", + "AllowedValues": [ "row", "col", "rowgroup", "colgroup" ], "Description": "The 'scope' attribute defines what's covered by the header cells" }, { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "disabled" + "Name": "disabled", + "AllowedRegExp": [ { "Name": "anything" } ] }, { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "readonly" + "Name": "readonly", + "AllowedRegExp": [ { "Name": "anything" } ] }, { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "accesskey" + "Name": "accesskey", + "AllowedRegExp": [ { "Name": "anything" } ] }, { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "size" + "Name": "size", + "AllowedRegExp": [ { "Name": "number" } ] }, { - - "AllowedValues": [ "on", "off" ], - "Name": "autocomplete" + "Name": "autocomplete", + "AllowedValues": [ "on", "off" ] }, { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "rows" + "Name": "rows", + "AllowedRegExp": [ { "Name": "number" } ] }, { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "cols" + "Name": "cols", + "AllowedRegExp": [ { "Name": "number" } ] } ], "CssRules": [ { + "Name": "azimuth", "AllowedRegExp": [ { "Name": "angle" } ], "AllowedValues": [ "left-side", "far-left", "left", "center-left", "center", "center-right", "right", "far-right", "right-side", "behind", "leftwards", "rightwards", "inherit" ], - "Name": "azimuth", "Description": "This property is most likely to be implemented by mixing the same signal into different channels at differing volumes." }, { + "Name": "background", "Shorthands": [ "background-color", "background-image", "background-repeat", "background-attachment", "background-position" ], "AllowedValues": [ "inherit" ], - "Name": "background", "Description": "The 'background' property is a shorthand property for setting the individual background properties (i.e., 'background-color', 'background-image', 'background-repeat', 'background-attachment' and 'background-position') at the same place in the style sheet." }, { - "AllowedValues": [ "scroll", "fixed", "inherit" ], "Name": "background-attachment", + "AllowedValues": [ "scroll", "fixed", "inherit" ], "Description": "If a background image is specified, this property specifies whether it is fixed with regard to the viewport ('fixed') or scrolls along with the document ('scroll')." }, { + "Name": "background-color", "AllowedRegExp": [ { "Name": "cssColor" } ], "AllowedValues": [ "transparent", "inherit" ], - "Name": "background-color", "Description": "This property sets the background color of an element, either a value or the keyword 'transparent', to make the underlying colors shine through." }, { + "Name": "background-image", "AllowedRegExp": [ { "Name": "cssOffsiteUri" }, { "Name": "cssOnsiteUri" } ], "AllowedValues": [ "none", "inherit" ], - "Name": "background-image", "Description": "This property sets the background image of an element." }, { + "Name": "background-position", "AllowedRegExp": [ { "Name": "percentage" }, { "Name": "length" } ], "AllowedValues": [ "top", "center", "bottom", "left", "center", "right", "inherit" ], - "Name": "background-position", "Description": "If a background image has been specified, this property specifies its initial position." }, { - "AllowedValues": [ "repeat", "repeat-x", "repeat-y", "no-repeat", "inherit" ], "Name": "background-repeat", + "AllowedValues": [ "repeat", "repeat-x", "repeat-y", "no-repeat", "inherit" ], "Description": "If a background image is specified, this property specifies whether the image is repeated (tiled), and how." }, { - "AllowedValues": [ "collapse", "separate", "inherit" ], "Name": "border-collapse", - "Description": "" + "AllowedValues": [ "collapse", "separate", "inherit" ] }, { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "transparent", "inherit" ], "Name": "border-color", - "Description": "" + "AllowedRegExp": [ { "Name": "cssColor" } ], + "AllowedValues": [ "transparent", "inherit" ] }, { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], "Name": "border-top-color", - "Description": "" + "AllowedRegExp": [ { "Name": "cssColor" } ], + "AllowedValues": [ "inherit" ] }, { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], "Name": "border-right-color", - "Description": "" + "AllowedRegExp": [ { "Name": "cssColor" } ], + "AllowedValues": [ "inherit" ] }, { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], "Name": "border-bottom-color", - "Description": "" - }, - { "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], - "Name": "border-left-color", - "Description": "" + "AllowedValues": [ "inherit" ] }, { + "Name": "border-left-color", + "AllowedRegExp": [ { "Name": "cssColor" } ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "bottom", "AllowedRegExp": [ { "Name": "length" }, { "Name": "percentage" } ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "bottom", - "Description": "" + "AllowedValues": [ "auto", "inherit" ] }, { - "AllowedValues": [ "top", "bottom", "left", "right", "inherit" ], "Name": "caption-side", - "Description": "" + "AllowedValues": [ "top", "bottom", "left", "right", "inherit" ] }, { - "AllowedValues": [ "none", "left", "right", "both", "inherit" ], "Name": "clear", - "Description": "" + "AllowedValues": [ "none", "left", "right", "both", "inherit" ] }, { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], "Name": "color", - "Description": "" + "AllowedRegExp": [ { "Name": "cssColor" } ], + "AllowedValues": [ "inherit" ] }, { - "AllowedRegExp": [ - { "Name": "cssOffsiteUri" }, - { "Name": "cssOnsiteUri" } - ], - "AllowedValues": [ "none", "inherit" ], "Name": "cue-after", - "Description": "" - }, - { "AllowedRegExp": [ { "Name": "cssOffsiteUri" }, { "Name": "cssOnsiteUri" } ], - "AllowedValues": [ "none", "inherit" ], + "AllowedValues": [ "none", "inherit" ] + }, + { "Name": "cue-before", - "Description": "" + "AllowedRegExp": [ + { "Name": "cssOffsiteUri" }, + { "Name": "cssOnsiteUri" } + ], + "AllowedValues": [ "none", "inherit" ] }, { - "AllowedValues": [ "ltr", "rtl", "inherit" ], "Name": "direction", - "Description": "" + "AllowedValues": [ "ltr", "rtl", "inherit" ] }, { - "AllowedValues": [ "inline", "block", "list-item", "run-in", "compact", "marker", "table", "inline-table", "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group", "table-column", "table-cell", "table-caption", "none", "inherit" ], "Name": "display", - "Description": "" + "AllowedValues": [ "inline", "block", "list-item", "run-in", "compact", "marker", "table", "inline-table", "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group", "table-column", "table-cell", "table-caption", "none", "inherit" ] }, { - "AllowedRegExp": [ { "Name": "angle" } ], - "AllowedValues": [ "below", "level", "above", "higher", "lower", "inherit" ], "Name": "elevation", - "Description": "" + "AllowedRegExp": [ { "Name": "angle" } ], + "AllowedValues": [ "below", "level", "above", "higher", "lower", "inherit" ] }, { - "AllowedValues": [ "show", "hide", "inherit" ], "Name": "empty-cells", - "Description": "" + "AllowedValues": [ "show", "hide", "inherit" ] }, { - "AllowedValues": [ "left", "right", "none", "inherit" ], "Name": "float", - "Description": "" + "AllowedValues": [ "left", "right", "none", "inherit" ] }, { + "Name": "font-size", "AllowedRegExp": [ { "Name": "absolute-size" }, { "Name": "relative-size" }, { "Name": "length" }, { "Name": "percentage" } ], - "AllowedValues": [ "inherit" ], - "Name": "font-size", - "Description": "" + "AllowedValues": [ "inherit" ] }, { - "AllowedRegExp": [ { "Name": "number" } ], - "AllowedValues": [ "none", "inherit" ], "Name": "font-size-adjust", - "Description": "" + "AllowedRegExp": [ { "Name": "number" } ], + "AllowedValues": [ "none", "inherit" ] }, { - "AllowedValues": [ "normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded", "inherit" ], "Name": "font-stretch", - "Description": "" + "AllowedValues": [ "normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded", "inherit" ] }, { - "AllowedValues": [ "normal", "italic", "oblique", "inherit" ], "Name": "font-style", - "Description": "" + "AllowedValues": [ "normal", "italic", "oblique", "inherit" ] }, { - "AllowedValues": [ "normal", "small-caps", "inherit" ], "Name": "font-variant", - "Description": "" + "AllowedValues": [ "normal", "small-caps", "inherit" ] }, { - "AllowedValues": [ "normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900", "inherit" ], "Name": "font-weight", - "Description": "" + "AllowedValues": [ "normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900", "inherit" ] }, { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "auto", "inherit" ], "Name": "height", - "Description": "" - }, - { "AllowedRegExp": [ { "Name": "length" }, { "Name": "percentage" } ], - "AllowedValues": [ "auto", "inherit" ], + "AllowedValues": [ "auto", "inherit" ] + }, + { "Name": "left", - "Description": "" + "AllowedRegExp": [ + { "Name": "length" }, + { "Name": "percentage" } + ], + "AllowedValues": [ "auto", "inherit" ] }, { - "AllowedRegExp": [ { "Name": "length" } ], - "AllowedValues": [ "normal", "inherit" ], "Name": "letter-spacing", - "Description": "" + "AllowedRegExp": [ { "Name": "length" } ], + "AllowedValues": [ "normal", "inherit" ] }, { + "Name": "line-height", "AllowedRegExp": [ { "Name": "number" }, { "Name": "length" }, { "Name": "percentage" } ], - "AllowedValues": [ "normal", "inherit" ], - "Name": "line-height", - "Description": "" + "AllowedValues": [ "normal", "inherit" ] }, { + "Name": "list-style-image", "AllowedRegExp": [ { "Name": "cssOffsiteUri" }, { "Name": "cssOnsiteUri" } ], - "AllowedValues": [ "none", "inherit" ], - "Name": "list-style-image", - "Description": "" + "AllowedValues": [ "none", "inherit" ] }, { - "AllowedValues": [ "inside", "outside", "inherit" ], "Name": "list-style-position", - "Description": "" + "AllowedValues": [ "inside", "outside", "inherit" ] }, { - "AllowedValues": [ "disc", "circle", "square", "decimal", "decimal-leading-zero", "lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "hebrew", "armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha", "katakana-iroha", "none", "inherit" ], "Name": "list-style-type", - "Description": "" + "AllowedValues": [ "disc", "circle", "square", "decimal", "decimal-leading-zero", "lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "hebrew", "armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha", "katakana-iroha", "none", "inherit" ] }, { - "AllowedRegExp": [ { "Name": "length" } ], - "AllowedValues": [ "auto", "inherit" ], "Name": "marker-offset", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "none", "inherit" ], - "Name": "max-height", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "none", "inherit" ], - "Name": "max-width", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], - "Name": "min-height", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], - "Name": "min-width", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "integer" } ], - "AllowedValues": [ "inherit" ], - "Name": "orphans", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "invert", "inherit" ], - "Name": "outline-color", - "Description": "" - }, - { - "AllowedValues": [ "visible", "hidden", "scroll", "auto", "inherit" ], - "Name": "overflow", - "Description": "" - }, - { - "AllowedValues": [ "auto", "always", "avoid", "left", "right", "inherit" ], - "Name": "page-break-after", - "Description": "" - }, - { - "AllowedValues": [ "auto", "always", "avoid", "left", "right", "inherit" ], - "Name": "page-break-before", - "Description": "" - }, - { - "AllowedValues": [ "avoid", "auto", "inherit" ], - "Name": "page-break-inside", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "time" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], - "Name": "pause-after", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "time" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], - "Name": "pause-before", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "frequency" } ], - "AllowedValues": [ "x-low", "low", "medium", "high", "x-high", "inherit" ], - "Name": "pitch", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "number" } ], - "AllowedValues": [ "inherit" ], - "Name": "pitch-range", - "Description": "" - }, - { - "AllowedValues": [ "static", "inherit" ], - "Name": "position", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "number" } ], - "AllowedValues": [ "inherit" ], - "Name": "richness", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "right", - "Description": "" - }, - { "AllowedRegExp": [ { "Name": "length" } ], - "AllowedValues": [ "auto", "portrait", "landscape", "inherit" ], + "AllowedValues": [ "auto", "inherit" ] + }, + { + "Name": "max-height", + "AllowedRegExp": [ + { "Name": "length" }, + { "Name": "percentage" } + ], + "AllowedValues": [ "none", "inherit" ] + }, + { + "Name": "max-width", + "AllowedRegExp": [ + { "Name": "length" }, + { "Name": "percentage" } + ], + "AllowedValues": [ "none", "inherit" ] + }, + { + "Name": "min-height", + "AllowedRegExp": [ + { "Name": "length" }, + { "Name": "percentage" } + ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "min-width", + "AllowedRegExp": [ + { "Name": "length" }, + { "Name": "percentage" } + ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "orphans", + "AllowedRegExp": [ { "Name": "integer" } ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "outline-color", + "AllowedRegExp": [ { "Name": "cssColor" } ], + "AllowedValues": [ "invert", "inherit" ] + }, + { + "Name": "overflow", + "AllowedValues": [ "visible", "hidden", "scroll", "auto", "inherit" ] + }, + { + "Name": "page-break-after", + "AllowedValues": [ "auto", "always", "avoid", "left", "right", "inherit" ] + }, + { + "Name": "page-break-before", + "AllowedValues": [ "auto", "always", "avoid", "left", "right", "inherit" ] + }, + { + "Name": "page-break-inside", + "AllowedValues": [ "avoid", "auto", "inherit" ] + }, + { + "Name": "pause-after", + "AllowedRegExp": [ + { "Name": "time" }, + { "Name": "percentage" } + ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "pause-before", + "AllowedRegExp": [ + { "Name": "time" }, + { "Name": "percentage" } + ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "pitch", + "AllowedRegExp": [ { "Name": "frequency" } ], + "AllowedValues": [ "x-low", "low", "medium", "high", "x-high", "inherit" ] + }, + { + "Name": "pitch-range", + "AllowedRegExp": [ { "Name": "number" } ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "position", + "AllowedValues": [ "static", "inherit" ] + }, + { + "Name": "richness", + "AllowedRegExp": [ { "Name": "number" } ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "right", + "AllowedRegExp": [ + { "Name": "length" }, + { "Name": "percentage" } + ], + "AllowedValues": [ "auto", "inherit" ] + }, + { "Name": "size", - "Description": "" + "AllowedRegExp": [ { "Name": "length" } ], + "AllowedValues": [ "auto", "portrait", "landscape", "inherit" ] }, { - "AllowedValues": [ "normal", "none", "spell-out", "inherit" ], "Name": "speak", - "Description": "" + "AllowedValues": [ "normal", "none", "spell-out", "inherit" ] }, { - "AllowedValues": [ "once", "always", "inherit" ], "Name": "speak-header", - "Description": "" + "AllowedValues": [ "once", "always", "inherit" ] }, { - "AllowedValues": [ "digits", "continuous", "inherit" ], "Name": "speak-numeral", - "Description": "" + "AllowedValues": [ "digits", "continuous", "inherit" ] }, { - "AllowedValues": [ "code", "none", "inherit" ], "Name": "speak-punctuation", - "Description": "" + "AllowedValues": [ "code", "none", "inherit" ] }, { - "AllowedRegExp": [ { "Name": "number" } ], - "AllowedValues": [ "x-slow", "slow", "medium", "fast", "x-fast", "faster", "slower", "inherit" ], "Name": "speech-rate", - "Description": "" - }, - { "AllowedRegExp": [ { "Name": "number" } ], - "AllowedValues": [ "inherit" ], + "AllowedValues": [ "x-slow", "slow", "medium", "fast", "x-fast", "faster", "slower", "inherit" ] + }, + { "Name": "stress", - "Description": "" + "AllowedRegExp": [ { "Name": "number" } ], + "AllowedValues": [ "inherit" ] }, { - "AllowedValues": [ "auto", "fixed", "inherit" ], "Name": "table-layout", - "Description": "" + "AllowedValues": [ "auto", "fixed", "inherit" ] }, { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit" ], "Name": "text-indent", - "Description": "" - }, - { - "AllowedValues": [ "capitalize", "uppercase", "lowercase", "none", "inherit" ], - "Name": "text-transform", - "Description": "" - }, - { "AllowedRegExp": [ { "Name": "length" }, { "Name": "percentage" } ], - "AllowedValues": [ "auto", "inherit" ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "text-transform", + "AllowedValues": [ "capitalize", "uppercase", "lowercase", "none", "inherit" ] + }, + { "Name": "top", - "Description": "" + "AllowedRegExp": [ + { "Name": "length" }, + { "Name": "percentage" } + ], + "AllowedValues": [ "auto", "inherit" ] }, { - "AllowedValues": [ "normal", "embed", "bidi-override", "inherit" ], "Name": "unicode-bidi", - "Description": "" + "AllowedValues": [ "normal", "embed", "bidi-override", "inherit" ] }, { + "Name": "vertical-align", "AllowedRegExp": [ { "Name": "percentage" }, { "Name": "length" } ], - "AllowedValues": [ "baseline", "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom", "inherit" ], - "Name": "vertical-align", - "Description": "" + "AllowedValues": [ "baseline", "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom", "inherit" ] }, { - "AllowedValues": [ "visible", "hidden", "collapse", "inherit" ], "Name": "visibility", - "Description": "" + "AllowedValues": [ "visible", "hidden", "collapse", "inherit" ] }, { + "Name": "volume", "AllowedRegExp": [ { "Name": "number" }, { "Name": "percentage" } ], - "AllowedValues": [ "silent", "x-soft", "soft", "medium", "loud", "x-loud", "inherit" ], - "Name": "volume", - "Description": "" + "AllowedValues": [ "silent", "x-soft", "soft", "medium", "loud", "x-loud", "inherit" ] }, { - "AllowedValues": [ "normal", "pre", "nowrap", "inherit" ], "Name": "white-space", - "Description": "" + "AllowedValues": [ "normal", "pre", "nowrap", "inherit" ] }, { - "AllowedRegExp": [ { "Name": "integer" } ], - "AllowedValues": [ "inherit" ], "Name": "widows", - "Description": "" - }, - { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "width", - "Description": "" - }, - { - "AllowedRegExp": [ { "Name": "length" } ], - "AllowedValues": [ "normal", "inherit" ], - "Name": "word-spacing", - "Description": "" - }, - { "AllowedRegExp": [ { "Name": "integer" } ], - "AllowedValues": [ "auto", "inherit" ], - "Name": "z-index", - "Description": "" + "AllowedValues": [ "inherit" ] }, { - "AllowedValues": [ "inherit", "none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset" ], - "Name": "border-style", - "Description": "" - }, - { - "AllowedValues": [ "inherit" ], - "Name": "border-top-style", - "Description": "" - }, - { - "Shorthands": [ "border-style" ], - "AllowedValues": [ "inherit" ], - "Name": "border-right-style", - "Description": "" - }, - { - "Shorthands": [ "border-style" ], - "AllowedValues": [ "inherit" ], - "Name": "border-bottom-style", - "Description": "" - }, - { - "Shorthands": [ "border-style" ], - "AllowedValues": [ "inherit" ], - "Name": "border-left-style", - "Description": "" - }, - { - "Shorthands": [ "border-width" ], - "AllowedValues": [ "inherit" ], - "Name": "border-top-width", - "Description": "" - }, - { - "Shorthands": [ "border-width" ], - "AllowedValues": [ "inherit" ], - "Name": "border-right-width", - "Description": "" - }, - { - "Shorthands": [ "border-width" ], - "AllowedValues": [ "inherit" ], - "Name": "border-bottom-width", - "Description": "" - }, - { - "Shorthands": [ "border-width" ], - "AllowedValues": [ "inherit" ], - "Name": "border-left-width", - "Description": "" + "Name": "width", + "AllowedRegExp": [ + { "Name": "length" }, + { "Name": "percentage" } + ], + "AllowedValues": [ "auto", "inherit" ] }, { + "Name": "word-spacing", "AllowedRegExp": [ { "Name": "length" } ], - "AllowedValues": [ "inherit", "thin", "medium", "thick" ], - "Name": "border-width", - "Description": "" + "AllowedValues": [ "normal", "inherit" ] }, { - "AllowedRegExp": [ - { "Name": "length" }, - { "Name": "percentage" } - ], - "AllowedValues": [ "inherit", "auto" ], - "Name": "margin", - "Description": "" + "Name": "z-index", + "AllowedRegExp": [ { "Name": "integer" } ], + "AllowedValues": [ "auto", "inherit" ] }, { - "Shorthands": [ "margin" ], - "AllowedValues": [ "inherit" ], - "Name": "margin-top", - "Description": "" + "Name": "border-style", + "AllowedValues": [ "inherit", "none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset" ] }, { - "Shorthands": [ "margin" ], - "AllowedValues": [ "inherit" ], - "Name": "margin-right", - "Description": "" - }, - { - "Shorthands": [ "margin" ], - "AllowedValues": [ "inherit" ], - "Name": "margin-bottom", - "Description": "" - }, - { - "Shorthands": [ "margin" ], - "AllowedValues": [ "inherit" ], - "Name": "margin-left", - "Description": "" + "Name": "border-top-style", + "AllowedValues": [ "inherit" ] }, { + "Name": "border-right-style", "Shorthands": [ "border-style" ], - "AllowedValues": [ "inherit" ], - "Name": "outline-style", - "Description": "" + "AllowedValues": [ "inherit" ] }, { + "Name": "border-bottom-style", + "Shorthands": [ "border-style" ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "border-left-style", + "Shorthands": [ "border-style" ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "border-top-width", "Shorthands": [ "border-width" ], - "AllowedValues": [ "inherit" ], - "Name": "outline-width", - "Description": "" + "AllowedValues": [ "inherit" ] }, { + "Name": "border-right-width", + "Shorthands": [ "border-width" ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "border-bottom-width", + "Shorthands": [ "border-width" ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "border-left-width", + "Shorthands": [ "border-width" ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "border-width", + "AllowedRegExp": [ { "Name": "length" } ], + "AllowedValues": [ "inherit", "thin", "medium", "thick" ] + }, + { + "Name": "margin", "AllowedRegExp": [ { "Name": "length" }, { "Name": "percentage" } ], - "AllowedValues": [ "inherit" ], + "AllowedValues": [ "inherit", "auto" ] + }, + { + "Name": "margin-top", + "Shorthands": [ "margin" ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "margin-right", + "Shorthands": [ "margin" ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "margin-bottom", + "Shorthands": [ "margin" ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "margin-left", + "Shorthands": [ "margin" ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "outline-style", + "Shorthands": [ "border-style" ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "outline-width", + "Shorthands": [ "border-width" ], + "AllowedValues": [ "inherit" ] + }, + { "Name": "padding", - "Description": "" + "AllowedRegExp": [ + { "Name": "length" }, + { "Name": "percentage" } + ], + "AllowedValues": [ "inherit" ] }, { - "Shorthands": [ "padding" ], - "AllowedValues": [ "inherit" ], "Name": "padding-top", - "Description": "" + "Shorthands": [ "padding" ], + "AllowedValues": [ "inherit" ] }, { - "Shorthands": [ "padding" ], - "AllowedValues": [ "inherit" ], "Name": "padding-right", - "Description": "" + "Shorthands": [ "padding" ], + "AllowedValues": [ "inherit" ] }, { - "Shorthands": [ "padding" ], - "AllowedValues": [ "inherit" ], "Name": "padding-bottom", - "Description": "" - }, - { "Shorthands": [ "padding" ], - "AllowedValues": [ "inherit" ], - "Name": "padding-left", - "Description": "" + "AllowedValues": [ "inherit" ] }, { + "Name": "padding-left", + "Shorthands": [ "padding" ], + "AllowedValues": [ "inherit" ] + }, + { + "Name": "border", "Shorthands": [ "border-width", "border-style" ], "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], - "Name": "border", - "Description": "" + "AllowedValues": [ "inherit" ] }, { - "Shorthands": [ "border-top-width", "border-style" ], - "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], "Name": "border-top", - "Description": "" - }, - { "Shorthands": [ "border-top-width", "border-style" ], "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], + "AllowedValues": [ "inherit" ] + }, + { "Name": "border-right", - "Description": "" - }, - { "Shorthands": [ "border-top-width", "border-style" ], "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], + "AllowedValues": [ "inherit" ] + }, + { "Name": "border-bottom", - "Description": "" - }, - { "Shorthands": [ "border-top-width", "border-style" ], "AllowedRegExp": [ { "Name": "cssColor" } ], - "AllowedValues": [ "inherit" ], + "AllowedValues": [ "inherit" ] + }, + { "Name": "border-left", - "Description": "" + "Shorthands": [ "border-top-width", "border-style" ], + "AllowedRegExp": [ { "Name": "cssColor" } ], + "AllowedValues": [ "inherit" ] }, { - "Shorthands": [ "cue-before", "cue-after" ], - "AllowedValues": [ "inherit" ], "Name": "cue", - "Description": "" + "Shorthands": [ "cue-before", "cue-after" ], + "AllowedValues": [ "inherit" ] }, { - "Shorthands": [ "list-style-type", "list-style-position", "list-style-image" ], - "AllowedValues": [ "inherit" ], "Name": "list-style", - "Description": "" + "Shorthands": [ "list-style-type", "list-style-position", "list-style-image" ], + "AllowedValues": [ "inherit" ] }, { - "AllowedValues": [ "crop", "cross", "none", "inherit" ], "Name": "marks", - "Description": "" + "AllowedValues": [ "crop", "cross", "none", "inherit" ] }, { - "Shorthands": [ "outline-color", "outline-style", "outline-width" ], - "AllowedValues": [ "inherit" ], "Name": "outline", - "Description": "" + "Shorthands": [ "outline-color", "outline-style", "outline-width" ], + "AllowedValues": [ "inherit" ] }, { + "Name": "pause", "AllowedRegExp": [ { "Name": "time" }, { "Name": "percentage" } ], - "AllowedValues": [ "inherit" ], - "Name": "pause", - "Description": "" + "AllowedValues": [ "inherit" ] }, { - "AllowedValues": [ "none", "underline", "overline", "line-through", "blink", "inherit" ], "Name": "text-decoration", - "Description": "" + "AllowedValues": [ "none", "underline", "overline", "line-through", "blink", "inherit" ] }, { + "Name": "border-spacing", "AllowedRegExp": [ { "Name": "length" } ], "AllowedValues": [ "inherit" ], - "Name": "border-spacing", "Description": "The lengths specify the distance that separates adjacent cell borders. If one length is specified, it gives both the horizontal and vertical spacing. If two are specified, the first gives the horizontal spacing and the second the vertical spacing. Lengths may not be negative." }, { + "Name": "counter-increment", "AllowedRegExp": [ { "Name": "cssElementSelector" }, { "Name": "cssClassSelector" }, @@ -989,46 +847,46 @@ { "Name": "integer" } ], "AllowedValues": [ "none", "inherit" ], - "Name": "counter-increment", "Description": "The 'counter-increment' property accepts one or more names of counters (identifiers), each one optionally followed by an integer." }, { + "Name": "clip", "AllowedRegExp": [ { "Name": "length" } ], "AllowedValues": [ "auto", "inherit" ], - "Name": "clip", "Description": "The 'clip' property applies to elements that have a 'overflow' property with a value other than 'visible'." }, { + "Name": "cursor", "AllowedRegExp": [ { "Name": "cssOffsiteUri" }, { "Name": "cssOnsiteUri" } ], "AllowedValues": [ "auto", "inherit", "crosshair", "default", "pointer", "move", "e-resize", "ne-resize", "nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize| text", "wait", "help" ], - "Name": "cursor", "Description": "This property specifies the type of cursor to be displayed for the pointing device." }, { + "Name": "text-shadow", "AllowedRegExp": [ { "Name": "cssColor" }, { "Name": "length" } ], "AllowedValues": [ "none", "inherit" ], - "Name": "text-shadow", "Description": "This property accepts a comma-separated list of shadow effects to be applied to the text of the element." }, { + "Name": "font", "Shorthands": [ "font-style", "font-variant", "font-weight", "font-size", "line-height", "font-family" ], "AllowedValues": [ "/", "caption", "icon", "menu", "message-box", "small-caption", "status-bar", "inherit" ], - "Name": "font", "Description": "The 'font' property is, except as described below, a shorthand property for setting 'font-style', 'font-variant', 'font-weight', 'font-size', 'line-height', and 'font-family', at the same place in the style sheet." }, { + "Name": "font-family", "AllowedRegExp": [ { "Value": "[\\w,\\-'\" ]+" } ], "AllowedValues": [ "serif", "arial", "lucida console", "sans-serif", "cursive", "verdana", "fantasy", "monospace" ], - "Name": "font-family", "Description": "This property specifies a prioritized list of font family names and/or generic family names." }, { + "Name": "page", "AllowedRegExp": [ { "Name": "cssElementSelector" }, { "Name": "cssClassSelector" }, @@ -1036,979 +894,563 @@ { "Name": "cssAttributeSelector" } ], "AllowedValues": [ "auto" ], - "Name": "page", "Description": "The 'page' property can be used to specify a particular type of page where an element should be displayed." }, { + "Name": "play-during", "AllowedRegExp": [ { "Name": "cssOffsiteUri" }, { "Name": "cssOnsiteUri" } ], "AllowedValues": [ "mix", "repeat", "none", "auto", "inherit" ], - "Name": "play-during", "Description": "Similar to the 'cue-before' and 'cue-after' properties, this property specifies a sound to be played as a background while an element's content is spoken." }, { - "AllowedValues": [ "left", "right", "center", "justify", "inherit" ], "Name": "text-align", + "AllowedValues": [ "left", "right", "center", "justify", "inherit" ], "Description": "This property describes how inline content of a block is aligned." }, { - "AllowedValues": [ "male", "female", "child", "inherit" ], "Name": "voice-family", + "AllowedValues": [ "male", "female", "child", "inherit" ], "Description": "The value is a comma-separated, prioritized list of voice family names (compare with 'font-family')." } ], "GlobalAttributes": [ - { - - "Name": "id" - }, - { - - "Name": "style" - }, - { - - "Name": "title" - }, - { - - "Name": "class" - }, - { - - "Name": "lang" - } + { "Name": "id" }, + { "Name": "style" }, + { "Name": "title" }, + { "Name": "class" }, + { "Name": "lang" } ], "TagRules": [ { - - "Action": 2, + "Action": "Validate", "Name": "html" }, { - "AllowedAttributes": { - "bgcolor": { - - "Name": "bgcolor" - } - }, - "Action": 2, - "Name": "body" + "Action": "Validate", + "Name": "body", + "AllowedAttributes": [ { "Name": "bgcolor" } ] }, { - - "Action": 3, + "Action": "Filter", "Name": "meta" }, { - - "Action": 2, + "Action": "Validate", "Name": "head" }, { - - "Action": 1, + "Action": "Truncate", "Name": "title" }, + { "Name": "script" }, { - - "Action": 0, - "Name": "script" - }, - { - - "Action": 2, + "Action": "Validate", "Name": "noscript" }, + { "Name": "iframe" }, + { "Name": "frameset" }, + { "Name": "frame" }, { - - "Action": 0, - "Name": "iframe" - }, - { - - "Action": 0, - "Name": "frameset" - }, - { - - "Action": 0, - "Name": "frame" - }, - { - "AllowedAttributes": { - "for": { - - "AllowedRegExp": [ { "Name": "htmlId" } ], - "Name": "for" + "Action": "Validate", + "Name": "label", + "AllowedAttributes": [ + { + "Name": "for", + "AllowedRegExp": [ { "Name": "htmlId" } ] } - }, - "Action": 0, - "Name": "label" + ] }, { - "AllowedAttributes": { - "action": { - + "Action": "Validate", + "Name": "form", + "AllowedAttributes": [ + { + "Name": "action", "AllowedRegExp": [ { "Name": "onsiteURL" }, { "Name": "offsiteURL" } - ], - "Name": "action" + ] }, - "name": { - - "Name": "name" - }, - "autocomplete": { - - "Name": "autocomplete" - }, - "method": { - - "AllowedValues": [ "post", "get" ], - "Name": "method" + { "Name": "name" }, + { "Name": "autocomplete" }, + { + "Name": "method", + "AllowedValues": [ "post", "get" ] } - }, - "Action": 2, - "Name": "form" + ] }, { - "AllowedAttributes": { - "name": { - - "Name": "name" + "Action": "Validate", + "Name": "button", + "AllowedAttributes": [ + { "Name": "name" }, + { + "Name": "value", + "AllowedRegExp": [ { "Name": "anything" } ] }, - "value": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "value" - }, - "disabled": { - - "Name": "disabled" - }, - "accesskey": { - - "Name": "accesskey" - }, - "type": { - - "AllowedValues": [ "submit", "reset", "button" ], - "Name": "type" + { "Name": "disabled" }, + { "Name": "accesskey" }, + { + "Name": "type", + "AllowedValues": [ "submit", "reset", "button" ] } - }, - "Action": 2, - "Name": "button" + ] }, { - "AllowedAttributes": { - "name": { - - "Name": "name" + "Action": "Validate", + "Name": "input", + "AllowedAttributes": [ + { "Name": "name" }, + { "Name": "size" }, + { + "Name": "maxlength", + "AllowedRegExp": [ { "Name": "number" } ] }, - "size": { - - "Name": "size" + { "Name": "autocomplete" }, + { + "Name": "checked", + "AllowedRegExp": [ { "Name": "anything" } ] }, - "maxlength": { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "maxlength" - }, - "autocomplete": { - - "Name": "autocomplete" - }, - "checked": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "checked" - }, - "alt": { - - "Name": "alt" - }, - "src": { - + { "Name": "alt" }, + { + "Name": "src", "AllowedRegExp": [ { "Name": "onsiteURL" }, { "Name": "offsiteURL" } - ], - "Name": "src" + ] }, - "usemap": { - - "AllowedRegExp": [ { "Name": "onsiteURL" } ], - "Name": "usemap" + { + "Name": "usemap", + "AllowedRegExp": [ { "Name": "onsiteURL" } ] }, - "type": { - - "AllowedValues": [ "hidden", "text", "password", "radio", "checkbox", "submit", "button", "image", "file", "reset" ], - "Name": "type" + { + "Name": "type", + "AllowedValues": [ "hidden", "text", "password", "radio", "checkbox", "submit", "button", "image", "file", "reset" ] }, - "value": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "value" + { + "Name": "value", + "AllowedRegExp": [ { "Name": "anything" } ] }, - "disabled": { - - "Name": "disabled" - }, - "readonly": { - - "Name": "readonly" - }, - "accesskey": { - - "Name": "accesskey" - }, - "border": { - - "Name": "border" - } - }, - "Action": 2, - "Name": "input" + { "Name": "disabled" }, + { "Name": "readonly" }, + { "Name": "accesskey" }, + { "Name": "border" } + ] }, { - "AllowedAttributes": { - "name": { - - "Name": "name" + "Action": "Validate", + "Name": "select", + "AllowedAttributes": [ + { "Name": "name" }, + { "Name": "disabled" }, + { + "Name": "multiple", + "AllowedRegExp": [ { "Name": "anything" } ] }, - "disabled": { - - "Name": "disabled" - }, - "multiple": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "multiple" - }, - "size": { - - "Name": "size" - } - }, - "Action": 2, - "Name": "select" + { "Name": "size" } + ] }, { - "AllowedAttributes": { - "disabled": { - - "Name": "disabled" + "Action": "Validate", + "Name": "option", + "AllowedAttributes": [ + { "Name": "disabled" }, + { + "Name": "value", + "AllowedRegExp": [ { "Name": "anything" } ] }, - "value": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "value" + { + "Name": "label", + "AllowedRegExp": [ { "Name": "anything" } ] }, - "label": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "label" - }, - "selected": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "selected" + { + "Name": "selected", + "AllowedRegExp": [ { "Name": "anything" } ] } - }, - "Action": 2, - "Name": "option" + ] }, { - "AllowedAttributes": { - "rows": { - - "Name": "rows" - }, - "cols": { - - "Name": "cols" - }, - "name": { - - "Name": "name" - }, - "disabled": { - - "Name": "disabled" - }, - "readonly": { - - "Name": "readonly" - }, - "accesskey": { - - "Name": "accesskey" - } - }, - "Action": 2, - "Name": "textarea" + "Action": "Validate", + "Name": "textarea", + "AllowedAttributes": [ + { "Name": "rows" }, + { "Name": "cols" }, + { "Name": "name" }, + { "Name": "disabled" }, + { "Name": "readonly" }, + { "Name": "accesskey" } + ] }, { - - "Action": 2, + "Action": "Validate", "Name": "h1" }, { - - "Action": 2, + "Action": "Validate", "Name": "h2" }, { - - "Action": 2, + "Action": "Validate", "Name": "h3" }, { - - "Action": 2, + "Action": "Validate", "Name": "h4" }, { - - "Action": 2, + "Action": "Validate", "Name": "h5" }, { - - "Action": 2, + "Action": "Validate", "Name": "h6" }, { - "AllowedAttributes": { - "align": { - - "Name": "align" - } - }, - "Action": 2, - "Name": "p" + "Action": "Validate", + "Name": "p", + "AllowedAttributes": [ { "Name": "align" } ] }, { - - "Action": 2, + "Action": "Validate", "Name": "i" }, { - - "Action": 2, + "Action": "Validate", "Name": "b" }, { - - "Action": 2, + "Action": "Validate", "Name": "u" }, { - - "Action": 2, + "Action": "Validate", "Name": "strong" }, { - - "Action": 2, + "Action": "Validate", "Name": "em" }, { - - "Action": 2, + "Action": "Validate", "Name": "small" }, { - - "Action": 2, + "Action": "Validate", "Name": "big" }, { - - "Action": 2, + "Action": "Validate", "Name": "pre" }, { - - "Action": 2, + "Action": "Validate", "Name": "code" }, { - - "Action": 2, + "Action": "Validate", "Name": "cite" }, { - - "Action": 2, + "Action": "Validate", "Name": "samp" }, { - - "Action": 2, + "Action": "Validate", "Name": "sub" }, { - - "Action": 2, + "Action": "Validate", "Name": "sup" }, { - - "Action": 2, + "Action": "Validate", "Name": "strike" }, { - - "Action": 2, + "Action": "Validate", "Name": "center" }, { - - "Action": 2, + "Action": "Validate", "Name": "blockquote" }, { - - "Action": 2, + "Action": "Validate", "Name": "hr" }, { - - "Action": 2, + "Action": "Validate", "Name": "br" }, { - "AllowedAttributes": { - "color": { - - "AllowedRegExp": [ { "Name": "colorNameOrCode" } ], - "Name": "color" + "Action": "Validate", + "Name": "font", + "AllowedAttributes": [ + { + "Name": "color", + "AllowedRegExp": [ { "Name": "colorNameOrCode" } ] }, - "face": { - - "AllowedRegExp": [ { "Value": "[\\w;, ]+" } ], - "Name": "face" + { + "Name": "face", + "AllowedRegExp": [ { "Value": "[\\w;, ]+" } ] }, - "size": { - - "AllowedRegExp": [ { "Value": "(\\+|-){0,1}(\\d)+" } ], - "Name": "size" + { + "Name": "size", + "AllowedRegExp": [ { "Value": "(\\+|-){0,1}(\\d)+" } ] } - }, - "Action": 2, - "Name": "font" + ] }, { - "AllowedAttributes": { - "href": { - - "Name": "href" + "Action": "Validate", + "Name": "a", + "AllowedAttributes": [ + { "Name": "href" }, + { "Name": "onFocus" }, + { "Name": "onBlur" }, + { + "Name": "nohref", + "AllowedRegExp": [ { "Name": "anything" } ] }, - "onfocus": { - - "Name": "onFocus" + { + "Name": "rel", + "AllowedValues": [ "nofollow" ] }, - "onblur": { - - "Name": "onBlur" - }, - "nohref": { - - "AllowedRegExp": [ { "Name": "anything" } ], - "Name": "nohref" - }, - "rel": { - - "AllowedValues": [ "nofollow" ], - "Name": "rel" - }, - "name": { - - "Name": "name" - } - }, - "Action": 2, - "Name": "a" + { "Name": "name" } + ] }, { - - "Action": 2, + "Action": "Validate", "Name": "map" }, { - "AllowedAttributes": { - "type": { - - "AllowedValues": [ "text/css" ], - "Name": "type" + "Action": "Validate", + "Name": "style", + "AllowedAttributes": [ + { + "Name": "type", + "AllowedValues": [ "text/css" ] }, - "media": { - - "Name": "media" - } - }, - "Action": 2, - "Name": "style" + { "Name": "media" } + ] }, { - - "Action": 2, + "Action": "Validate", "Name": "span" }, { - "AllowedAttributes": { - "align": { - - "Name": "align" - } - }, - "Action": 2, - "Name": "div" + "Action": "Validate", + "Name": "div", + "AllowedAttributes": [ { "Name": "align" } ] }, { - "AllowedAttributes": { - "src": { - "OnInvalid": 2, + "Action": "Validate", + "Name": "img", + "AllowedAttributes": [ + { + "Name": "src", + "OnInvalid": "RemoveTag", "AllowedRegExp": [ { "Name": "onsiteURL" }, { "Name": "offsiteURL" } - ], - "Name": "src" + ] }, - "name": { - - "Name": "name" + { "Name": "name" }, + { "Name": "alt" }, + { "Name": "height" }, + { "Name": "width" }, + { "Name": "border" }, + { "Name": "align" }, + { + "Name": "hspace", + "AllowedRegExp": [ { "Name": "number" } ] }, - "alt": { - - "Name": "alt" - }, - "height": { - - "Name": "height" - }, - "width": { - - "Name": "width" - }, - "border": { - - "Name": "border" - }, - "align": { - - "Name": "align" - }, - "hspace": { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "hspace" - }, - "vspace": { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "vspace" + { + "Name": "vspace", + "AllowedRegExp": [ { "Name": "number" } ] } - }, - "Action": 2, - "Name": "img" + ] }, { - "AllowedAttributes": { - "media": { - - "Name": "media" + "Action": "Validate", + "Name": "link", + "AllowedAttributes": [ + { "Name": "media" }, + { + "Name": "type", + "OnInvalid": "RemoveTag", + "AllowedValues": [ "text/css", "application/rss+xml", "image/x-icon" ] }, - "type": { - "OnInvalid": 2, - "AllowedValues": [ "text/css", "application/rss+xml", "image/x-icon" ], - "Name": "type" - }, - "rel": { - - "AllowedValues": [ "stylesheet", "shortcut icon", "search", "copyright", "top", "alternate" ], - "Name": "rel" + { + "Name": "rel", + "AllowedValues": [ "stylesheet", "shortcut icon", "search", "copyright", "top", "alternate" ] } - }, - "Action": 2, - "Name": "link" + ] }, { - - "Action": 2, + "Action": "Validate", "Name": "ul" }, { - - "Action": 2, + "Action": "Validate", "Name": "ol" }, { - - "Action": 2, + "Action": "Validate", "Name": "li" }, { - - "Action": 1, + "Action": "Truncate", "Name": "dd" }, { - - "Action": 1, + "Action": "Truncate", "Name": "dl" }, { - - "Action": 1, + "Action": "Truncate", "Name": "dt" }, { - "AllowedAttributes": { - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - } - }, - "Action": 2, - "Name": "thead" + "Action": "Validate", + "Name": "thead", + "AllowedAttributes": [ + { "Name": "align" }, + { "Name": "char" }, + { "Name": "charoff" }, + { "Name": "valign" } + ] }, { - "AllowedAttributes": { - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - } - }, - "Action": 2, - "Name": "tbody" + "Action": "Validate", + "Name": "tbody", + "AllowedAttributes": [ + { "Name": "align" }, + { "Name": "char" }, + { "Name": "charoff" }, + { "Name": "valign" } + ] }, { - "AllowedAttributes": { - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - } - }, - "Action": 2, - "Name": "tfoot" + "Action": "Validate", + "Name": "tfoot", + "AllowedAttributes": [ + { "Name": "align" }, + { "Name": "char" }, + { "Name": "charoff" }, + { "Name": "valign" } + ] }, { - "AllowedAttributes": { - "height": { - - "Name": "height" - }, - "width": { - - "Name": "width" - }, - "border": { - - "Name": "border" - }, - "bgcolor": { - - "Name": "bgcolor" - }, - "cellpadding": { - - "Name": "cellpadding" - }, - "cellspacing": { - - "Name": "cellspacing" - }, - "background": { - - "Name": "background" - }, - "align": { - - "Name": "align" - }, - "noresize": { - - "AllowedValues": [ "noresize" ], - "Name": "noresize" + "Action": "Validate", + "Name": "table", + "AllowedAttributes": [ + { "Name": "height" }, + { "Name": "width" }, + { "Name": "border" }, + { "Name": "bgcolor" }, + { "Name": "cellpadding" }, + { "Name": "cellspacing" }, + { "Name": "background" }, + { "Name": "align" }, + { + "Name": "noresize", + "AllowedValues": [ "noresize" ] } - }, - "Action": 2, - "Name": "table" + ] }, { - "AllowedAttributes": { - "background": { - - "Name": "background" - }, - "bgcolor": { - - "Name": "bgcolor" - }, - "abbrev": { - - "Name": "abbrev" - }, - "axis": { - - "Name": "axis" - }, - "headers": { - - "Name": "headers" - }, - "scope": { - - "Name": "scope" - }, - "nowrap": { - - "Name": "nowrap" - }, - "height": { - - "Name": "height" - }, - "width": { - - "Name": "width" - }, - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - }, - "colspan": { - - "Name": "colspan" - }, - "rowspan": { - - "Name": "rowspan" - } - }, - "Action": 2, - "Name": "td" + "Action": "Validate", + "Name": "td", + "AllowedAttributes": [ + { "Name": "background" }, + { "Name": "bgcolor" }, + { "Name": "abbrev" }, + { "Name": "axis" }, + { "Name": "headers" }, + { "Name": "scope" }, + { "Name": "nowrap" }, + { "Name": "height" }, + { "Name": "width" }, + { "Name": "align" }, + { "Name": "char" }, + { "Name": "charoff" }, + { "Name": "valign" }, + { "Name": "colspan" }, + { "Name": "rowspan" } + ] }, { - "AllowedAttributes": { - "abbrev": { - - "Name": "abbrev" - }, - "axis": { - - "Name": "axis" - }, - "headers": { - - "Name": "headers" - }, - "scope": { - - "Name": "scope" - }, - "nowrap": { - - "Name": "nowrap" - }, - "bgcolor": { - - "Name": "bgcolor" - }, - "height": { - - "Name": "height" - }, - "width": { - - "Name": "width" - }, - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - }, - "colspan": { - - "Name": "colspan" - }, - "rowspan": { - - "Name": "rowspan" - } - }, - "Action": 2, - "Name": "th" + "Action": "Validate", + "Name": "th", + "AllowedAttributes": [ + { "Name": "abbrev" }, + { "Name": "axis" }, + { "Name": "headers" }, + { "Name": "scope" }, + { "Name": "nowrap" }, + { "Name": "bgcolor" }, + { "Name": "height" }, + { "Name": "width" }, + { "Name": "align" }, + { "Name": "char" }, + { "Name": "charoff" }, + { "Name": "valign" }, + { "Name": "colspan" }, + { "Name": "rowspan" } + ] }, { - "AllowedAttributes": { - "height": { - - "Name": "height" - }, - "width": { - - "Name": "width" - }, - "align": { - - "Name": "align" - }, - "valign": { - - "Name": "valign" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "background": { - - "Name": "background" - } - }, - "Action": 2, - "Name": "tr" + "Action": "Validate", + "Name": "tr", + "AllowedAttributes": [ + { "Name": "height" }, + { "Name": "width" }, + { "Name": "align" }, + { "Name": "valign" }, + { "Name": "char" }, + { "Name": "charoff" }, + { "Name": "background" } + ] }, { - "AllowedAttributes": { - "span": { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "span" + "Action": "Validate", + "Name": "colgroup", + "AllowedAttributes": [ + { + "Name": "span", + "AllowedRegExp": [ { "Name": "number" } ] }, - "width": { - - "Name": "width" - }, - "align": { - - "Name": "align" - }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - } - }, - "Action": 2, - "Name": "colgroup" + { "Name": "width" }, + { "Name": "align" }, + { "Name": "char" }, + { "Name": "charoff" }, + { "Name": "valign" } + ] }, { - "AllowedAttributes": { - "align": { - - "Name": "align" + "Action": "Validate", + "Name": "col", + "AllowedAttributes": [ + { "Name": "align" }, + { "Name": "char" }, + { "Name": "charoff" }, + { "Name": "valign" }, + { + "Name": "span", + "AllowedRegExp": [ { "Name": "number" } ] }, - "char": { - - "Name": "char" - }, - "charoff": { - - "Name": "charoff" - }, - "valign": { - - "Name": "valign" - }, - "span": { - - "AllowedRegExp": [ { "Name": "number" } ], - "Name": "span" - }, - "width": { - - "Name": "width" - } - }, - "Action": 2, - "Name": "col" + { "Name": "width" } + ] }, { - - "Action": 2, + "Action": "Validate", "Name": "fieldset" }, { - - "Action": 2, + "Action": "Validate", "Name": "legend" } ] diff --git a/Framework461Test/Framework461Test.csproj b/Framework461Test/Framework461Test.csproj new file mode 100644 index 0000000..fa93161 --- /dev/null +++ b/Framework461Test/Framework461Test.csproj @@ -0,0 +1,84 @@ + + + + + + Debug + AnyCPU + {AFDE17BE-9067-44B7-9AED-8184ABB57E5C} + Library + Properties + Framework461Test + Framework461Test + v4.6.1 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\AngleSharp.0.13.0\lib\net46\AngleSharp.dll + + + ..\packages\MSTest.TestFramework.2.1.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.2.1.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Text.Encoding.CodePages.4.5.0\lib\net461\System.Text.Encoding.CodePages.dll + + + + + + + + + + + + + {313ae160-70b2-4a7c-9e1a-f00353c0a75a} + AntiXssUF + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + + \ No newline at end of file diff --git a/Framework461Test/Properties/AssemblyInfo.cs b/Framework461Test/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8c8f5ac --- /dev/null +++ b/Framework461Test/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Framework461Test")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Framework461Test")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("afde17be-9067-44b7-9aed-8184abb57e5c")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Framework461Test/UnitTest1.cs b/Framework461Test/UnitTest1.cs new file mode 100644 index 0000000..5944654 --- /dev/null +++ b/Framework461Test/UnitTest1.cs @@ -0,0 +1,203 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Ufangx.Xss; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; +using System.Diagnostics; + +namespace Framework461Test +{ + + [TestClass] + public class UnitTest1 + { + void FilterAttacks(RichText richText, Func fn, [CallerMemberName] string propertyName = null) + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.Append($"\n==== in {propertyName} ==================================================\n原文:\n{richText.Source}\n"); + + stringBuilder.Append("过滤\n"); + string clean = richText.ToString(); + stringBuilder.Append(clean); + var isTrue = fn(clean); + + stringBuilder.Append($"\n状态:{isTrue}"); + Console.WriteLine(stringBuilder.ToString()); + Assert.IsTrue(isTrue); + } + + [TestMethod] + public void testScriptAttacks() + { + FilterAttacks("", str => str.IndexOf("script", StringComparison.OrdinalIgnoreCase) == -1); + FilterAttacks("test", str => str.IndexOf("script", StringComparison.OrdinalIgnoreCase) == -1); + FilterAttacks("<<<><", str => str.IndexOf("", str => str.IndexOf("onload", StringComparison.OrdinalIgnoreCase) == -1); + FilterAttacks("", str => str.IndexOf("alert") == -1); + FilterAttacks("", str => str.IndexOf("iframe") == -1); + FilterAttacks("", str => str.IndexOf("javascript") == -1); + FilterAttacks("", str => str.IndexOf("background") == -1); + FilterAttacks("
", str => str.IndexOf("background") == -1); + FilterAttacks("
", str => str.IndexOf("javascript") == -1); + FilterAttacks("
", str => str.IndexOf("alert") == -1); + FilterAttacks("", str => str.IndexOf("alert") == -1); + + FilterAttacks("", str => str.IndexOf("ript:alert") == -1); + + FilterAttacks("", str => str.IndexOf("javascript") == -1); + FilterAttacks("", str => str.IndexOf("", str => str.IndexOf("", str => str.IndexOf("", str => str.IndexOf("", str => str.IndexOf("\" SRC=\"http://ha.ckers.org/xss.js\">", str => str.IndexOf("\" '' SRC=\"http://ha.ckers.org/xss.js\">", str => str.IndexOf("` SRC=\"http://ha.ckers.org/xss.js\">", str => str.IndexOf("'>\" SRC=\"http://ha.ckers.org/xss.js\">", str => str.IndexOf("document.write(\"PT SRC=\"http://ha.ckers.org/xss.js\">", str => str.IndexOf("script") == -1); + FilterAttacks("