Skip to content

Commit 526cc0a

Browse files
securityMBcopybara-github
authored andcommitted
No public description
PiperOrigin-RevId: 649387310
1 parent fa5bbf0 commit 526cc0a

File tree

2 files changed

+46
-11
lines changed

2 files changed

+46
-11
lines changed

src/builders/html_sanitizer/css/sanitizer.ts

+14-11
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class CssSanitizer {
4141
constructor(
4242
private readonly propertyAllowlist: ReadonlySet<string>,
4343
private readonly functionAllowlist: ReadonlySet<string>,
44-
private readonly resourceUrlPolicy: ResourceUrlPolicy,
44+
private readonly resourceUrlPolicy: ResourceUrlPolicy | undefined,
4545
private readonly allowKeyframes: boolean,
4646
private readonly propertyDiscarders: PropertyDiscarder[],
4747
) {}
@@ -142,18 +142,21 @@ class CssSanitizer {
142142
return null;
143143
}
144144
const url = nextToken.value;
145-
const sanitizedUrl = this.resourceUrlPolicy(parseUrl(url), {
146-
type: calledFromStyleTag
147-
? ResourceUrlPolicyHintsType.STYLE_TAG
148-
: ResourceUrlPolicyHintsType.STYLE_ATTRIBUTE,
149-
propertyName,
150-
});
151-
if (!sanitizedUrl) {
145+
let parsedUrl: URL | null = parseUrl(url);
146+
if (this.resourceUrlPolicy) {
147+
parsedUrl = this.resourceUrlPolicy(parseUrl(url), {
148+
type: calledFromStyleTag
149+
? ResourceUrlPolicyHintsType.STYLE_TAG
150+
: ResourceUrlPolicyHintsType.STYLE_ATTRIBUTE,
151+
propertyName,
152+
});
153+
}
154+
if (!parsedUrl) {
152155
return null;
153156
}
154157
tokens[i + 1] = {
155158
tokenKind: CssTokenKind.STRING,
156-
value: sanitizedUrl.toString(),
159+
value: parsedUrl.toString(),
157160
};
158161

159162
// Skip the string token.
@@ -293,7 +296,7 @@ export function sanitizeStyleTag(
293296
cssText: string,
294297
propertyAllowlist: ReadonlySet<string>,
295298
functionAllowlist: ReadonlySet<string>,
296-
resourceUrlPolicy: ResourceUrlPolicy,
299+
resourceUrlPolicy: ResourceUrlPolicy | undefined,
297300
allowKeyframes: boolean,
298301
propertyDiscarders: PropertyDiscarder[],
299302
): string {
@@ -316,7 +319,7 @@ export function sanitizeStyleAttribute(
316319
cssText: string,
317320
propertyAllowlist: ReadonlySet<string>,
318321
functionAllowlist: ReadonlySet<string>,
319-
resourceUrlPolicy: ResourceUrlPolicy,
322+
resourceUrlPolicy: ResourceUrlPolicy | undefined,
320323
propertyDiscarders: PropertyDiscarder[],
321324
): string {
322325
return new CssSanitizer(

test/builders/html_sanitizer/css/sanitizer_test.ts

+32
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,38 @@ describe('sanitizeStyleTag', () => {
122122
});
123123
}
124124

125+
describe('without a custom resource url policy', () => {
126+
it('allows all URLs', () => {
127+
const propertyAllowlist = new Set([
128+
'background-image',
129+
'border-image-source',
130+
'cursor',
131+
]);
132+
const functionAllowlist = new Set(['url']);
133+
const sanitized = sanitizeStyleTag(
134+
`
135+
body { background-image: url("https://www.google.com") }
136+
div { border-image-source: url("file:///etc/passwd") }
137+
span { cursor: url(/relative/path), pointer }
138+
`,
139+
propertyAllowlist,
140+
functionAllowlist,
141+
undefined, // resourceUrlPolicy
142+
false,
143+
[],
144+
);
145+
const relativePath = new URL(
146+
'/relative/path',
147+
document.baseURI,
148+
).toString();
149+
expect(sanitized).toEqual(
150+
`body { background-image: url("https://www.google.com/"); }
151+
div { border-image-source: url("file:///etc/passwd"); }
152+
span { cursor: url("${relativePath}"), pointer; }`,
153+
);
154+
});
155+
});
156+
125157
describe('with a custom resource url policy', () => {
126158
it('calls the policy with a valid URL and hints', () => {
127159
const resourceUrlPolicy = jasmine

0 commit comments

Comments
 (0)