From 7e0d94a048cb7a73af5638f46bdb65794bcc4292 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Wed, 5 Oct 2022 17:42:46 -0500 Subject: [DOM:Base] Use the sanitizer to restrict href in svg:use to fragment-only URLs --- dom/base/nsTreeSanitizer.cpp | 18 +++++++++++++++--- dom/base/nsTreeSanitizer.h | 4 +++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/dom/base/nsTreeSanitizer.cpp b/dom/base/nsTreeSanitizer.cpp index 39c2408b7..970e4386b 100644 --- a/dom/base/nsTreeSanitizer.cpp +++ b/dom/base/nsTreeSanitizer.cpp @@ -1185,7 +1185,8 @@ nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement, continue; } if (IsURL(aURLs, attrLocal)) { - if (SanitizeURL(aElement, attrNs, attrLocal)) { + bool fragmentOnly = aElement->IsSVGElement(nsGkAtoms::use); + if (SanitizeURL(aElement, attrNs, attrLocal, fragmentOnly)) { // in case the attribute removal shuffled the attribute order, start // the loop again. --ac; @@ -1239,7 +1240,8 @@ nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement, // else not allowed } else if (aAllowXLink && kNameSpaceID_XLink == attrNs) { if (nsGkAtoms::href == attrLocal) { - if (SanitizeURL(aElement, attrNs, attrLocal)) { + bool fragmentOnly = aElement->IsSVGElement(nsGkAtoms::use); + if (SanitizeURL(aElement, attrNs, attrLocal, fragmentOnly)) { // in case the attribute removal shuffled the attribute order, start // the loop again. --ac; @@ -1273,7 +1275,8 @@ nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement, bool nsTreeSanitizer::SanitizeURL(mozilla::dom::Element* aElement, int32_t aNamespace, - nsIAtom* aLocalName) + nsIAtom* aLocalName, + bool aFragmentOnly) { nsAutoString value; aElement->GetAttr(aNamespace, aLocalName, value); @@ -1282,6 +1285,15 @@ nsTreeSanitizer::SanitizeURL(mozilla::dom::Element* aElement, static const char* kWhitespace = "\n\r\t\b"; const nsAString& v = nsContentUtils::TrimCharsInSet(kWhitespace, value); + // Fragment-only url cannot be harmful. + if (!v.IsEmpty() && v.First() == u'#') { + return false; + } + // if we allow only same-document fragment URLs, stop and remove here + if (aFragmentOnly) { + aElement->UnsetAttr(aNamespace, aLocalName, false); + return true; + } nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager(); uint32_t flags = nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL; diff --git a/dom/base/nsTreeSanitizer.h b/dom/base/nsTreeSanitizer.h index b4a333f61..fe4917150 100644 --- a/dom/base/nsTreeSanitizer.h +++ b/dom/base/nsTreeSanitizer.h @@ -143,11 +143,13 @@ class MOZ_STACK_CLASS nsTreeSanitizer { * @param aElement the element whose attribute to possibly modify * @param aNamespace the namespace of the URL attribute * @param aLocalName the local name of the URL attribute + * @param aFragmentOnly allows same-document references only * @return true if the attribute was removed and false otherwise */ bool SanitizeURL(mozilla::dom::Element* aElement, int32_t aNamespace, - nsIAtom* aLocalName); + nsIAtom* aLocalName, + bool aFragmentOnly = false); /** * Checks a style rule for the presence of the 'binding' CSS property and -- cgit v1.2.3