[Pkg-javascript-commits] [dompurify.js] 01/03: Imported Upstream version 0.7.4~dfsg1
Alexandre Viau
aviau at moszumanska.debian.org
Wed May 18 16:14:21 UTC 2016
This is an automated email from the git hooks/post-receive script.
aviau pushed a commit to branch master
in repository dompurify.js.
commit a2d553699f408201092004c587f559854aa591fd
Author: aviau <alexandre at alexandreviau.net>
Date: Wed May 18 12:08:53 2016 -0400
Imported Upstream version 0.7.4~dfsg1
---
README.md | 4 +-
bower.json | 2 +-
package.json | 2 +-
src/purify.js | 106 +++++++++++++++++++++++----------------
test/fixtures/expect.js | 131 ++++++++++++++++++++++++++----------------------
test/test-suite.js | 1 +
website/index.html | 4 +-
7 files changed, 141 insertions(+), 109 deletions(-)
diff --git a/README.md b/README.md
index 1f96897..0e21e5c 100644
--- a/README.md
+++ b/README.md
@@ -183,8 +183,8 @@ We recently implemented a Hook-API allowing developers to create their own DOMPu
## Who contributed?
-Several people need to be listed here! [@garethheyes](https://twitter.com/garethheyes) for invaluable help, [@shafigullin](https://twitter.com/shafigullin) for breaking the library multiple times and thereby strengthening it, [@mmrupp](https://twitter.com/mmrupp) and [@irsdl](https://twitter.com/irsdl) for doing the same.
+Several people need to be listed here! [@garethheyes](https://twitter.com/garethheyes) and [@filedescriptor](https://twitter.com/filedescriptor) for invaluable help, [@shafigullin](https://twitter.com/shafigullin) for breaking the library multiple times and thereby strengthening it, [@mmrupp](https://twitter.com/mmrupp) and [@irsdl](https://twitter.com/irsdl) for doing the same.
-Big thanks also go to [@asutherland](https://twitter.com/asutherland), [@mathias](https://twitter.com/mathias), [@cgvwzq](https://twitter.com/cgvwzq), [@robbertatwork](https://twitter.com/robbertatwork), [@giutro](https://twitter.com/giutro) and [@fhemberger](https://twitter.com/fhemberger)! Further, thanks [@neilj](https://twitter.com/neilj) for his code review and countless small optimizations, fixes and beautifications. Big thanks also go to [@tdeekens](https://twitter.com/tdeekens) f [...]
+Big thanks also go to [@asutherland](https://twitter.com/asutherland), [@mathias](https://twitter.com/mathias), [@cgvwzq](https://twitter.com/cgvwzq), [@robbertatwork](https://twitter.com/robbertatwork), [@giutro](https://twitter.com/giutro) and [@fhemberger](https://twitter.com/fhemberger)! Further, thanks [@neilj](https://twitter.com/neilj) and [@0xsobky](https://twitter.com/0xsobky) for their code reviews and countless small optimizations, fixes and beautifications. Big thanks also go [...]
And last but not least, thanks to [BrowserStack](https://browserstack.com) for supporting this project with their services for free and delivering excellent, dedicated and very professional support on top of that.
diff --git a/bower.json b/bower.json
index ef68422..a08c55a 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
{
"name": "DOMPurify",
- "version": "0.7.3",
+ "version": "0.7.4",
"homepage": "https://github.com/cure53/DOMPurify",
"author": "Cure53 <info at cure53.de>",
"description": "A DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG",
diff --git a/package.json b/package.json
index 61bb57e..2af2207 100644
--- a/package.json
+++ b/package.json
@@ -35,7 +35,7 @@
},
"name": "dompurify",
"description": "DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. It's written in JavaScript and works in all modern browsers (Safari, Opera (15+), Internet Explorer (10+), Firefox and Chrome - as well as almost anything else using Blink or WebKit). DOMPurify is written by security people who have vast background in web attacks and XSS. Fear not.",
- "version": "0.7.3",
+ "version": "0.7.4",
"main": "src/purify.js",
"directories": {
"test": "test"
diff --git a/src/purify.js b/src/purify.js
index e705be8..71f62b7 100644
--- a/src/purify.js
+++ b/src/purify.js
@@ -21,7 +21,7 @@
* Version label, exposed for easier checks
* if DOMPurify is up to date or not
*/
- DOMPurify.version = '0.7.3';
+ DOMPurify.version = '0.7.4';
if (!window || !window.document || window.document.nodeType !== 9) {
// not running in a browser, provide a factory function
@@ -211,6 +211,10 @@
*/
var SAFE_FOR_TEMPLATES = false;
+ /* Specify template detection regex for SAFE_FOR_TEMPLATES mode */
+ var MUSTACHE_EXPR = /\{\{[\s\S]*|[\s\S]*\}\}/gm;
+ var ERB_EXPR = /<%[\s\S]*|[\s\S]*%>/gm;
+
/* Decide if document with <html>... should be returned */
var WHOLE_DOCUMENT = false;
@@ -239,6 +243,17 @@
'audio', 'head', 'math', 'script', 'style', 'svg', 'video'
]);
+ /* Tags that are safe for data: URIs */
+ var DATA_URI_TAGS = _addToSet({}, [
+ 'audio', 'video', 'img', 'source'
+ ]);
+
+ /* Attributes safe for values like "javascript:" */
+ var URI_SAFE_ATTRIBUTES = _addToSet({}, [
+ 'alt','class','for','id','label','name','pattern','placeholder',
+ 'summary','title','value','style','xmlns'
+ ]);
+
/* Keep a reference to config to pass to hooks */
var CONFIG = null;
@@ -277,6 +292,10 @@
SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
+ if (SAFE_FOR_TEMPLATES) {
+ ALLOW_DATA_ATTR = false;
+ }
+
if (RETURN_DOM_FRAGMENT) {
RETURN_DOM = true;
}
@@ -333,7 +352,7 @@
/* Some browsers throw, some browsers return null for the code above
DOMParser with text/html support is only in very recent browsers. */
- if (!doc){
+ if (!doc) {
doc = implementation.createHTMLDocument('');
body = doc.body;
body.parentNode.removeChild(body.parentNode.firstElementChild);
@@ -341,13 +360,12 @@
}
/* Work on whole document or just its body */
- if (typeof doc.getElementsByTagName === 'function'){
+ if (typeof doc.getElementsByTagName === 'function') {
return doc.getElementsByTagName(
WHOLE_DOCUMENT ? 'html' : 'body')[0];
- } else {
- return getElementsByTagName.call(doc,
- WHOLE_DOCUMENT ? 'html' : 'body')[0];
}
+ return getElementsByTagName.call(doc,
+ WHOLE_DOCUMENT ? 'html' : 'body')[0];
};
/**
@@ -389,9 +407,6 @@
return false;
};
- var MUSTACHE_EXPR = /\{\{.*|.*\}\}/gm;
- var ERB_EXPR = /<%.*|.*%>/gm;
-
/**
* _sanitizeElements
*
@@ -403,6 +418,7 @@
* @return true if node was killed, false if left alive
*/
var _sanitizeElements = function(currentNode) {
+ var tagName, content;
/* Execute a hook if present */
_executeHook('beforeSanitizeElements', currentNode, null);
@@ -413,7 +429,7 @@
}
/* Now let's check the element's type and name */
- var tagName = currentNode.nodeName.toLowerCase();
+ tagName = currentNode.nodeName.toLowerCase();
/* Execute a hook if present */
_executeHook('uponSanitizeElement', currentNode, {
@@ -442,7 +458,7 @@
/* Sanitize element content to be template-safe */
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
/* Get the element's text content */
- var content = currentNode.textContent;
+ content = currentNode.textContent;
content = content.replace(MUSTACHE_EXPR, ' ');
content = content.replace(ERB_EXPR, ' ');
currentNode.textContent = content;
@@ -455,7 +471,7 @@
};
var DATA_ATTR = /^data-[\w.\u00B7-\uFFFF-]/;
- var IS_SCRIPT_OR_DATA = /^(?:\w+script|data):/i;
+ var IS_ALLOWED_URI = /^(?:(?:(?:f|ht)tps?|mailto|tel):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i;
/* This needs to be extensive thanks to Webkit/Blink's behavior */
var ATTR_WHITESPACE = /[\x00-\x20\xA0\u1680\u180E\u2000-\u2029\u205f\u3000]/g;
@@ -471,21 +487,21 @@
* @return void
*/
var _sanitizeAttributes = function(currentNode) {
+ var attr, name, value, lcName, idAttr, attributes, hookEvent, l;
/* Execute a hook if present */
_executeHook('beforeSanitizeAttributes', currentNode, null);
- var attributes = currentNode.attributes;
+ attributes = currentNode.attributes;
/* Check if we have attributes; if not we might have a text node */
if (!attributes) { return; }
- var hookEvent = {
+ hookEvent = {
attrName: '',
attrValue: '',
keepAttr: true
};
- var l = attributes.length;
- var attr, name, value, lcName, idAttr;
+ l = attributes.length;
/* Go backwards over all attributes; safely remove bad ones */
while (l--) {
@@ -536,30 +552,32 @@
continue;
}
+ /* Sanitize attribute content to be template-safe */
+ if (SAFE_FOR_TEMPLATES) {
+ value = value.replace(MUSTACHE_EXPR, ' ');
+ value = value.replace(ERB_EXPR, ' ');
+ }
+
if (
/* Check the name is permitted */
- (
- (ALLOWED_ATTR[lcName] && !FORBID_ATTR[lcName]) ||
- /* Allow potentially valid data-* attributes
- * At least one character after "-" (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
- * XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804) */
- (!SAFE_FOR_TEMPLATES && ALLOW_DATA_ATTR && DATA_ATTR.test(lcName))
- ) &&
- /* Get rid of script and data URIs */
- (
- !IS_SCRIPT_OR_DATA.test(value.replace(ATTR_WHITESPACE,'')) ||
- /* Keep image data URIs alive if src is allowed */
- (lcName === 'src' && value.indexOf('data:') === 0 &&
- currentNode.nodeName === 'IMG')
- )
+ (ALLOWED_ATTR[lcName] && !FORBID_ATTR[lcName] && (
+ /* Check no script, data or unknown possibly unsafe URI
+ unless we know URI values are safe for that attribute */
+ URI_SAFE_ATTRIBUTES[lcName] ||
+ IS_ALLOWED_URI.test(value.replace(ATTR_WHITESPACE,'')) ||
+ /* Keep image data URIs alive if src is allowed */
+ (lcName === 'src' && value.indexOf('data:') === 0 &&
+ DATA_URI_TAGS[currentNode.nodeName.toLowerCase()])
+ )) ||
+ /* Allow potentially valid data-* attributes:
+ * At least one character after "-" (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
+ * XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
+ * We don't need to check the value; it's always URI safe.
+ */
+ (ALLOW_DATA_ATTR && DATA_ATTR.test(lcName))
) {
/* Handle invalid data-* attribute set by try-catching it */
try {
- /* Sanitize attribute content to be template-safe */
- if (SAFE_FOR_TEMPLATES) {
- value = value.replace(MUSTACHE_EXPR, ' ');
- value = value.replace(ERB_EXPR, ' ');
- }
currentNode.setAttribute(name, value);
} catch (e) {}
}
@@ -627,6 +645,7 @@
* @param {Object} configuration object
*/
DOMPurify.sanitize = function(dirty, cfg) {
+ var body, currentNode, oldNode, nodeIterator, returnNode;
/* Make sure we have a string to sanitize.
DO NOT return early, as this will return the wrong type if
the user has requested a DOM object rather than a string */
@@ -634,14 +653,18 @@
dirty = '';
}
- /* Stringify, in case dirty is an array or other object */
+ /* Stringify, in case dirty is an object */
if (typeof dirty !== 'string') {
- dirty = dirty.toString();
+ if (typeof dirty.toString !== 'function') {
+ throw new TypeError('toString is not a function');
+ } else {
+ dirty = dirty.toString();
+ }
}
/* Check we can run. Otherwise fall back or ignore */
if (!DOMPurify.isSupported) {
- if (typeof window.toStaticHTML === 'object'
+ if (typeof window.toStaticHTML === 'object'
|| typeof window.toStaticHTML === 'function') {
return window.toStaticHTML(dirty);
}
@@ -657,7 +680,7 @@
}
/* Initialize the document to work on */
- var body = _initDocument(dirty);
+ body = _initDocument(dirty);
/* Check we have a DOM node from the data */
if (!body) {
@@ -665,9 +688,7 @@
}
/* Get node iterator */
- var currentNode;
- var oldNode;
- var nodeIterator = _createIterator(body);
+ nodeIterator = _createIterator(body);
/* Now start iterating over the created document */
while ( (currentNode = nodeIterator.nextNode()) ) {
@@ -694,7 +715,6 @@
}
/* Return sanitized string or DOM */
- var returnNode;
if (RETURN_DOM) {
if (RETURN_DOM_FRAGMENT) {
diff --git a/test/fixtures/expect.js b/test/fixtures/expect.js
index 5aec4a5..8faa7bd 100644
--- a/test/fixtures/expect.js
+++ b/test/fixtures/expect.js
@@ -1,11 +1,22 @@
-module.exports = [{
+module.exports = [
+ {
+ "title": "safe usage of URI-like attribute values (see #135)",
+ "payload": "<b href=\"javascript:alert(1)\" title=\"javascript:alert(2)\"></b>",
+ "expected": "<b title=\"javascript:alert(2)\"></b>"
+ },
+ {
+ "title": "src Attributes for IMG, AUDIO, VIDEO and SOURCE (see #131)",
+ "payload": "<img src=\"data:,123\"><audio src=\"data:,456\"></audio><video src=\"data:,789\"></video><source src=\"data:,012\"><div src=\"data:,345\">",
+ "expected": "<img src=\"data:,123\"><audio src=\"data:,456\"></audio><video src=\"data:,789\"></video><source src=\"data:,012\"><div></div>"
+ },
+ {
"title": "DOM Clobbering against document.createElement() (see #47)",
- "payload": "<img src=x:x name=createElement><img src=y id=createElement>",
- "expected": "<img src=\"x:x\"><img src=\"y\">"
+ "payload": "<img src=x name=createElement><img src=y id=createElement>",
+ "expected": "<img src=\"x\"><img src=\"y\">"
}, {
"title": "DOM Clobbering against an empty cookie",
- "payload": "<img src=x:x name=cookie>",
- "expected": "<img src=\"x:x\">"
+ "payload": "<img src=x name=cookie>",
+ "expected": "<img src=\"x\">"
}, {
"title": "JavaScript URIs using Unicode LS/PS I",
"payload": "123<a href='\u2028javascript:alert(1)'>I am a dolphin!</a>",
@@ -40,8 +51,8 @@ module.exports = [{
"expected": ["", "<form><input><input></form>"]
}, {
"title": "DOM clobbering: getElementById",
- "payload": "<img src=x:x name=getElementById>",
- "expected": "<img src=\"x:x\">"
+ "payload": "<img src=x name=getElementById>",
+ "expected": "<img src=\"x\">"
}, {
"title": "DOM clobbering: location",
"payload": "<a href=\"#some-code-here\" id=\"location\">invisible",
@@ -88,35 +99,35 @@ module.exports = [{
"expected": "<p>hello</p>"
}, {
"title": "mXSS Variation I",
- "payload": "<listing><img onerror=\"alert(1);//\" src=x:x><t t></listing>",
+ "payload": "<listing><img onerror=\"alert(1);//\" src=x><t t></listing>",
"expected": [
- "<img onerror=\"alert(1);//\" src=x:x>",
- "<img src=\"x:x\">"
+ "<img onerror=\"alert(1);//\" src=x>",
+ "<img src=\"x\">"
]
}, {
"title": "mXSS Variation II",
- "payload": "<img src=x:x id/=' onerror=alert(1)//'>",
- "expected": ["<img src=\"x:x\">", "<img id=\"\" src=\"x:x\">"]
+ "payload": "<img src=x id/=' onerror=alert(1)//'>",
+ "expected": ["<img src=\"x\">", "<img id=\"\" src=\"x\">"]
}, {
"title": "Textarea and comments enabling img element",
"payload": "<textarea>@shafigullin</textarea><!--</textarea><img src=x onerror=alert(1)>-->",
"expected": "<textarea>@shafigullin</textarea>"
}, {
"title": "Img element inside noscript terminated inside comment",
- "payload": "<b><noscript><!-- </noscript><img src=x:x onerror=alert(1) --></noscript>",
- "expected": ["<b></b>", "<b><img src=\"x:x\"></b>"]
+ "payload": "<b><noscript><!-- </noscript><img src=x onerror=alert(1) --></noscript>",
+ "expected": ["<b></b>", "<b><img src=\"x\"></b>"]
}, {
"title": "Img element inside noscript terminated inside attribute",
- "payload": "<b><noscript><a alt=\"</noscript><img src=x:x onerror=alert(1)>\"></noscript>",
+ "payload": "<b><noscript><a alt=\"</noscript><img src=x onerror=alert(1)>\"></noscript>",
"expected": [
- "<b><img src=\"x:x\">\"></b>",
- "<b><a alt=\"</noscript><img src=x:x onerror=alert(1)>\"></a></b>",
- "<b><a alt=\"</noscript><img src=x:x onerror=alert(1)>\"></a></b>"
+ "<b><img src=\"x\">\"></b>",
+ "<b><a alt=\"</noscript><img src=x onerror=alert(1)>\"></a></b>",
+ "<b><a alt=\"</noscript><img src=x onerror=alert(1)>\"></a></b>"
]
}, {
"title": "Img element inside shadow DOM template",
- "payload": "<body><template><s><template><s><img src=x:x onerror=alert(1)>@shafigullin</s></template></s></template>",
- "expected": "<template><s><template><s><img src=\"x:x\">@shafigullin</s></template></s></template>"
+ "payload": "<body><template><s><template><s><img src=x onerror=alert(1)>@shafigullin</s></template></s></template>",
+ "expected": "<template><s><template><s><img src=\"x\">@shafigullin</s></template></s></template>"
}, {
"title": "Low-range-ASCII obfuscated JavaScript URI",
"payload": "<a href=\"\u0001java\u0003script:alert(1)\">@shafigullin<a>",
@@ -126,8 +137,8 @@ module.exports = [{
]
}, {
"title": "Img inside style inside broken option element",
- "payload": "\u0001<option><style></option></select><b><img src=x:x onerror=alert(1)></style></option>",
- "expected": "\u0001<option><style></option></select><b><img src=x:x onerror=alert(1)></style></option>"
+ "payload": "\u0001<option><style></option></select><b><img src=x onerror=alert(1)></style></option>",
+ "expected": "\u0001<option><style></option></select><b><img src=x onerror=alert(1)></style></option>"
}, {
"title": "Iframe inside option element",
"payload": "<option><iframe></select><b><script>alert(1)</script>",
@@ -141,12 +152,12 @@ module.exports = [{
"expected": ""
}, {
"title": "Image after style to trick jQuery tag-completion",
- "payload": "<b><style><style/><img src=x:x onerror=alert(1)>",
- "expected": "<b><style><style/><img src=x:x onerror=alert(1)></style></b>"
+ "payload": "<b><style><style/><img src=x onerror=alert(1)>",
+ "expected": "<b><style><style/><img src=x onerror=alert(1)></style></b>"
}, {
"title": "Image after self-closing style to trick jQuery tag-completion",
- "payload": "<b><style><style////><img src=x:x onerror=alert(1)></style>",
- "expected": "<b><style><style////><img src=x:x onerror=alert(1)></style></b>"
+ "payload": "<b><style><style////><img src=x onerror=alert(1)></style>",
+ "expected": "<b><style><style////><img src=x onerror=alert(1)></style></b>"
}, {
"title": "MathML example",
"payload": "<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"block\">\n <mrow>\n <menclose notation=\"box\"><mi>a</mi></menclose><mo>,</mo>\n <menclose notation=\"box\"><mi mathcolor=\"#FF0000\">a</mi></menclose><mo>,</mo>\n <menclose notation=\"box\" mathcolor=\"#FF0000\"><mi>a</mi></menclose><mo>,</mo>\n <menclose notation=\"box\" mathbackground=\"#80FF80\"><mi mathcolor=\"#FF0000\">a</mi></menclose><mo>,</mo>\n <menclose notation=\"box\" mathcolor=\"# [...]
@@ -180,10 +191,10 @@ module.exports = [{
]
}, {
"title": "DOM clobbering attack using name=body and injecting SVG + keygen",
- "payload": "<image name=body><img src=x:x><svg onload=alert(1); autofocus>, <keygen onfocus=alert(1); autofocus>",
+ "payload": "<image name=body><img src=x><svg onload=alert(1); autofocus>, <keygen onfocus=alert(1); autofocus>",
"expected": [
- "<img><img src=\"x:x\"><svg>, </svg>",
- "<img><img src=\"x:x\"><svg xmlns=\"http://www.w3.org/2000/svg\">, </svg></svg>"
+ "<img><img src=\"x\"><svg>, </svg>",
+ "<img><img src=\"x\"><svg xmlns=\"http://www.w3.org/2000/svg\">, </svg></svg>"
]
}, {
"title": "Bypass using multiple unknown attributes",
@@ -314,7 +325,7 @@ module.exports = [{
"<div id=\"23\"><form><input><button>X</button>//[\"'`-->]]>]</form></div>"
]
}, {
- "payload": "<div id=\"24\">1<set/xmlns=`urn:schemas-microsoft-com:time` style=`behAvior:url(#default#time2)` attributename=`innerhtml` to=`<img/src=\"x:x\"onerror=alert(24)>`>//[\"'`-->]]>]</div>",
+ "payload": "<div id=\"24\">1<set/xmlns=`urn:schemas-microsoft-com:time` style=`behAvior:url(#default#time2)` attributename=`innerhtml` to=`<img/src=\"x\"onerror=alert(24)>`>//[\"'`-->]]>]</div>",
"expected": "<div id=\"24\">1`>//[\"'`-->]]>]</div>"
}, {
"payload": "<div id=\"25\"><script src=\"#\">{alert(25)}</script>;1//[\"'`-->]]>]</div>",
@@ -362,8 +373,8 @@ module.exports = [{
"<div id=\"36\"><a style=\"-ms-behavior: url(#default#AnchorClick);\">XXX</a>//[\"'`-->]]>]</div>"
]
}, {
- "payload": "<div id=\"37\"><!--<img src=\"--><img src=x:x onerror=alert(37)//\">//[\"'`-->]]>]</div>",
- "expected": "<div id=\"37\"><img src=\"x:x\">//[\"'`-->]]>]</div>"
+ "payload": "<div id=\"37\"><!--<img src=\"--><img src=x onerror=alert(37)//\">//[\"'`-->]]>]</div>",
+ "expected": "<div id=\"37\"><img src=\"x\">//[\"'`-->]]>]</div>"
}, {
"payload": "<div id=\"38\"><comment><img src=\"</comment><img src=x onerror=alert(38)//\">//[\"'`-->]]>]</div><div id=\"39\"><!-- up to Opera 11.52, FF 3.6.28 -->",
"expected": [
@@ -379,15 +390,15 @@ module.exports = [{
"<img src=\"]%3E%3Cimg%20src=x%20onerror=alert%2839%29//\">"
]
}, {
- "payload": "<!-- IE9+, FF4+, Opera 11.60+, Safari 4.0.4+, GC7+ -->\n<svg><![CDATA[><image xlink:href=\"]]><img src=x:x onerror=alert(2)//\"></svg>//[\"'`-->]]>]</div>",
+ "payload": "<!-- IE9+, FF4+, Opera 11.60+, Safari 4.0.4+, GC7+ -->\n<svg><![CDATA[><image xlink:href=\"]]><img src=x onerror=alert(2)//\"></svg>//[\"'`-->]]>]</div>",
"expected": [
- "<svg>><image xlink:href=\"</svg><img src=\"x:x\">//[\"'`-->]]>]",
- "<svg>><image xlink:href=\"<img src=\"x:x\"></img></svg>//[\"'`-->]]>]",
- "<svg xmlns=\"http://www.w3.org/2000/svg\">><image xlink:href=\"</svg></svg><img src=\"x:x\">//[\"'`-->]]>]"
+ "<svg>><image xlink:href=\"</svg><img src=\"x\">//[\"'`-->]]>]",
+ "<svg>><image xlink:href=\"<img src=\"x\"></img></svg>//[\"'`-->]]>]",
+ "<svg xmlns=\"http://www.w3.org/2000/svg\">><image xlink:href=\"</svg></svg><img src=\"x\">//[\"'`-->]]>]"
]
}, {
- "payload": "<div id=\"40\"><style><img src=\"</style><img src=x:x onerror=alert(40)//\">//[\"'`-->]]>]</div>",
- "expected": "<div id=\"40\"><style><img src=\"</style><img src=\"x:x\">//[\"'`-->]]>]</div>"
+ "payload": "<div id=\"40\"><style><img src=\"</style><img src=x onerror=alert(40)//\">//[\"'`-->]]>]</div>",
+ "expected": "<div id=\"40\"><style><img src=\"</style><img src=\"x\">//[\"'`-->]]>]</div>"
}, {
"payload": "<div id=\"41\"><li style=list-style:url() onerror=alert(41)></li>",
"expected": [
@@ -501,7 +512,7 @@ module.exports = [{
"<div id=\"65\"><svg xmlns=\"http://www.w3.org/2000/svg\" />//[\"'`-->]]>]</div><div id=\"66\"></div>"
]
}, {
- "payload": "<?xml-stylesheet type=\"text/xsl\" href=\"data:,%3Cxsl:transform version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' id='xss'%3E%3Cxsl:output method='html'/%3E%3Cxsl:template match='/'%3E%3Cscript%3Ealert(66)%3C/script%3E%3C/xsl:template%3E%3C/xsl:transform%3E\"?>\n<root/>//[\"'`-->]]>]</div>\n<div id=\"67\"><!DOCTYPE x [\n <!ATTLIST img xmlns CDATA \"http://www.w3.org/1999/xhtml\" src CDATA \"xx:x\"\n onerror CDATA \"alert(67)\"\n onload CDATA \"alert(2)\ [...]
+ "payload": "<?xml-stylesheet type=\"text/xsl\" href=\"data:,%3Cxsl:transform version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' id='xss'%3E%3Cxsl:output method='html'/%3E%3Cxsl:template match='/'%3E%3Cscript%3Ealert(66)%3C/script%3E%3C/xsl:template%3E%3C/xsl:transform%3E\"?>\n<root/>//[\"'`-->]]>]</div>\n<div id=\"67\"><!DOCTYPE x [\n <!ATTLIST img xmlns CDATA \"http://www.w3.org/1999/xhtml\" src CDATA \"xx\"\n onerror CDATA \"alert(67)\"\n onload CDATA \"alert(2)\"> [...]
"expected": "//[\"'`-->]]>]\n<div id=\"67\">\n]><img>//[\"'`-->]]>]</div>"
}, {
"payload": "<div id=\"68\"><doc xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:html=\"http://www.w3.org/1999/xhtml\">\n <html:style /><x xlink:href=\"javascript:alert(68)\" xlink:type=\"simple\">XXX</x>\n</doc>//[\"'`-->]]>]</div>",
@@ -543,7 +554,7 @@ module.exports = [{
"payload": "<div id=\"78\"><?xml-stylesheet type=\"text/xsl\" href=\"#\"?><img xmlns=\"x-schema:test.xdr\"/>//[\"'`-->]]>]</div>",
"expected": "<div id=\"78\"><img xmlns=\"x-schema:test.xdr\">//[\"'`-->]]>]</div>"
}, {
- "payload": "<div id=\"79\"><object allowscriptaccess=\"always\" data=\"x:x\"></object>//[\"'`-->]]>]</div>",
+ "payload": "<div id=\"79\"><object allowscriptaccess=\"always\" data=\"x\"></object>//[\"'`-->]]>]</div>",
"expected": "<div id=\"79\">//[\"'`-->]]>]</div>"
}, {
"payload": "<div id=\"80\"><style>*{x:\uFF45\uFF58\uFF50\uFF52\uFF45\uFF53\uFF53\uFF49\uFF4F\uFF4E(alert(80))}</style>//[\"'`-->]]>]</div>",
@@ -642,8 +653,8 @@ module.exports = [{
"<div id=\"98\"><div id=\"d\"><div style=\"font-family:'sansFAAFB colorAredB'\">X</div></div>\n//[\"'`-->]]>]</div>"
]
}, {
- "payload": "<div id=\"99\">XXX<style>\n\n*{color:gre/**/en !/**/important} /* IE 6-9 Standards mode */\n\n<!--\n--><!--*{color:red} /* all UA */\n\n*{background:url(xx:x //**/\red/*)} /* IE 6-7 Standards mode */\n\n</style>//[\"'`-->]]>]</div>",
- "expected": "<div id=\"99\">XXX<style>\n\n*{color:gre/**/en !/**/important} /* IE 6-9 Standards mode */\n\n<!--\n--><!--*{color:red} /* all UA */\n\n*{background:url(xx:x //**/\ned/*)} /* IE 6-7 Standards mode */\n\n</style>//[\"'`-->]]>]</div>"
+ "payload": "<div id=\"99\">XXX<style>\n\n*{color:gre/**/en !/**/important} /* IE 6-9 Standards mode */\n\n<!--\n--><!--*{color:red} /* all UA */\n\n*{background:url(xx //**/\red/*)} /* IE 6-7 Standards mode */\n\n</style>//[\"'`-->]]>]</div>",
+ "expected": "<div id=\"99\">XXX<style>\n\n*{color:gre/**/en !/**/important} /* IE 6-9 Standards mode */\n\n<!--\n--><!--*{color:red} /* all UA */\n\n*{background:url(xx //**/\ned/*)} /* IE 6-7 Standards mode */\n\n</style>//[\"'`-->]]>]</div>"
}, {
"payload": "<div id=\"100\"><img[a][b]src=x[d]onerror[c]=[e]\"alert(100)\">//[\"'`-->]]>]</div>",
"expected": "<div id=\"100\">//[\"'`-->]]>]</div>"
@@ -680,11 +691,11 @@ module.exports = [{
"payload": "<div id=\"107\"><title onpropertychange=alert(107)></title><title title=></title>//[\"'`-->]]>]</div>",
"expected": "<div id=\"107\"><title></title><title title=\"\"></title>//[\"'`-->]]>]</div>"
}, {
- "payload": "<div id=\"108\"><!-- IE 5-8 standards mode -->\n<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=xx:x onerror=alert(108)></a>\">\n<!-- IE 5-9 standards mode -->\n<!a foo=x=`y><img alt=\"`><img src=xx:x onerror=alert(2)//\">\n<?a foo=x=`y><img alt=\"`><img src=xx:x onerror=alert(3)//\">//[\"'`-->]]>]</div>",
+ "payload": "<div id=\"108\"><!-- IE 5-8 standards mode -->\n<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=xx onerror=alert(108)></a>\">\n<!-- IE 5-9 standards mode -->\n<!a foo=x=`y><img alt=\"`><img src=xx onerror=alert(2)//\">\n<?a foo=x=`y><img alt=\"`><img src=xx onerror=alert(3)//\">//[\"'`-->]]>]</div>",
"expected": [
- "<div id=\"108\">\n<a href=\"http://foo.bar/#x=`y\"></a><img alt=\"`><img src=xx:x onerror=alert(108)></a>\">\n\n<img alt=\"`><img src=xx:x onerror=alert(2)//\">\n<img alt=\"`><img src=xx:x onerror=alert(3)//\">//[\"'`-->]]>]</div>",
- "<div id=\"108\">\n<a href=\"http://foo.bar/#x=`y\"></a><img alt=\"`><img src=xx:x onerror=alert(108)></a>\">\n\n<img alt=\"`><img src=xx:x onerror=alert(2)//\">\n<img alt=\"`><img src=xx:x onerror=alert(3)//\">//[\"'`-->]]>]</div>",
- "<div id=\"108\">\n<a href=\"http://foo.bar/#x=%60y\"></a><img alt=\"`><img src=xx:x onerror=alert(108)></a>\">\n\n<img alt=\"`><img src=xx:x onerror=alert(2)//\">\n<img alt=\"`><img src=xx:x onerror=alert(3)//\">//[\"'`-->]]>]</div>"
+ "<div id=\"108\">\n<a href=\"http://foo.bar/#x=`y\"></a><img alt=\"`><img src=xx onerror=alert(108)></a>\">\n\n<img alt=\"`><img src=xx onerror=alert(2)//\">\n<img alt=\"`><img src=xx onerror=alert(3)//\">//[\"'`-->]]>]</div>",
+ "<div id=\"108\">\n<a href=\"http://foo.bar/#x=`y\"></a><img alt=\"`><img src=xx onerror=alert(108)></a>\">\n\n<img alt=\"`><img src=xx onerror=alert(2)//\">\n<img alt=\"`><img src=xx onerror=alert(3)//\">//[\"'`-->]]>]</div>",
+ "<div id=\"108\">\n<a href=\"http://foo.bar/#x=%60y\"></a><img alt=\"`><img src=xx onerror=alert(108)></a>\">\n\n<img alt=\"`><img src=xx onerror=alert(2)//\">\n<img alt=\"`><img src=xx onerror=alert(3)//\">//[\"'`-->]]>]</div>"
]
}, {
"payload": "<div id=\"109\"><svg xmlns=\"http://www.w3.org/2000/svg\">\n<a id=\"x\"><rect fill=\"white\" width=\"1000\" height=\"1000\"/></a>\n<rect fill=\"white\" style=\"clip-path:url(test3.svg#a);fill:url(#b);filter:url(#c);marker:url(#d);mask:url(#e);stroke:url(#f);\"/>\n</svg>//[\"'`-->]]>]</div>",
@@ -720,7 +731,7 @@ module.exports = [{
"expected": "<div id=\"114\">XXX//[\"'`-->]]>]</div><div id=\"115\">\n//[\"'`-->]]>]</div>"
}, {
"title": "XML",
- "payload": "<div id=\"116\"><div id=\"x\">x</div>\n<xml:namespace prefix=\"t\">\n<import namespace=\"t\" implementation=\"#default#time2\">\n<t:set attributeName=\"innerHTML\" targetElement=\"x\" to=\"<img\u000Bsrc=x:x\u000Bonerror\u000B=alert(116)>\">//[\"'`-->]]>]</div>",
+ "payload": "<div id=\"116\"><div id=\"x\">x</div>\n<xml:namespace prefix=\"t\">\n<import namespace=\"t\" implementation=\"#default#time2\">\n<t:set attributeName=\"innerHTML\" targetElement=\"x\" to=\"<img\u000Bsrc=x\u000Bonerror\u000B=alert(116)>\">//[\"'`-->]]>]</div>",
"expected": "<div id=\"116\"><div id=\"x\">x</div>\n\n\n//[\"'`-->]]>]</div>"
}, {
"title": "iframe",
@@ -780,11 +791,11 @@ module.exports = [{
"<div id=\"127\"><svg xmlns=\"http://www.w3.org/2000/svg\" id=\"x\">\n\n\n</svg>//[\"'`-->]]>]</div>"
]
}, {
- "payload": "<div id=\"128\"><svg><style><img/src=x:x onerror=alert(128)// </b>//[\"'`-->]]>]</div>",
+ "payload": "<div id=\"128\"><svg><style><img/src=x onerror=alert(128)// </b>//[\"'`-->]]>]</div>",
"expected": [
- "<div id=\"128\"><svg><style></style></svg><img src=\"x:x\">//[\"'`-->]]>]</div>",
- "<div id=\"128\"><svg><style><img src=\"x:x\">//[\"'`-->]]>]</img></style></svg></div>",
- "<div id=\"128\"><svg xmlns=\"http://www.w3.org/2000/svg\"><style /></svg></svg><img src=\"x:x\">//[\"'`-->]]>]</div>"
+ "<div id=\"128\"><svg><style></style></svg><img src=\"x\">//[\"'`-->]]>]</div>",
+ "<div id=\"128\"><svg><style><img src=\"x\">//[\"'`-->]]>]</img></style></svg></div>",
+ "<div id=\"128\"><svg xmlns=\"http://www.w3.org/2000/svg\"><style /></svg></svg><img src=\"x\">//[\"'`-->]]>]</div>"
]
}, {
"title": "Inline SVG (data-uri)",
@@ -817,14 +828,14 @@ module.exports = [{
"<div id=\"132\">\n<form>\n<label>type a,b,c,d - watch the network tab/traffic (JS is off, latest NoScript)</label>\n<br>\n<input name=\"secret\" type=\"password\">\n</form>\n<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"50px\">\n<image xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n\n\n\n\n</image>\n</svg>//[\"'`-->]]>]</div>"
]
}, {
- "payload": "<div id=\"133\"><!-- `<img/src=xx:xx onerror=alert(133)//--!>//[\"'`-->]]>]</div>",
+ "payload": "<div id=\"133\"><!-- `<img/src=xxx onerror=alert(133)//--!>//[\"'`-->]]>]</div>",
"expected": "<div id=\"133\">//[\"'`-->]]>]</div>"
}, {
"title": "XMP",
- "payload": "<div id=\"134\"><xmp>\n<%\n</xmp>\n<img alt='%></xmp><img src=xx:x onerror=alert(134)//'>\n\n<script>\nx='<%'\n</script> %>/\nalert(2)\n</script>\n\nXXX\n<style>\n*['<!--']{}\n</style>\n-->{}\n*{color:red}</style>//[\"'`-->]]>]</div>",
+ "payload": "<div id=\"134\"><xmp>\n<%\n</xmp>\n<img alt='%></xmp><img src=xx onerror=alert(134)//'>\n\n<script>\nx='<%'\n</script> %>/\nalert(2)\n</script>\n\nXXX\n<style>\n*['<!--']{}\n</style>\n-->{}\n*{color:red}</style>//[\"'`-->]]>]</div>",
"expected": [
- "<div id=\"134\">\n<%\n\n<img alt=\"%></xmp><img src=xx:x onerror=alert(134)//\">\n\n %>/\nalert(2)\n\n\nXXX\n<style>\n*['<!--']{}\n</style>\n-->{}\n*{color:red}//[\"'`-->]]>]</div>",
- "<div id=\"134\">\n<%\n\n<img alt=\"%></xmp><img src=xx:x onerror=alert(134)//\">\n\n %>/\nalert(2)\n\n\nXXX\n<style>\n*['<!--']{}\n</style>\n-->{}\n*{color:red}//[\"'`-->]]>]</div>"
+ "<div id=\"134\">\n<%\n\n<img alt=\"%></xmp><img src=xx onerror=alert(134)//\">\n\n %>/\nalert(2)\n\n\nXXX\n<style>\n*['<!--']{}\n</style>\n-->{}\n*{color:red}//[\"'`-->]]>]</div>",
+ "<div id=\"134\">\n<%\n\n<img alt=\"%></xmp><img src=xx onerror=alert(134)//\">\n\n %>/\nalert(2)\n\n\nXXX\n<style>\n*['<!--']{}\n</style>\n-->{}\n*{color:red}//[\"'`-->]]>]</div>"
]
}, {
"title": "SVG",
@@ -834,12 +845,12 @@ module.exports = [{
"<div id=\"135\">\n\n<template>\nnew ActiveXObject('htmlfile').parentWindow.alert(135)\n\n</template>\n//[\"'`-->]]>]</div>"
]
}, {
- "payload": "<div id=\"136\"><form action=\"\" method=\"post\">\n<input name=\"username\" value=\"admin\" />\n<input name=\"password\" type=\"password\" value=\"secret\" />\n<input name=\"injected\" value=\"injected\" dirname=\"password\" />\n<input type=\"submit\">\n</form>//[\"'`-->]]>]</div>",
+ "payload": "<div id=\"136\"><form action=\"x\" method=\"post\">\n<input name=\"username\" value=\"admin\" />\n<input name=\"password\" type=\"password\" value=\"secret\" />\n<input name=\"injected\" value=\"injected\" dirname=\"password\" />\n<input type=\"submit\">\n</form>//[\"'`-->]]>]</div>",
"expected": [
- "<div id=\"136\"><form method=\"post\" action=\"\">\n<input value=\"admin\" name=\"username\">\n<input value=\"secret\" type=\"password\" name=\"password\">\n<input value=\"injected\" name=\"injected\">\n<input type=\"submit\">\n</form>//[\"'`-->]]>]</div>",
- "<div id=\"136\"><form method=\"post\" action=\"\">\n<input value=\"admin\" name=\"username\">\n<input value=\"secret\" type=\"password\" name=\"password\">\n<input value=\"injected\" name=\"injected\">\n<input type=\"submit\">\n//[\"'`-->]]>]</form></div>",
- "<div id=\"136\"><form method=\"post\" action=\"\">\n<input value=\"admin\" name=\"username\">\n<input value=\"secret\" name=\"password\" type=\"password\">\n<input value=\"injected\" name=\"injected\">\n<input type=\"submit\">\n</form>//[\"'`-->]]>]</div>",
- "<div id=\"136\"><form action=\"\" method=\"post\">\n<input name=\"username\" value=\"admin\">\n<input name=\"password\" type=\"password\" value=\"secret\">\n<input name=\"injected\" value=\"injected\">\n<input type=\"submit\" value=\"Submit Query\">\n</form>//[\"'`-->]]>]</div>"
+ "<div id=\"136\"><form method=\"post\" action=\"x\">\n<input value=\"admin\" name=\"username\">\n<input value=\"secret\" type=\"password\" name=\"password\">\n<input value=\"injected\" name=\"injected\">\n<input type=\"submit\">\n</form>//[\"'`-->]]>]</div>",
+ "<div id=\"136\"><form method=\"post\" action=\"x\">\n<input value=\"admin\" name=\"username\">\n<input value=\"secret\" type=\"password\" name=\"password\">\n<input value=\"injected\" name=\"injected\">\n<input type=\"submit\">\n//[\"'`-->]]>]</form></div>",
+ "<div id=\"136\"><form method=\"post\" action=\"x\">\n<input value=\"admin\" name=\"username\">\n<input value=\"secret\" name=\"password\" type=\"password\">\n<input value=\"injected\" name=\"injected\">\n<input type=\"submit\">\n</form>//[\"'`-->]]>]</div>",
+ "<div id=\"136\"><form action=\"x\" method=\"post\">\n<input name=\"username\" value=\"admin\">\n<input name=\"password\" type=\"password\" value=\"secret\">\n<input name=\"injected\" value=\"injected\">\n<input type=\"submit\" value=\"Submit Query\">\n</form>//[\"'`-->]]>]</div>"
]
}, {
"title": "SVG",
diff --git a/test/test-suite.js b/test/test-suite.js
index ae0d08d..e97c290 100644
--- a/test/test-suite.js
+++ b/test/test-suite.js
@@ -78,6 +78,7 @@ module.exports = function(DOMPurify, tests, xssTests) {
["<b>he ya</b>", "<b>he </b>", "<b>he <form><img src=\"x\"></form> ya</b>"] // Investigate on Safari 8!
);
assert.equal( DOMPurify.sanitize( '<a>123<% <b>456}}</b><style>{{ alert(1) }}</style>456 %></a>', {SAFE_FOR_TEMPLATES: true}), "<a>123 <b> </b><style> </style> </a>" );
+ assert.equal( DOMPurify.sanitize( '<a href="}}javascript:alert(1)"></a>', {SAFE_FOR_TEMPLATES: true}), "<a></a>" );
});
QUnit.test( 'Config-Flag tests: SANITIZE_DOM', function(assert) {
// SANITIZE_DOM
diff --git a/website/index.html b/website/index.html
index 24f19bc..a09fa20 100644
--- a/website/index.html
+++ b/website/index.html
@@ -2,7 +2,7 @@
<html>
<head>
<meta charset="UTF-8">
- <title>DOMPurify 0.7.3 "Black Mamba"</title>
+ <title>DOMPurify 0.7.4 "Common Snapping Turtle"</title>
<script src="../dist/purify.min.js"></script>
<!-- we don't actually need it - just to demo and test the $(html) sanitation -->
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
@@ -23,7 +23,7 @@
</script>
</head>
<body>
- <h4>DOMPurify 0.7.3 "Black Mamba"</h4>
+ <h4>DOMPurify 0.7.4 "Common Snapping Turtle"</h4>
<p>
<a href="http://badge.fury.io/bo/dompurify"><img style="max-width:100%;" alt="Bower version" src="https://badge.fury.io/bo/dompurify.svg"></a> · <a href="http://badge.fury.io/js/dompurify"><img style="max-width:100%;" alt="npm version" src="https://badge.fury.io/js/dompurify.svg"></a> · <a href="https://travis-ci.org/cure53/DOMPurify"><img style="max-width:100%;" alt="Build Status" src="https://travis-ci.org/cure53/DOMPurify.svg?branch=master"></a>
</p>
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/dompurify.js.git
More information about the Pkg-javascript-commits
mailing list