// 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.

/// This tests HTML validation and sanitization, which is very important
/// for prevent XSS or other attacks. If you suppress this, or parts of it
/// please make it a critical bug and bring it to the attention of the
/// dart:html maintainers.
library node_validator_test;

import 'dart:html';
import 'dart:svg' as svg;

import 'package:expect/minitest.dart';

import 'utils.dart';

void validateHtml(String html, String reference, NodeValidator validator) {
  var a = document.body!.createFragment(html, validator: validator);
  var b = document.body!
      .createFragment(reference, treeSanitizer: NodeTreeSanitizer.trusted);

  // Prevent a false pass when both the html and the reference both get entirely
  // deleted, which is technically a match, but unlikely to be what we meant.
  if (reference != '') {
    expect(b.childNodes.length > 0, isTrue);
  }
  validateNodeTree(a, b);
}

class RecordingUriValidator implements UriPolicy {
  final List<String> calls = <String>[];

  bool allowsUri(String uri) {
    calls.add('$uri');
    return false;
  }

  void reset() {
    calls.clear();
  }
}

void testHtml(String name, NodeValidator validator, String html,
    [String? reference]) {
  test(name, () {
    if (reference == null) {
      reference = html;
    }

    validateHtml(html, reference!, validator);
  });
}

main() {
  group('DOM_sanitization', () {
    var validator = new NodeValidatorBuilder.common();

    testHtml('allows simple constructs', validator,
        '<div class="baz">something</div>');

    testHtml('blocks unknown attributes', validator,
        '<div foo="baz">something</div>', '<div>something</div>');

    testHtml('blocks custom element', validator,
        '<x-my-element>something</x-my-element>', '');

    testHtml('blocks custom is element', validator,
        '<div is="x-my-element">something</div>', '');

    testHtml(
        'blocks body elements', validator, '<body background="s"></body>', '');

    testHtml(
        'allows select elements',
        validator,
        '<select>'
            '<option>a</option>'
            '</select>');

    testHtml('blocks sequential script elements', validator,
        '<div><script></script><script></script></div>', '<div></div>');

    testHtml('blocks inline styles', validator,
        '<div style="background: red"></div>', '<div></div>');

    testHtml('blocks namespaced attributes', validator,
        '<div ns:foo="foo"></div>', '<div></div>');

    testHtml('blocks namespaced common attributes', validator,
        '<div ns:class="foo"></div>', '<div></div>');

    testHtml('blocks namespaced common elements', validator,
        '<ns:div></ns:div>', '');

    testHtml('allows CDATA sections', validator,
        '<span>![CDATA[ some text ]]></span>');

    testHtml('backquotes not removed', validator,
        '<img src="dice.png" alt="``onload=xss()" />');

    testHtml('0x3000 not removed', validator,
        '<a href="&#x3000;javascript:alert(1)">CLICKME</a>');

    test('sanitizes template contents', () {
      if (!TemplateElement.supported) return;

      var html = '<template>'
          '<div></div>'
          '<script></script>'
          '<img src="http://example.com/foo"/>'
          '</template>';

      var fragment = document.body!.createFragment(html, validator: validator);
      var template = fragment.nodes.single as TemplateElement;

      var expectedContent = document.body!.createFragment('<div></div>'
          '<img/>');

      validateNodeTree(template.content, expectedContent);
    });

    test("appendHtml is sanitized", () {
      var html = '<body background="s"></body><div></div>';
      document.body!.appendHtml('<div id="stuff"></div>');
      var stuff = document.querySelector("#stuff")!;
      stuff.appendHtml(html);
      expect(stuff.childNodes.length, 1);
      stuff.remove();
    });

    test("documentFragment.appendHtml is sanitized", () {
      var html = '<div id="things></div>';
      var fragment = new DocumentFragment.html(html);
      fragment.appendHtml('<div id="bad"><script></script></div>');
      expect(fragment.childNodes.length, 1);
      var child = fragment.childNodes[0] as Element;
      expect(child.id, "bad");
      expect(child.childNodes.length, 0);
    });

    testHtml(
        "sanitizes embed",
        validator,
        "<div><embed src='' type='application/x-shockwave-flash'></embed></div>",
        "<div></div>");
  });

  group('URI_sanitization', () {
    var recorder = new RecordingUriValidator();
    var validator = new NodeValidatorBuilder()..allowHtml5(uriPolicy: recorder);

    checkUriPolicyCalls(String name, String html, String reference,
        List<String> expectedCalls) {
      test(name, () {
        recorder.reset();

        validateHtml(html, reference, validator);
        expect(recorder.calls, expectedCalls);
      });
    }

    checkUriPolicyCalls('a::href', '<a href="s"></a>', '<a></a>', ['s']);

    checkUriPolicyCalls(
        'area::href', '<area href="s"></area>', '<area></area>', ['s']);

    checkUriPolicyCalls(
        'blockquote::cite',
        '<blockquote cite="s"></blockquote>',
        '<blockquote></blockquote>',
        ['s']);
    checkUriPolicyCalls(
        'command::icon', '<command icon="s"/>', '<command/>', ['s']);
    checkUriPolicyCalls('img::src', '<img src="s"/>', '<img/>', ['s']);
    checkUriPolicyCalls('input::src', '<input src="s"/>', '<input/>', ['s']);
    checkUriPolicyCalls(
        'ins::cite', '<ins cite="s"></ins>', '<ins></ins>', ['s']);
    checkUriPolicyCalls('q::cite', '<q cite="s"></q>', '<q></q>', ['s']);
    checkUriPolicyCalls(
        'video::poster', '<video poster="s"/>', '<video/>', ['s']);
  });

  group('allowNavigation', () {
    var validator = new NodeValidatorBuilder()..allowNavigation();

    testHtml('allows anchor tags', validator, '<a href="#foo">foo</a>');

    testHtml('allows form elements', validator,
        '<form method="post" action="/foo"></form>');

    testHtml('disallows script navigation', validator,
        '<a href="javascript:foo = 1">foo</a>', '<a>foo</a>');

    testHtml('disallows cross-site navigation', validator,
        '<a href="http://example.com">example.com</a>', '<a>example.com</a>');

    testHtml('blocks other elements', validator,
        '<a href="#foo"><b>foo</b></a>', '<a href="#foo"></a>');

    testHtml('blocks tag extension', validator, '<a is="x-foo"></a>', '');
  });

  group('allowImages', () {
    var validator = new NodeValidatorBuilder()..allowImages();

    testHtml('allows images', validator,
        '<img src="/foo.jpg" alt="something" width="100" height="100"/>');

    testHtml('blocks onerror', validator,
        '<img src="/foo.jpg" onerror="something"/>', '<img src="/foo.jpg"/>');

    testHtml('enforces same-origin', validator,
        '<img src="http://example.com/foo.jpg"/>', '<img/>');
  });

  group('allowCustomElement', () {
    var validator = new NodeValidatorBuilder()
      ..allowCustomElement('x-foo', attributes: ['bar'], uriAttributes: ['baz'])
      ..allowHtml5();

    testHtml('allows custom elements', validator,
        '<x-foo bar="something" baz="/foo.jpg"></x-foo>');

    testHtml('validates custom tag URIs', validator,
        '<x-foo baz="http://example.com/foo.jpg"></x-foo>', '<x-foo></x-foo>');

    testHtml('blocks type extensions', validator, '<div is="x-foo"></div>', '');

    testHtml('blocks tags on non-matching elements', validator,
        '<div bar="foo"></div>', '<div></div>');
  });

  group('identify Uri attributes listed as attributes', () {
    var validator = new NodeValidatorBuilder()
      ..allowElement('a', attributes: ['href']);

    testHtml(
        'reject different-origin link',
        validator,
        '<a href="http://www.google.com/foo">Google-Foo</a>',
        '<a>Google-Foo</a>');
  });

  group('allowTagExtension', () {
    var validator = new NodeValidatorBuilder()
      ..allowTagExtension('x-foo', 'div',
          attributes: ['bar'], uriAttributes: ['baz'])
      ..allowHtml5();

    testHtml('allows tag extensions', validator,
        '<div is="x-foo" bar="something" baz="/foo.jpg"></div>');

    testHtml('blocks custom elements', validator, '<x-foo></x-foo>', '');

    testHtml(
        'validates tag extension URIs',
        validator,
        '<div is="x-foo" baz="http://example.com/foo.jpg"></div>',
        '<div is="x-foo"></div>');

    testHtml('blocks tags on non-matching elements', validator,
        '<div bar="foo"></div>', '<div></div>');

    testHtml('blocks non-matching tags', validator,
        '<span is="x-foo">something</span>', '');

    validator = new NodeValidatorBuilder()
      ..allowTagExtension('x-foo', 'div',
          attributes: ['bar'], uriAttributes: ['baz'])
      ..allowTagExtension('x-else', 'div');

    testHtml('blocks tags on non-matching custom elements', validator,
        '<div bar="foo" is="x-else"></div>', '<div is="x-else"></div>');
  });

  group('allowTemplating', () {
    var validator = new NodeValidatorBuilder()
      ..allowTemplating()
      ..allowHtml5();

    testHtml(
        'allows templates', validator, '<template bind="{{a}}"></template>');

    testHtml('allows template attributes', validator,
        '<template bind="{{a}}" ref="foo" repeat="{{}}" if="{{}}" syntax="foo"></template>');

    testHtml('allows template attribute', validator,
        '<div template repeat="{{}}"></div>');

    testHtml('blocks illegal template attribute', validator,
        '<div template="foo" repeat="{{}}"></div>', '<div></div>');
  });

  group('allowSvg', () {
    var validator = new NodeValidatorBuilder()
      ..allowSvg()
      ..allowTextElements();

    testHtml(
        'allows basic SVG',
        validator,
        '<svg xmlns="http://www.w3.org/2000/svg'
            'xmlns:xlink="http://www.w3.org/1999/xlink">'
            '<image xlink:href="foo" data-foo="bar"/>'
            '</svg>');

    testHtml(
        'blocks script elements',
        validator,
        '<svg xmlns="http://www.w3.org/2000/svg>'
            '<script></script>'
            '</svg>',
        '');

    testHtml(
        'blocks script elements but allows other',
        validator,
        '<svg xmlns="http://www.w3.org/2000/svg>'
            '<script></script><ellipse cx="200" cy="80" rx="100" ry="50"></ellipse>'
            '</svg>',
        '<svg xmlns="http://www.w3.org/2000/svg>'
            '<ellipse cx="200" cy="80" rx="100" ry="50"></ellipse>'
            '</svg>');

    testHtml(
        'blocks script handlers',
        validator,
        '<svg xmlns="http://www.w3.org/2000/svg'
            'xmlns:xlink="http://www.w3.org/1999/xlink">'
            '<image xlink:href="foo" onerror="something"/>'
            '</svg>',
        '<svg xmlns="http://www.w3.org/2000/svg'
            'xmlns:xlink="http://www.w3.org/1999/xlink">'
            '<image xlink:href="foo"/>'
            '</svg>');

    testHtml(
        'blocks foreignObject content',
        validator,
        '<svg xmlns="http://www.w3.org/2000/svg">'
            '<foreignobject width="100" height="150">'
            '<body xmlns="http://www.w3.org/1999/xhtml">'
            '<div>Some content</div>'
            '</body>'
            '</foreignobject>'
            '<b>42</b>'
            '</svg>',
        '<svg xmlns="http://www.w3.org/2000/svg">'
            '<b>42</b>'
            '</svg>');
  });

  group('allowInlineStyles', () {
    var validator = new NodeValidatorBuilder()
      ..allowTextElements()
      ..allowInlineStyles();

    testHtml('allows inline styles', validator,
        '<span style="background-color:red">text</span>');

    testHtml('blocks other attributes', validator,
        '<span class="red-span"></span>', '<span></span>');

    validator = new NodeValidatorBuilder()
      ..allowTextElements()
      ..allowInlineStyles(tagName: 'span');

    testHtml('scoped allows inline styles on spans', validator,
        '<span style="background-color:red">text</span>');

    testHtml('scoped blocks inline styles on LIs', validator,
        '<li style="background-color:red">text</li>', '<li>text</li>');
  });

  group('throws', () {
    var validator = new NodeValidator.throws(new NodeValidatorBuilder.common());

    var validationError = throwsArgumentError;

    test('does not throw on valid syntax', () {
      expect(() {
        document.body!.createFragment('<div></div>', validator: validator);
      }, returnsNormally);
    });

    test('throws on invalid elements', () {
      expect(() {
        document.body!.createFragment('<foo></foo>', validator: validator);
      }, validationError);
    });

    test('throws on invalid attributes', () {
      expect(() {
        document.body!
            .createFragment('<div foo="bar"></div>', validator: validator);
      }, validationError);
    });

    test('throws on invalid attribute values', () {
      expect(() {
        document.body!.createFragment('<img src="http://example.com/foo.jpg"/>',
            validator: validator);
      }, validationError);
    });
  });

  group('svg', () {
    test('parsing', () {
      var svgText = '<svg xmlns="http://www.w3.org/2000/svg'
          'xmlns:xlink="http://www.w3.org/1999/xlink">'
          '<image xlink:href="foo" data-foo="bar"/>'
          '</svg>';

      var fragment = new DocumentFragment.svg(svgText);
      var element = fragment.nodes.first as Element;
      expect(element is svg.SvgSvgElement, isTrue);
      expect(element.children[0] is svg.ImageElement, isTrue);
    });
  });

  group('dom_clobbering', () {
    var validator = new NodeValidatorBuilder.common();

    testHtml(
        'DOM clobbering of attributes with single node',
        validator,
        "<form id='single_node_clobbering' onmouseover='alert(1)'><input name='attributes'>",
        "");

    testHtml(
        'DOM clobbering of attributes with multiple nodes',
        validator,
        "<form onmouseover='alert(1)'><input name='attributes'>"
            "<input name='attributes'>",
        "");

    testHtml('DOM clobbering of lastChild', validator,
        "<form><input name='lastChild'><input onmouseover='alert(1)'>", "");

    testHtml(
        'DOM clobbering of both children and lastChild',
        validator,
        "<form><input name='lastChild'><input name='children'>"
            "<input id='children'><input onmouseover='alert(1)'>",
        "");

    testHtml(
        'DOM clobbering of both children and lastChild, different order',
        validator,
        "<form><input name='children'><input name='children'>"
            "<input id='children' name='lastChild'>"
            "<input id='bad' onmouseover='alert(1)'>",
        "");

    test('tagName makes containing form invalid', () {
      var fragment = document.body!.createFragment(
          "<form onmouseover='alert(2)'><input name='tagName'>",
          validator: validator);
      var form = fragment.lastChild as FormElement?;
      // If the tagName was clobbered, the sanitizer should have removed
      // the whole thing and form is null.
      // If the tagName was not clobbered, then there will be content,
      // but the tagName should be the normal value. IE11 has started
      // doing this.
      if (form != null) {
        expect(form.tagName, 'FORM');
      }
    });

    test('tagName without mouseover', () {
      var fragment = document.body!
          .createFragment("<form><input name='tagName'>", validator: validator);
      var form = fragment.lastChild as FormElement?;
      // If the tagName was clobbered, the sanitizer should have removed
      // the whole thing and form is null.
      // If the tagName was not clobbered, then there will be content,
      // but the tagName should be the normal value.
      if (form != null) {
        expect(form.tagName, 'FORM');
      }
    });
  });
}
