Skip to content

Commit daa3d11

Browse files
committed
Bug 1925468 - Factor out "Get Trusted Type Data For Attribute". r=smaug
This patch introduces TrustedTypeUtils::GetTrustedTypeDataForAttribute to implement the corresponding algorithm from the spec: https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-data-for-attribute It is currently only used by TrustedTypePolicyFactory::GetAttributeType but "Get Trusted Types-compliant attribute value" will use it to when we implement trusted types for setAttribute/setAttributeNS. https://w3c.github.io/trusted-types/dist/spec/#validate-attribute-mutation Differential Revision: https://phabricator.services.mozilla.com/D227926
1 parent a30c609 commit daa3d11

File tree

3 files changed

+112
-39
lines changed

3 files changed

+112
-39
lines changed

dom/security/trusted-types/TrustedTypePolicyFactory.cpp

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -204,49 +204,48 @@ void TrustedTypePolicyFactory::GetAttributeType(const nsAString& aTagName,
204204
const nsAString& aElementNs,
205205
const nsAString& aAttrNs,
206206
DOMString& aResult) {
207+
// We first determine the namespace IDs for the element and attribute.
208+
// Currently, GetTrustedTypeDataForAttribute() only test a few of them so use
209+
// direct string comparisons instead of relying on
210+
// nsNameSpaceManager::GetNameSpaceID().
211+
212+
// GetTrustedTypeDataForAttribute() can only return true for empty or XLink
213+
// attribute namespaces, so don't bother calling it for other namespaces.
214+
int32_t attributeNamespaceID = kNameSpaceID_Unknown;
215+
if (aAttrNs.IsEmpty()) {
216+
attributeNamespaceID = kNameSpaceID_None;
217+
} else if (nsGkAtoms::nsuri_xlink->Equals(aAttrNs)) {
218+
attributeNamespaceID = kNameSpaceID_XLink;
219+
} else {
220+
aResult.SetNull();
221+
return;
222+
}
223+
224+
// GetTrustedTypeDataForAttribute() only test HTML or SVG element namespaces,
225+
// for testing event handler attributes the element namespace does not matter.
226+
int32_t elementNamespaceID = kNameSpaceID_Unknown;
227+
if (aElementNs.IsEmpty() || nsGkAtoms::nsuri_xhtml->Equals(aElementNs)) {
228+
elementNamespaceID = kNameSpaceID_XHTML;
229+
} else if (nsGkAtoms::nsuri_svg->Equals(aElementNs)) {
230+
elementNamespaceID = kNameSpaceID_SVG;
231+
}
232+
207233
nsAutoString attribute;
208234
nsContentUtils::ASCIIToLower(aAttribute, attribute);
209235
RefPtr<nsAtom> attributeAtom = NS_Atomize(attribute);
210236

211-
// The spec is not really clear about which "event handler content attributes"
212-
// we should consider, so we just include everything but XUL's specific ones.
213-
// See https://github.com/w3c/trusted-types/issues/520.
214-
if (aAttrNs.IsEmpty() &&
215-
nsContentUtils::IsEventAttributeName(
216-
attributeAtom, EventNameType_All & ~EventNameType_XUL)) {
217-
// Event handler content attribute.
218-
aResult.SetKnownLiveString(GetTrustedTypeName<TrustedScript>());
237+
nsAutoString localName;
238+
nsContentUtils::ASCIIToLower(aTagName, localName);
239+
RefPtr<nsAtom> elementAtom = NS_Atomize(localName);
240+
241+
TrustedType trustedType;
242+
nsAutoString unusedSink;
243+
if (GetTrustedTypeDataForAttribute(elementAtom, elementNamespaceID,
244+
attributeAtom, attributeNamespaceID,
245+
trustedType, unusedSink)) {
246+
aResult.SetKnownLiveString(GetTrustedTypeName(trustedType));
219247
return;
220248
}
221-
if (aElementNs.IsEmpty() ||
222-
aElementNs == nsDependentAtomString(nsGkAtoms::nsuri_xhtml)) {
223-
if (nsContentUtils::EqualsIgnoreASCIICase(
224-
aTagName, nsDependentAtomString(nsGkAtoms::iframe))) {
225-
// HTMLIFrameElement
226-
if (aAttrNs.IsEmpty() && attributeAtom == nsGkAtoms::srcdoc) {
227-
aResult.SetKnownLiveString(GetTrustedTypeName<TrustedHTML>());
228-
return;
229-
}
230-
} else if (nsContentUtils::EqualsIgnoreASCIICase(
231-
aTagName, nsDependentAtomString(nsGkAtoms::script))) {
232-
// HTMLScriptElement
233-
if (aAttrNs.IsEmpty() && attributeAtom == nsGkAtoms::src) {
234-
aResult.SetKnownLiveString(GetTrustedTypeName<TrustedScriptURL>());
235-
return;
236-
}
237-
}
238-
} else if (aElementNs == nsDependentAtomString(nsGkAtoms::nsuri_svg)) {
239-
if (nsContentUtils::EqualsIgnoreASCIICase(
240-
aTagName, nsDependentAtomString(nsGkAtoms::script))) {
241-
// SVGScriptElement
242-
if ((aAttrNs.IsEmpty() ||
243-
aAttrNs == nsDependentAtomString(nsGkAtoms::nsuri_xlink)) &&
244-
attributeAtom == nsGkAtoms::href) {
245-
aResult.SetKnownLiveString(GetTrustedTypeName<TrustedScriptURL>());
246-
return;
247-
}
248-
}
249-
}
250249

251250
aResult.SetNull();
252251
}
@@ -263,8 +262,7 @@ void TrustedTypePolicyFactory::GetPropertyType(const nsAString& aTagName,
263262
const nsAString& aElementNs,
264263
DOMString& aResult) {
265264
RefPtr<nsAtom> propertyAtom = NS_Atomize(aProperty);
266-
if (aElementNs.IsEmpty() ||
267-
aElementNs == nsDependentAtomString(nsGkAtoms::nsuri_xhtml)) {
265+
if (aElementNs.IsEmpty() || nsGkAtoms::nsuri_xhtml->Equals(aElementNs)) {
268266
if (nsContentUtils::EqualsIgnoreASCIICase(
269267
aTagName, nsDependentAtomString(nsGkAtoms::iframe))) {
270268
// HTMLIFrameElement

dom/security/trusted-types/TrustedTypeUtils.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@
3434

3535
namespace mozilla::dom::TrustedTypeUtils {
3636

37+
nsString GetTrustedTypeName(TrustedType aTrustedType) {
38+
switch (aTrustedType) {
39+
case TrustedType::TrustedHTML:
40+
return GetTrustedTypeName<TrustedHTML>();
41+
break;
42+
case TrustedType::TrustedScript:
43+
return GetTrustedTypeName<TrustedScript>();
44+
break;
45+
case TrustedType::TrustedScriptURL:
46+
return GetTrustedTypeName<TrustedScriptURL>();
47+
break;
48+
}
49+
}
50+
3751
// https://w3c.github.io/trusted-types/dist/spec/#abstract-opdef-does-sink-type-require-trusted-types
3852
static bool DoesSinkTypeRequireTrustedTypes(nsIContentSecurityPolicy* aCSP,
3953
const nsAString& aSinkGroup) {
@@ -373,4 +387,50 @@ IMPL_GET_TRUSTED_TYPES_COMPLIANT_STRING(TrustedScriptOrNullIsEmptyString,
373387
IMPL_GET_TRUSTED_TYPES_COMPLIANT_STRING(TrustedScriptURLOrString,
374388
TrustedScriptURL);
375389

390+
bool GetTrustedTypeDataForAttribute(const nsAtom* aElementName,
391+
int32_t aElementNamespaceID,
392+
nsAtom* aAttributeName,
393+
int32_t aAttributeNamespaceID,
394+
TrustedType& aTrustedType,
395+
nsAString& aSink) {
396+
// The spec is not really clear about which "event handler content attributes"
397+
// we should consider, so we just include everything but XUL's specific ones.
398+
// See https://github.com/w3c/trusted-types/issues/520.
399+
if (aAttributeNamespaceID == kNameSpaceID_None &&
400+
nsContentUtils::IsEventAttributeName(
401+
aAttributeName, EventNameType_All & ~EventNameType_XUL)) {
402+
aTrustedType = TrustedType::TrustedScript;
403+
return true;
404+
}
405+
if (aElementNamespaceID == kNameSpaceID_XHTML) {
406+
if (aElementName == nsGkAtoms::iframe) {
407+
// HTMLIFrameElement
408+
if (aAttributeNamespaceID == kNameSpaceID_None &&
409+
aAttributeName == nsGkAtoms::srcdoc) {
410+
aTrustedType = TrustedType::TrustedHTML;
411+
return true;
412+
}
413+
} else if (aElementName == nsGkAtoms::script) {
414+
// HTMLScriptElement
415+
if (aAttributeNamespaceID == kNameSpaceID_None &&
416+
aAttributeName == nsGkAtoms::src) {
417+
aTrustedType = TrustedType::TrustedScriptURL;
418+
return true;
419+
}
420+
}
421+
} else if (aElementNamespaceID == kNameSpaceID_SVG) {
422+
if (aElementName == nsGkAtoms::script) {
423+
// SVGScriptElement
424+
if ((aAttributeNamespaceID == kNameSpaceID_None ||
425+
aAttributeNamespaceID == kNameSpaceID_XLink) &&
426+
aAttributeName == nsGkAtoms::href) {
427+
aTrustedType = TrustedType::TrustedScriptURL;
428+
return true;
429+
}
430+
}
431+
}
432+
433+
return false;
434+
}
435+
376436
} // namespace mozilla::dom::TrustedTypeUtils

dom/security/trusted-types/TrustedTypeUtils.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ nsString GetTrustedTypeName() {
4848
return u"TrustedScriptURL"_ns;
4949
}
5050

51+
enum class TrustedType : int8_t {
52+
TrustedHTML,
53+
TrustedScript,
54+
TrustedScriptURL,
55+
};
56+
nsString GetTrustedTypeName(TrustedType aTrustedType);
57+
5158
// https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-compliant-string-algorithm
5259
//
5360
// May only run script if aInput is not a trusted type and if the trusted types
@@ -82,6 +89,14 @@ MOZ_CAN_RUN_SCRIPT void ProcessValueWithADefaultPolicy(
8289
const Document& aDocument, const nsAString& aInput, const nsAString& aSink,
8390
ExpectedType** aResult, ErrorResult& aError);
8491

92+
// https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-data-for-attribute
93+
bool GetTrustedTypeDataForAttribute(const nsAtom* aElementName,
94+
int32_t aElementNamespaceID,
95+
nsAtom* aAttributeName,
96+
int32_t aAttributeNamespaceID,
97+
TrustedType& aTrustedType,
98+
nsAString& aSink);
99+
85100
} // namespace TrustedTypeUtils
86101

87102
} // namespace dom

0 commit comments

Comments
 (0)