feat(security): fill in missing security contexts.
Reviewers: koto, rjamet, molnarg Differential Revision: https://reviews.angular.io/D109
This commit is contained in:
parent
6d36a7a45f
commit
67ed2e2c0a
|
@ -206,6 +206,53 @@ var attrToPropMap: {[name: string]: string} = <any>{
|
||||||
'tabindex': 'tabIndex'
|
'tabindex': 'tabIndex'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function registerContext(map: {[k: string]: SecurityContext}, ctx: SecurityContext, specs: string[]) {
|
||||||
|
for (let spec of specs) map[spec] = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Map from tagName|propertyName SecurityContext. Properties applying to all tags use '*'. */
|
||||||
|
const SECURITY_SCHEMA: {[k: string]: SecurityContext} = {};
|
||||||
|
|
||||||
|
registerContext(SECURITY_SCHEMA, SecurityContext.HTML, [
|
||||||
|
'iframe|srcdoc',
|
||||||
|
'*|innerHTML',
|
||||||
|
'*|outerHTML',
|
||||||
|
]);
|
||||||
|
registerContext(SECURITY_SCHEMA, SecurityContext.STYLE, ['*|style']);
|
||||||
|
// NB: no SCRIPT contexts here, they are never allowed.
|
||||||
|
registerContext(SECURITY_SCHEMA, SecurityContext.URL, [
|
||||||
|
'area|href',
|
||||||
|
'area|ping',
|
||||||
|
'audio|src',
|
||||||
|
'a|href',
|
||||||
|
'a|ping',
|
||||||
|
'blockquote|cite',
|
||||||
|
'body|background',
|
||||||
|
'button|formaction',
|
||||||
|
'del|cite',
|
||||||
|
'form|action',
|
||||||
|
'img|src',
|
||||||
|
'input|formaction',
|
||||||
|
'input|src',
|
||||||
|
'ins|cite',
|
||||||
|
'q|cite',
|
||||||
|
'source|src',
|
||||||
|
'video|poster',
|
||||||
|
'video|src',
|
||||||
|
]);
|
||||||
|
registerContext(SECURITY_SCHEMA, SecurityContext.RESOURCE_URL, [
|
||||||
|
'applet|code',
|
||||||
|
'applet|codebase',
|
||||||
|
'base|href',
|
||||||
|
'frame|src',
|
||||||
|
'head|profile',
|
||||||
|
'html|manifest',
|
||||||
|
'iframe|src',
|
||||||
|
'object|codebase',
|
||||||
|
'object|data',
|
||||||
|
'script|src',
|
||||||
|
'track|src',
|
||||||
|
]);
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DomElementSchemaRegistry extends ElementSchemaRegistry {
|
export class DomElementSchemaRegistry extends ElementSchemaRegistry {
|
||||||
|
@ -267,11 +314,10 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry {
|
||||||
* attack vectors are assigned their appropriate context.
|
* attack vectors are assigned their appropriate context.
|
||||||
*/
|
*/
|
||||||
securityContext(tagName: string, propName: string): SecurityContext {
|
securityContext(tagName: string, propName: string): SecurityContext {
|
||||||
// TODO(martinprobst): Fill in missing properties.
|
let ctx = SECURITY_SCHEMA[tagName + '|' + propName];
|
||||||
if (propName === 'style') return SecurityContext.STYLE;
|
if (ctx !== undefined) return ctx;
|
||||||
if (tagName === 'a' && propName === 'href') return SecurityContext.URL;
|
ctx = SECURITY_SCHEMA['*|' + propName];
|
||||||
if (propName === 'innerHTML') return SecurityContext.HTML;
|
return ctx !== undefined ? ctx : SecurityContext.NONE;
|
||||||
return SecurityContext.NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMappedPropName(propName: string): string {
|
getMappedPropName(propName: string): string {
|
||||||
|
|
|
@ -57,8 +57,14 @@ export function main() {
|
||||||
expect(registry.getMappedPropName('exotic-unknown')).toEqual('exotic-unknown');
|
expect(registry.getMappedPropName('exotic-unknown')).toEqual('exotic-unknown');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return security contexts for elements',
|
it('should return security contexts for elements', () => {
|
||||||
() => { expect(registry.securityContext('a', 'href')).toBe(SecurityContext.URL); });
|
expect(registry.securityContext('iframe', 'srcdoc')).toBe(SecurityContext.HTML);
|
||||||
|
expect(registry.securityContext('p', 'innerHTML')).toBe(SecurityContext.HTML);
|
||||||
|
expect(registry.securityContext('a', 'href')).toBe(SecurityContext.URL);
|
||||||
|
expect(registry.securityContext('a', 'style')).toBe(SecurityContext.STYLE);
|
||||||
|
expect(registry.securityContext('ins', 'cite')).toBe(SecurityContext.URL);
|
||||||
|
expect(registry.securityContext('base', 'href')).toBe(SecurityContext.RESOURCE_URL);
|
||||||
|
});
|
||||||
|
|
||||||
it('should detect properties on namespaced elements',
|
it('should detect properties on namespaced elements',
|
||||||
() => { expect(registry.hasProperty('@svg:g', 'id')).toBeTruthy(); });
|
() => { expect(registry.hasProperty('@svg:g', 'id')).toBeTruthy(); });
|
||||||
|
|
Loading…
Reference in New Issue