Skip to content

Commit

Permalink
feat(security): fill in missing security contexts.
Browse files Browse the repository at this point in the history
Reviewers: koto, rjamet, molnarg

Differential Revision: https://reviews.angular.io/D109
  • Loading branch information
mprobst committed May 5, 2016
1 parent 6d36a7a commit 67ed2e2
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,53 @@ var attrToPropMap: {[name: string]: string} = <any>{
'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()
export class DomElementSchemaRegistry extends ElementSchemaRegistry {
Expand Down Expand Up @@ -267,11 +314,10 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry {
* attack vectors are assigned their appropriate context.
*/
securityContext(tagName: string, propName: string): SecurityContext {
// TODO(martinprobst): Fill in missing properties.
if (propName === 'style') return SecurityContext.STYLE;
if (tagName === 'a' && propName === 'href') return SecurityContext.URL;
if (propName === 'innerHTML') return SecurityContext.HTML;
return SecurityContext.NONE;
let ctx = SECURITY_SCHEMA[tagName + '|' + propName];
if (ctx !== undefined) return ctx;
ctx = SECURITY_SCHEMA['*|' + propName];
return ctx !== undefined ? ctx : SecurityContext.NONE;
}

getMappedPropName(propName: string): string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,14 @@ export function main() {
expect(registry.getMappedPropName('exotic-unknown')).toEqual('exotic-unknown');
});

it('should return security contexts for elements',
() => { expect(registry.securityContext('a', 'href')).toBe(SecurityContext.URL); });
it('should return security contexts for elements', () => {
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',
() => { expect(registry.hasProperty('@svg:g', 'id')).toBeTruthy(); });
Expand Down

0 comments on commit 67ed2e2

Please sign in to comment.