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

Side by Side Diff: tools/dom/src/Validators.dart

Issue 16374007: First rev of Safe DOM (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 6 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:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of dart.dom.html;
6
7
8 /**
9 * Interface used to validate that only accepted elements and attributes are
10 * allowed while parsing HTML strings into DOM nodes.
11 */
12 abstract class NodeValidator {
13
14 /**
15 * Construct a default NodeValidator which only accepts whitelisted HTML5
16 * elements and attributes.
17 *
18 * If a uriPolicy is not specified then the default uriPolicy will be used.
19 */
20 factory NodeValidator({UriPolicy uriPolicy}) =>
21 new _Html5NodeValidator(uriPolicy: uriPolicy);
22
23 /**
24 * Returns true if the tagName is an accepted type.
25 */
26 bool allowsElement(Element element);
27
28 /**
29 * Returns true if the attribute is allowed.
30 *
31 * The attributeName parameter will always be in lowercase.
32 *
33 * See [allowsElement] for format of tagName.
34 */
35 bool allowsAttribute(Element element, String attributeName, String value);
36 }
37
38 /**
39 * Performs sanitization of a node tree after construction to ensure that it
40 * does not contain any disallowed elements or attributes.
41 *
42 * In general custom implementations of this class should not be necessary and
43 * all validation customization should be done in custom NodeValidators, but
44 * custom implementations of this class can be created to perform more complex
45 * tree sanitization.
46 */
47 abstract class NodeTreeSanitizer {
48
49 /**
50 * Constructs a default tree sanitizer which will remove all elements and
51 * attributes which are not allowed by the provided validator.
52 */
53 factory NodeTreeSanitizer(NodeValidator validator) =>
54 new _ValidatingTreeSanitizer(validator);
55
56 /**
57 * Called with the root of the tree which is to be sanitized.
58 *
59 * This method needs to walk the entire tree and either remove elements and
60 * attributes which are not recognized as safe or throw an exception which
61 * will mark the entire tree as unsafe.
62 */
63 void sanitizeTree(Node node);
64 }
65
66 /**
67 * Defines the policy for what types of uris are allowed for particular
68 * attribute values.
69 *
70 * This can be used to provide custom rules such as allowing all http:// URIs
71 * for image attributes but only same-origin URIs for anchor tags.
72 */
73 abstract class UriPolicy {
74 /**
75 * Constructs the default UriPolicy which is to only allow Uris to the same
76 * origin as the application was launched from.
77 *
78 * This will block all ftp: mailto: URIs. It will also block accessing
79 * https://example.com if the app is running from http://example.com.
80 */
81 factory UriPolicy() => new _SameOriginUriPolicy();
82
83 /**
84 * Checks if the uri is allowed on the specified attribute.
85 *
86 * The uri provided may or may not be a relative path.
87 */
88 bool allowsUri(String uri);
89 }
90
91 /**
92 * Allows URIs to the same origin as the current application was loaded from
93 * (such as https://example.com:80).
94 */
95 class _SameOriginUriPolicy implements UriPolicy {
96 final AnchorElement _hiddenAnchor = new AnchorElement();
97
98 bool allowsUri(String uri) {
99 _hiddenAnchor.href = uri;
100 return _hiddenAnchor.href.startsWith(window.location.origin);
Jacob 2013/06/05 23:42:50 I think a more robust solution is: final AnchorEl
blois 2013/06/06 16:59:42 Done.
101 }
102 }
103
104
105 /**
106 * Standard tree sanitizer which validates a node tree against the provided
107 * validator and removes any nodes or attributes which are not allowed.
108 */
109 class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
110 final NodeValidator validator;
111 _ValidatingTreeSanitizer(this.validator) {}
112
113 void sanitizeTree(Node node) {
114 void walk(Node node) {
115 sanitizeNode(node);
116
117 var child = node.$dom_lastChild;
118 while (child != null) {
119 // Child may be removed during the walk.
120 var nextChild = child.previousNode;
121 walk(child);
122 child = nextChild;
123 }
124 }
125 walk(node);
126 }
127
128 void sanitizeNode(Node node) {
129 switch (node.nodeType) {
130 case Node.ELEMENT_NODE:
Jacob 2013/06/05 23:42:50 what if the element has a shadow DOM?
Jennifer Messerly 2013/06/06 05:55:53 good question. I think right now you cannot expose
blois 2013/06/06 16:59:42 One similar thing that I was just looking into was
131 Element element = node;
132 var attrs = element.attributes;
133 if (!validator.allowsElement(element)) {
134 element.remove();
135 break;
136 }
137
138 var isAttr = attrs['is'];
139 if (isAttr != null) {
140 if (!validator.allowsAttribute(element, 'is', isAttr)) {
141 element.remove();
142 break;
143 }
144 }
145
146 // TODO(blois): Need to be able to get all attributes, irrespective of
147 // XMLNS.
148 var keys = attrs.keys.toList();
149 for (var i = attrs.length - 1; i >= 0; --i) {
150 var name = keys[i];
151 if (!validator.allowsAttribute(element, name, attrs[name])) {
152 attrs.remove(name);
153 }
154 }
155 break;
156 case Node.COMMENT_NODE:
157 case Node.DOCUMENT_FRAGMENT_NODE:
158 case Node.TEXT_NODE:
159 case Node.CDATA_SECTION_NODE:
160 break;
161 default:
162 node.remove();
163 }
164 }
165 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698