Bug 1779184 - Handle funky attributes in Sanitizer. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D153956
This commit is contained in:
Tom Schuster 2022-08-12 10:33:27 +00:00
Родитель 0c4ace9581
Коммит f713d72cd4
3 изменённых файлов: 62 добавлений и 63 удалений

Просмотреть файл

@ -14,12 +14,14 @@
#include "mozilla/StyleSheetInlines.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/css/Rule.h"
#include "mozilla/dom/SanitizerBinding.h"
#include "mozilla/dom/CSSRuleList.h"
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/ShadowIncludingTreeIterator.h"
#include "mozilla/dom/HTMLFormElement.h"
#include "mozilla/dom/HTMLTemplateElement.h"
#include "mozilla/dom/HTMLUnknownElement.h"
#include "mozilla/dom/Link.h"
#include "mozilla/dom/SanitizerBinding.h"
#include "mozilla/dom/ShadowIncludingTreeIterator.h"
#include "mozilla/dom/SRIMetadata.h"
#include "mozilla/NullPrincipal.h"
#include "nsAtom.h"
@ -1858,7 +1860,8 @@ void nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement,
RefPtr<nsAtom> attrLocal = attrName->LocalName();
if (mIsForSanitizerAPI) {
if (MustDropAttribute(aElement, attrNs, attrLocal)) {
if (MustDropAttribute(aElement, attrNs, attrLocal) ||
MustDropFunkyAttribute(aElement, attrNs, attrLocal)) {
aElement->UnsetAttr(kNameSpaceID_None, attrLocal, false);
if (mLogRemovals) {
LogMessage("Removed unsafe attribute.", aElement->OwnerDoc(),
@ -2045,6 +2048,60 @@ bool nsTreeSanitizer::MustDropAttribute(Element* aElement,
return false;
}
// https://wicg.github.io/sanitizer-api/#handle-funky-elements
bool nsTreeSanitizer::MustDropFunkyAttribute(Element* aElement,
int32_t aAttrNamespace,
nsAtom* aAttrLocalName) {
// Step 1. If elements element interface is HTMLTemplateElement:
// Note: This step is implemented in the main loop of SanitizeChildren.
// Step 2. If elements element interface has a HTMLHyperlinkElementUtils
// mixin, and if elements protocol property is "javascript:":
// TODO(https://github.com/WICG/sanitizer-api/issues/168)
if (aAttrLocalName == nsGkAtoms::href) {
if (nsCOMPtr<Link> link = do_QueryInterface(aElement)) {
nsCOMPtr<nsIURI> uri = link->GetURI();
if (uri && uri->SchemeIs("javascript")) {
// Step 2.1. Remove the `href` attribute from element.
return true;
}
}
}
// Step 3. if elements element interface is HTMLFormElement, and if elements
// action attribute is a URL with "javascript:" protocol:
if (auto* form = HTMLFormElement::FromNode(aElement)) {
if (aAttrNamespace == kNameSpaceID_None &&
aAttrLocalName == nsGkAtoms::action) {
nsCOMPtr<nsIURI> uri;
form->GetURIAttr(aAttrLocalName, nullptr, getter_AddRefs(uri));
if (uri && uri->SchemeIs("javascript")) {
// Step 3.1 Remove the `action` attribute from element.
return true;
}
}
}
// Step 4. if elements element interface is HTMLInputElement or
// HTMLButtonElement, and if elements formaction attribute is a [URL] with
// javascript: protocol
if (aElement->IsAnyOfHTMLElements(nsGkAtoms::input, nsGkAtoms::button) &&
aAttrNamespace == kNameSpaceID_None &&
aAttrLocalName == nsGkAtoms::formaction) {
// XXX nsGenericHTMLFormControlElementWithState::GetFormAction falls back to
// the document URI.
nsGenericHTMLElement* el = nsGenericHTMLElement::FromNode(aElement);
nsCOMPtr<nsIURI> uri;
el->GetURIAttr(aAttrLocalName, nullptr, getter_AddRefs(uri));
if (uri && uri->SchemeIs("javascript")) {
// Step 4.1 Remove the `formaction` attribute from element.
return true;
}
}
return false;
}
bool nsTreeSanitizer::SanitizeURL(mozilla::dom::Element* aElement,
int32_t aNamespace, nsAtom* aLocalName,
bool aFragmentsOnly) {

Просмотреть файл

@ -205,6 +205,8 @@ class nsTreeSanitizer {
// Currently only used for the Sanitizer API.
bool MustDropAttribute(mozilla::dom::Element* aElement,
int32_t aAttrNamespace, nsAtom* aAttrLocalName);
bool MustDropFunkyAttribute(mozilla::dom::Element* aElement,
int32_t aAttrNamespace, nsAtom* aAttrLocalName);
/**
* Remove the named URL attribute from the element if the URL fails a

Просмотреть файл

@ -3,71 +3,11 @@
[SanitizerAPI with config: plaintext, sanitize from document function for <body>]
expected: FAIL
[SanitizerAPI with config: HTMLAnchorElement with javascript protocal, sanitize from document function for <body>]
expected: FAIL
[SanitizerAPI with config: HTMLAnchorElement with javascript protocal start with space, sanitize from document function for <body>]
expected: FAIL
[SanitizerAPI with config: HTMLAreaElement with javascript protocal, sanitize from document function for <body>]
expected: FAIL
[SanitizerAPI with config: HTMLAreaElement with javascript protocal start with space, sanitize from document function for <body>]
expected: FAIL
[SanitizerAPI with config: HTMLFormElement with javascript action, sanitize from document function for <body>]
expected: FAIL
[SanitizerAPI with config: HTMLFormElement with javascript action start with space, sanitize from document function for <body>]
expected: FAIL
[SanitizerAPI with config: HTMLInputElement with javascript formaction, sanitize from document function for <body>]
expected: FAIL
[SanitizerAPI with config: HTMLInputElement with javascript formaction start with space, sanitize from document function for <body>]
expected: FAIL
[SanitizerAPI with config: HTMLButtonElement with javascript formaction, sanitize from document function for <body>]
expected: FAIL
[SanitizerAPI with config: HTMLButtonElement with javascript formaction start with space, sanitize from document function for <body>]
expected: FAIL
[SanitizerAPI with config: allowAttributes unknown attributes and with allowUnknownMarkup, sanitize from document function for <body>]
expected: FAIL
[SanitizerAPI with config: plaintext, sanitize from document fragment function for <template>]
expected: FAIL
[SanitizerAPI with config: HTMLAnchorElement with javascript protocal, sanitize from document fragment function for <template>]
expected: FAIL
[SanitizerAPI with config: HTMLAnchorElement with javascript protocal start with space, sanitize from document fragment function for <template>]
expected: FAIL
[SanitizerAPI with config: HTMLAreaElement with javascript protocal, sanitize from document fragment function for <template>]
expected: FAIL
[SanitizerAPI with config: HTMLAreaElement with javascript protocal start with space, sanitize from document fragment function for <template>]
expected: FAIL
[SanitizerAPI with config: HTMLFormElement with javascript action, sanitize from document fragment function for <template>]
expected: FAIL
[SanitizerAPI with config: HTMLFormElement with javascript action start with space, sanitize from document fragment function for <template>]
expected: FAIL
[SanitizerAPI with config: HTMLInputElement with javascript formaction, sanitize from document fragment function for <template>]
expected: FAIL
[SanitizerAPI with config: HTMLInputElement with javascript formaction start with space, sanitize from document fragment function for <template>]
expected: FAIL
[SanitizerAPI with config: HTMLButtonElement with javascript formaction, sanitize from document fragment function for <template>]
expected: FAIL
[SanitizerAPI with config: HTMLButtonElement with javascript formaction start with space, sanitize from document fragment function for <template>]
expected: FAIL
[SanitizerAPI with config: allowAttributes unknown attributes and with allowUnknownMarkup, sanitize from document fragment function for <template>]
expected: FAIL