Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(293)

Unified Diff: sdk/lib/html/dart2js/html_dart2js.dart

Side-by-side diff isn't available for this file because of its large size.
Issue 1077813002: Check for DOM clobbering attacks in sanitizing/node validation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
Download patch
« no previous file with comments | « no previous file | sdk/lib/html/dartium/html_dartium.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/html/dart2js/html_dart2js.dart
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index bd5a30e4a378e5fd2dc5bb2a8ddddd7e5e959948..2b7006bd5a81f4be99f61e711e7acc6f9625cd41 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -13255,6 +13255,33 @@ abstract class Element extends Node implements GlobalEventHandlers, ParentNode,
* used when an explicit accessor is not available.
*/
ElementEvents get on => new ElementEvents(this);
+
+ /**
+ * Verify if any of the attributes that we use in the sanitizer look unexpected,
+ * possibly indicating DOM clobbering attacks.
+ *
+ * Those attributes are: attributes, lastChild, children, previousNode and tagName.
+ */
+ bool get _hasCorruptedAttributes {
+ return JS('bool', r'''
+ (function(element) {
+ if (!(element.attributes instanceof NamedNodeMap)) {
+ return true;
+ }
+ var childNodes = element.childNodes;
+ if (element.lastChild &&
+ element.lastChild !== childNodes[childNodes.length -1]) {
+ return true;
+ }
+ if (element.children) {
+ if (!((element.children instanceof HTMLCollection) ||
+ (element.children instanceof NodeList))) {
+ return true;
+ }
+ }
+ return false;
+ })(#)''', this);
+ }
@DomName('Element.offsetHeight')
@DocsEditable()
@@ -40773,29 +40800,50 @@ class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
_ValidatingTreeSanitizer(this.validator) {}
void sanitizeTree(Node node) {
- void walk(Node node) {
- sanitizeNode(node);
+ void walk(Node node, Node parent) {
+ sanitizeNode(node, parent);
var child = node.lastChild;
while (child != null) {
// Child may be removed during the walk.
var nextChild = child.previousNode;
- walk(child);
+ walk(child, node);
child = nextChild;
}
}
- walk(node);
+ walk(node, null);
}
- void sanitizeNode(Node node) {
+ /// Aggressively try to remove node.
+ void _removeNode(Node node, Node parent) {
+ // If we have the parent, it's presumably already passed more sanitization or
+ // is the fragment, so ask it to remove the child. And if that fails try to
+ // set the outer html.
+ if (parent == null) {
+ node.remove();
+ } else {
+ try {
+ parent._removeChild(node);
+ } catch (e) {
+ node.outerHtml = '';
+ }
+ }
+ }
+
+ void sanitizeNode(Node node, Node parent) {
switch (node.nodeType) {
case Node.ELEMENT_NODE:
Element element = node;
+ if (element._hasCorruptedAttributes) {
+ window.console.warn('Removing element due to corrupted attributes on <${element}>');
+ _removeNode(node, parent);
+ break;
+ }
var attrs = element.attributes;
if (!validator.allowsElement(element)) {
window.console.warn(
'Removing disallowed element <${element.tagName}>');
- element.remove();
+ _removeNode(node, parent);
break;
}
@@ -40804,7 +40852,7 @@ class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
if (!validator.allowsAttribute(element, 'is', isAttr)) {
window.console.warn('Removing disallowed type extension '
'<${element.tagName} is="$isAttr">');
- element.remove();
+ _removeNode(node, parent);
break;
}
}
@@ -40833,7 +40881,7 @@ class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
case Node.CDATA_SECTION_NODE:
break;
default:
- node.remove();
+ _removeNode(node, parent);
}
}
}
« no previous file with comments | « no previous file | sdk/lib/html/dartium/html_dartium.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698