| Index: tools/dom/src/NodeValidatorBuilder.dart
|
| diff --git a/tools/dom/src/NodeValidatorBuilder.dart b/tools/dom/src/NodeValidatorBuilder.dart
|
| deleted file mode 100644
|
| index c5f0c80542a90835393044215c1d36965ea7bdbf..0000000000000000000000000000000000000000
|
| --- a/tools/dom/src/NodeValidatorBuilder.dart
|
| +++ /dev/null
|
| @@ -1,453 +0,0 @@
|
| -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -part of dart.dom.html;
|
| -
|
| -
|
| -/**
|
| - * Class which helps construct standard node validation policies.
|
| - *
|
| - * By default this will not accept anything, but the 'allow*' functions can be
|
| - * used to expand what types of elements or attributes are allowed.
|
| - *
|
| - * All allow functions are additive- elements will be accepted if they are
|
| - * accepted by any specific rule.
|
| - *
|
| - * It is important to remember that sanitization is not just intended to prevent
|
| - * cross-site scripting attacks, but also to prevent information from being
|
| - * displayed in unexpected ways. For example something displaying basic
|
| - * formatted text may not expect `<video>` tags to appear. In this case an
|
| - * empty NodeValidatorBuilder with just [allowTextElements] might be
|
| - * appropriate.
|
| - */
|
| -class NodeValidatorBuilder implements NodeValidator {
|
| -
|
| - final List<NodeValidator> _validators = <NodeValidator>[];
|
| -
|
| - NodeValidatorBuilder() {
|
| - }
|
| -
|
| - /**
|
| - * Creates a new NodeValidatorBuilder which accepts common constructs.
|
| - *
|
| - * By default this will accept HTML5 elements and attributes with the default
|
| - * [UriPolicy] and templating elements.
|
| - *
|
| - * Notable syntax which is filtered:
|
| - *
|
| - * * Only known-good HTML5 elements and attributes are allowed.
|
| - * * All URLs must be same-origin, use [allowNavigation] and [allowImages] to
|
| - * specify additional URI policies.
|
| - * * Inline-styles are not allowed.
|
| - * * Custom element tags are disallowed, use [allowCustomElement].
|
| - * * Custom tags extensions are disallowed, use [allowTagExtension].
|
| - * * SVG Elements are not allowed, use [allowSvg].
|
| - *
|
| - * For scenarios where the HTML should only contain formatted text
|
| - * [allowTextElements] is more appropriate.
|
| - *
|
| - * Use [allowSvg] to allow SVG elements.
|
| - */
|
| - NodeValidatorBuilder.common() {
|
| - allowHtml5();
|
| - allowTemplating();
|
| - }
|
| -
|
| - /**
|
| - * Allows navigation elements- Form and Anchor tags, along with common
|
| - * attributes.
|
| - *
|
| - * The UriPolicy can be used to restrict the locations the navigation elements
|
| - * are allowed to direct to. By default this will use the default [UriPolicy].
|
| - */
|
| - void allowNavigation([UriPolicy uriPolicy]) {
|
| - if (uriPolicy == null) {
|
| - uriPolicy = new UriPolicy();
|
| - }
|
| - add(new _SimpleNodeValidator.allowNavigation(uriPolicy));
|
| - }
|
| -
|
| - /**
|
| - * Allows image elements.
|
| - *
|
| - * The UriPolicy can be used to restrict the locations the images may be
|
| - * loaded from. By default this will use the default [UriPolicy].
|
| - */
|
| - void allowImages([UriPolicy uriPolicy]) {
|
| - if (uriPolicy == null) {
|
| - uriPolicy = new UriPolicy();
|
| - }
|
| - add(new _SimpleNodeValidator.allowImages(uriPolicy));
|
| - }
|
| -
|
| - /**
|
| - * Allow basic text elements.
|
| - *
|
| - * This allows a subset of HTML5 elements, specifically just these tags and
|
| - * no attributes.
|
| - *
|
| - * * B
|
| - * * BLOCKQUOTE
|
| - * * BR
|
| - * * EM
|
| - * * H1
|
| - * * H2
|
| - * * H3
|
| - * * H4
|
| - * * H5
|
| - * * H6
|
| - * * HR
|
| - * * I
|
| - * * LI
|
| - * * OL
|
| - * * P
|
| - * * SPAN
|
| - * * UL
|
| - */
|
| - void allowTextElements() {
|
| - add(new _SimpleNodeValidator.allowTextElements());
|
| - }
|
| -
|
| - /**
|
| - * Allow common safe HTML5 elements and attributes.
|
| - *
|
| - * This list is based off of the Caja whitelists at:
|
| - * https://code.google.com/p/google-caja/wiki/CajaWhitelists.
|
| - *
|
| - * Common things which are not allowed are script elements, style attributes
|
| - * and any script handlers.
|
| - */
|
| - void allowHtml5({UriPolicy uriPolicy}) {
|
| - add(new _Html5NodeValidator(uriPolicy: uriPolicy));
|
| - }
|
| -
|
| - /**
|
| - * Allow SVG elements and attributes except for known bad ones.
|
| - */
|
| - void allowSvg() {
|
| - add(new _SvgNodeValidator());
|
| - }
|
| -
|
| - /**
|
| - * Allow custom elements with the specified tag name and specified attributes.
|
| - *
|
| - * This will allow the elements as custom tags (such as <x-foo></x-foo>),
|
| - * but will not allow tag extensions. Use [allowTagExtension] to allow
|
| - * tag extensions.
|
| - */
|
| - void allowCustomElement(String tagName,
|
| - {UriPolicy uriPolicy,
|
| - Iterable<String> attributes,
|
| - Iterable<String> uriAttributes}) {
|
| -
|
| - var tagNameUpper = tagName.toUpperCase();
|
| - var attrs;
|
| - if (attributes != null) {
|
| - attrs =
|
| - attributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
|
| - }
|
| - var uriAttrs;
|
| - if (uriAttributes != null) {
|
| - uriAttrs =
|
| - uriAttributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
|
| - }
|
| - if (uriPolicy == null) {
|
| - uriPolicy = new UriPolicy();
|
| - }
|
| -
|
| - add(new _CustomElementNodeValidator(
|
| - uriPolicy,
|
| - [tagNameUpper],
|
| - attrs,
|
| - uriAttrs,
|
| - false,
|
| - true));
|
| - }
|
| -
|
| - /**
|
| - * Allow custom tag extensions with the specified type name and specified
|
| - * attributes.
|
| - *
|
| - * This will allow tag extensions (such as <div is="x-foo"></div>),
|
| - * but will not allow custom tags. Use [allowCustomElement] to allow
|
| - * custom tags.
|
| - */
|
| - void allowTagExtension(String tagName, String baseName,
|
| - {UriPolicy uriPolicy,
|
| - Iterable<String> attributes,
|
| - Iterable<String> uriAttributes}) {
|
| -
|
| - var baseNameUpper = baseName.toUpperCase();
|
| - var tagNameUpper = tagName.toUpperCase();
|
| - var attrs;
|
| - if (attributes != null) {
|
| - attrs =
|
| - attributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
|
| - }
|
| - var uriAttrs;
|
| - if (uriAttributes != null) {
|
| - uriAttrs =
|
| - uriAttributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
|
| - }
|
| - if (uriPolicy == null) {
|
| - uriPolicy = new UriPolicy();
|
| - }
|
| -
|
| - add(new _CustomElementNodeValidator(
|
| - uriPolicy,
|
| - [tagNameUpper, baseNameUpper],
|
| - attrs,
|
| - uriAttrs,
|
| - true,
|
| - false));
|
| - }
|
| -
|
| - void allowElement(String tagName, {UriPolicy uriPolicy,
|
| - Iterable<String> attributes,
|
| - Iterable<String> uriAttributes}) {
|
| -
|
| - allowCustomElement(tagName, uriPolicy: uriPolicy,
|
| - attributes: attributes,
|
| - uriAttributes: uriAttributes);
|
| - }
|
| -
|
| - /**
|
| - * Allow templating elements (such as <template> and template-related
|
| - * attributes.
|
| - *
|
| - * This still requires other validators to allow regular attributes to be
|
| - * bound (such as [allowHtml5]).
|
| - */
|
| - void allowTemplating() {
|
| - add(new _TemplatingNodeValidator());
|
| - }
|
| -
|
| - /**
|
| - * Add an additional validator to the current list of validators.
|
| - *
|
| - * Elements and attributes will be accepted if they are accepted by any
|
| - * validators.
|
| - */
|
| - void add(NodeValidator validator) {
|
| - _validators.add(validator);
|
| - }
|
| -
|
| - bool allowsElement(Element element) {
|
| - return _validators.any((v) => v.allowsElement(element));
|
| - }
|
| -
|
| - bool allowsAttribute(Element element, String attributeName, String value) {
|
| - return _validators.any(
|
| - (v) => v.allowsAttribute(element, attributeName, value));
|
| - }
|
| -}
|
| -
|
| -class _SimpleNodeValidator implements NodeValidator {
|
| - final Set<String> allowedElements;
|
| - final Set<String> allowedAttributes;
|
| - final Set<String> allowedUriAttributes;
|
| - final UriPolicy uriPolicy;
|
| -
|
| - factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
|
| - return new _SimpleNodeValidator(uriPolicy,
|
| - allowedElements: [
|
| - 'A',
|
| - 'FORM'],
|
| - allowedAttributes: [
|
| - 'A::accesskey',
|
| - 'A::coords',
|
| - 'A::hreflang',
|
| - 'A::name',
|
| - 'A::shape',
|
| - 'A::tabindex',
|
| - 'A::target',
|
| - 'A::type',
|
| - 'FORM::accept',
|
| - 'FORM::autocomplete',
|
| - 'FORM::enctype',
|
| - 'FORM::method',
|
| - 'FORM::name',
|
| - 'FORM::novalidate',
|
| - 'FORM::target',
|
| - ],
|
| - allowedUriAttributes: [
|
| - 'A::href',
|
| - 'FORM::action',
|
| - ]);
|
| - }
|
| -
|
| - factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
|
| - return new _SimpleNodeValidator(uriPolicy,
|
| - allowedElements: [
|
| - 'IMG'
|
| - ],
|
| - allowedAttributes: [
|
| - 'IMG::align',
|
| - 'IMG::alt',
|
| - 'IMG::border',
|
| - 'IMG::height',
|
| - 'IMG::hspace',
|
| - 'IMG::ismap',
|
| - 'IMG::name',
|
| - 'IMG::usemap',
|
| - 'IMG::vspace',
|
| - 'IMG::width',
|
| - ],
|
| - allowedUriAttributes: [
|
| - 'IMG::src',
|
| - ]);
|
| - }
|
| -
|
| - factory _SimpleNodeValidator.allowTextElements() {
|
| - return new _SimpleNodeValidator(null,
|
| - allowedElements: [
|
| - 'B',
|
| - 'BLOCKQUOTE',
|
| - 'BR',
|
| - 'EM',
|
| - 'H1',
|
| - 'H2',
|
| - 'H3',
|
| - 'H4',
|
| - 'H5',
|
| - 'H6',
|
| - 'HR',
|
| - 'I',
|
| - 'LI',
|
| - 'OL',
|
| - 'P',
|
| - 'SPAN',
|
| - 'UL',
|
| - ]);
|
| - }
|
| -
|
| - /**
|
| - * Elements must be uppercased tag names. For example `'IMG'`.
|
| - * Attributes must be uppercased tag name followed by :: followed by
|
| - * lowercase attribute name. For example `'IMG:src'`.
|
| - */
|
| - _SimpleNodeValidator(this.uriPolicy,
|
| - {Iterable<String> allowedElements, Iterable<String> allowedAttributes,
|
| - Iterable<String> allowedUriAttributes}):
|
| - this.allowedElements = allowedElements != null ?
|
| - new Set.from(allowedElements) : new Set(),
|
| - this.allowedAttributes = allowedAttributes != null ?
|
| - new Set.from(allowedAttributes) : new Set(),
|
| - this.allowedUriAttributes = allowedUriAttributes != null ?
|
| - new Set.from(allowedUriAttributes) : new Set();
|
| -
|
| - bool allowsElement(Element element) {
|
| - return allowedElements.contains(element.tagName);
|
| - }
|
| -
|
| - bool allowsAttribute(Element element, String attributeName, String value) {
|
| - var tagName = element.tagName;
|
| - if (allowedUriAttributes.contains('$tagName::$attributeName')) {
|
| - return uriPolicy.allowsUri(value);
|
| - } else if (allowedUriAttributes.contains('*::$attributeName')) {
|
| - return uriPolicy.allowsUri(value);
|
| - } else if (allowedAttributes.contains('$tagName::$attributeName')) {
|
| - return true;
|
| - } else if (allowedAttributes.contains('*::$attributeName')) {
|
| - return true;
|
| - } else if (allowedAttributes.contains('$tagName::*')) {
|
| - return true;
|
| - } else if (allowedAttributes.contains('*::*')) {
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -class _CustomElementNodeValidator extends _SimpleNodeValidator {
|
| - final bool allowTypeExtension;
|
| - final bool allowCustomTag;
|
| -
|
| - _CustomElementNodeValidator(UriPolicy uriPolicy,
|
| - Iterable<String> allowedElements,
|
| - Iterable<String> allowedAttributes,
|
| - Iterable<String> allowedUriAttributes,
|
| - bool allowTypeExtension,
|
| - bool allowCustomTag):
|
| -
|
| - super(uriPolicy,
|
| - allowedElements: allowedElements,
|
| - allowedAttributes: allowedAttributes,
|
| - allowedUriAttributes: allowedUriAttributes),
|
| - this.allowTypeExtension = allowTypeExtension == true,
|
| - this.allowCustomTag = allowCustomTag == true;
|
| -
|
| - bool allowsElement(Element element) {
|
| - if (allowTypeExtension) {
|
| - var isAttr = element.attributes['is'];
|
| - if (isAttr != null) {
|
| - return allowedElements.contains(isAttr.toUpperCase()) &&
|
| - allowedElements.contains(element.tagName);
|
| - }
|
| - }
|
| - return allowCustomTag && allowedElements.contains(element.tagName);
|
| - }
|
| -
|
| - bool allowsAttribute(Element element, String attributeName, String value) {
|
| - if (allowsElement(element)) {
|
| - if (allowTypeExtension && attributeName == 'is' &&
|
| - allowedElements.contains(value.toUpperCase())) {
|
| - return true;
|
| - }
|
| - return super.allowsAttribute(element, attributeName, value);
|
| - }
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -class _TemplatingNodeValidator extends _SimpleNodeValidator {
|
| - static const _TEMPLATE_ATTRS =
|
| - const <String>['bind', 'if', 'ref', 'repeat', 'syntax'];
|
| -
|
| - final Set<String> _templateAttrs;
|
| -
|
| - _TemplatingNodeValidator():
|
| - super(null,
|
| - allowedElements: [
|
| - 'TEMPLATE'
|
| - ],
|
| - allowedAttributes: _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')),
|
| - _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS) {
|
| - }
|
| -
|
| - bool allowsAttribute(Element element, String attributeName, String value) {
|
| - if (super.allowsAttribute(element, attributeName, value)) {
|
| - return true;
|
| - }
|
| -
|
| - if (attributeName == 'template' && value == "") {
|
| - return true;
|
| - }
|
| -
|
| - if (element.attributes['template'] == "" ) {
|
| - return _templateAttrs.contains(attributeName);
|
| - }
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -
|
| -class _SvgNodeValidator implements NodeValidator {
|
| - bool allowsElement(Element element) {
|
| - if (element is svg.ScriptElement) {
|
| - return false;
|
| - }
|
| - if (element is svg.SvgElement) {
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - bool allowsAttribute(Element element, String attributeName, String value) {
|
| - if (attributeName == 'is' || attributeName.startsWith('on')) {
|
| - return false;
|
| - }
|
| - return allowsElement(element);
|
| - }
|
| -}
|
|
|