Skip to content

Commit

Permalink
docs: extract XSS security doc URL into a constant (#48082)
Browse files Browse the repository at this point in the history
We plan to change the link in google3 to point to google3-specific
documentation. Replacing a single constant will make for a smaller and
more maintainable patch.

PR Close #48082
  • Loading branch information
bjarkler authored and dylhunn committed Nov 17, 2022
1 parent 8a45dab commit 414b1b2
Show file tree
Hide file tree
Showing 9 changed files with 23 additions and 18 deletions.
1 change: 1 addition & 0 deletions packages/core/src/core_private_export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export {convertToBitFlags as ɵconvertToBitFlags, setCurrentInjector as ɵsetCur
export {getInjectableDef as ɵgetInjectableDef, ɵɵInjectableDeclaration, ɵɵInjectorDef} from './di/interface/defs';
export {InternalEnvironmentProviders as ɵInternalEnvironmentProviders, isEnvironmentProviders as ɵisEnvironmentProviders} from './di/interface/provider';
export {INJECTOR_SCOPE as ɵINJECTOR_SCOPE} from './di/scope';
export {XSS_SECURITY_URL as ɵXSS_SECURITY_URL} from './error_details_base_url';
export {formatRuntimeError as ɵformatRuntimeError, RuntimeError as ɵRuntimeError} from './errors';
export {CurrencyIndex as ɵCurrencyIndex, ExtraLocaleDataIndex as ɵExtraLocaleDataIndex, findLocaleData as ɵfindLocaleData, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, LocaleDataIndex as ɵLocaleDataIndex, registerLocaleData as ɵregisterLocaleData, unregisterAllLocaleData as ɵunregisterLocaleData} from './i18n/locale_data_api';
export {DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID} from './i18n/localization';
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/error_details_base_url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@
/**
* Base URL for the error details page.
*
* Keep the files below in full sync:
* Keep this constant in sync across:
* - packages/compiler-cli/src/ngtsc/diagnostics/src/error_details_base_url.ts
* - packages/core/src/error_details_base_url.ts
*/
export const ERROR_DETAILS_PAGE_BASE_URL = 'https://angular.io/errors';

/**
* URL for the XSS security documentation.
*/
export const XSS_SECURITY_URL = 'https://g.co/ng/security#xss';
3 changes: 2 additions & 1 deletion packages/core/src/render3/i18n/i18n_parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import '../../util/ng_dev_mode';
import '../../util/ng_i18n_closure_mode';

import {XSS_SECURITY_URL} from '../../error_details_base_url';
import {getTemplateContent, URI_ATTRS, VALID_ATTRS, VALID_ELEMENTS} from '../../sanitization/html_sanitizer';
import {getInertBodyHelper} from '../../sanitization/inert_body';
import {_sanitizeUrl} from '../../sanitization/url_sanitizer';
Expand Down Expand Up @@ -632,7 +633,7 @@ function walkIcuTree(
console.warn(
`WARNING: ignoring unsafe attribute value ` +
`${lowerAttrName} on element ${tagName} ` +
`(see https://g.co/ng/security#xss)`);
`(see ${XSS_SECURITY_URL})`);
}
} else {
addCreateAttribute(create, newIndex, attr);
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/sanitization/bypass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {XSS_SECURITY_URL} from '../error_details_base_url';

export const enum BypassType {
Url = 'URL',
Expand Down Expand Up @@ -65,7 +66,7 @@ abstract class SafeValueImpl implements SafeValue {

toString() {
return `SafeValue must use [property]=binding: ${this.changingThisBreaksApplicationSecurity}` +
` (see https://g.co/ng/security#xss)`;
` (see ${XSS_SECURITY_URL})`;
}
}

Expand Down Expand Up @@ -118,8 +119,7 @@ export function allowSanitizationBypassAndThrow(value: any, type: BypassType): b
if (actualType != null && actualType !== type) {
// Allow ResourceURLs in URL contexts, they are strictly more trusted.
if (actualType === BypassType.ResourceUrl && type === BypassType.Url) return true;
throw new Error(
`Required a safe ${type}, got a ${actualType} (see https://g.co/ng/security#xss)`);
throw new Error(`Required a safe ${type}, got a ${actualType} (see ${XSS_SECURITY_URL})`);
}
return actualType === type;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/sanitization/html_sanitizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {XSS_SECURITY_URL} from '../error_details_base_url';
import {TrustedHTML} from '../util/security/trusted_type_defs';
import {trustedHTMLFromString} from '../util/security/trusted_types';

Expand Down Expand Up @@ -268,8 +269,7 @@ export function _sanitizeHtml(defaultDoc: any, unsafeHtmlInput: string): Trusted
const safeHtml = sanitizer.sanitizeChildren(
getTemplateContent(inertBodyElement!) as Element || inertBodyElement);
if ((typeof ngDevMode === 'undefined' || ngDevMode) && sanitizer.sanitizedSomething) {
console.warn(
'WARNING: sanitizing HTML stripped some content, see https://g.co/ng/security#xss');
console.warn(`WARNING: sanitizing HTML stripped some content, see ${XSS_SECURITY_URL}`);
}

return trustedHTMLFromString(safeHtml);
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/sanitization/sanitization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {XSS_SECURITY_URL} from '../error_details_base_url';
import {RuntimeError, RuntimeErrorCode} from '../errors';
import {getDocument} from '../render3/interfaces/document';
import {SANITIZER} from '../render3/interfaces/view';
Expand Down Expand Up @@ -120,8 +121,7 @@ export function ɵɵsanitizeResourceUrl(unsafeResourceUrl: any): TrustedScriptUR
}
throw new RuntimeError(
RuntimeErrorCode.UNSAFE_VALUE_IN_RESOURCE_URL,
ngDevMode &&
'unsafe value used in a resource URL context (see https://g.co/ng/security#xss)');
ngDevMode && `unsafe value used in a resource URL context (see ${XSS_SECURITY_URL})`);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/sanitization/url_sanitizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {XSS_SECURITY_URL} from '../error_details_base_url';

/**
* A pattern that recognizes a commonly useful subset of URLs that are safe.
Expand Down Expand Up @@ -40,7 +41,7 @@ export function _sanitizeUrl(url: string): string {
if (url.match(SAFE_URL_PATTERN)) return url;

if (typeof ngDevMode === 'undefined' || ngDevMode) {
console.warn(`WARNING: sanitizing unsafe URL value ${url} (see https://g.co/ng/security#xss)`);
console.warn(`WARNING: sanitizing unsafe URL value ${url} (see ${XSS_SECURITY_URL})`);
}

return 'unsafe:' + url;
Expand Down
6 changes: 2 additions & 4 deletions packages/core/test/sanitization/sanitization_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ describe('sanitization', () => {
});

it('should sanitize resourceUrl', () => {
const ERROR =
'NG0904: unsafe value used in a resource URL context (see https://g.co/ng/security#xss)';
const ERROR = /NG0904: unsafe value used in a resource URL context.*/;
expect(() => ɵɵsanitizeResourceUrl('http://server')).toThrowError(ERROR);
expect(() => ɵɵsanitizeResourceUrl('javascript:true')).toThrowError(ERROR);
expect(() => ɵɵsanitizeResourceUrl(bypassSanitizationTrustHtml('javascript:true')))
Expand Down Expand Up @@ -106,8 +105,7 @@ describe('sanitization', () => {
});

it('should sanitize resourceUrls via sanitizeUrlOrResourceUrl', () => {
const ERROR =
'NG0904: unsafe value used in a resource URL context (see https://g.co/ng/security#xss)';
const ERROR = /NG0904: unsafe value used in a resource URL context.*/;
expect(() => ɵɵsanitizeUrlOrResourceUrl('http://server', 'iframe', 'src')).toThrowError(ERROR);
expect(() => ɵɵsanitizeUrlOrResourceUrl('javascript:true', 'iframe', 'src'))
.toThrowError(ERROR);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import {DOCUMENT} from '@angular/common';
import {forwardRef, Inject, Injectable, Injector, Sanitizer, SecurityContext, ɵ_sanitizeHtml as _sanitizeHtml, ɵ_sanitizeUrl as _sanitizeUrl, ɵallowSanitizationBypassAndThrow as allowSanitizationBypassOrThrow, ɵbypassSanitizationTrustHtml as bypassSanitizationTrustHtml, ɵbypassSanitizationTrustResourceUrl as bypassSanitizationTrustResourceUrl, ɵbypassSanitizationTrustScript as bypassSanitizationTrustScript, ɵbypassSanitizationTrustStyle as bypassSanitizationTrustStyle, ɵbypassSanitizationTrustUrl as bypassSanitizationTrustUrl, ɵBypassType as BypassType, ɵgetSanitizationBypassType as getSanitizationBypassType, ɵunwrapSafeValue as unwrapSafeValue} from '@angular/core';
import {forwardRef, Inject, Injectable, Injector, Sanitizer, SecurityContext, ɵ_sanitizeHtml as _sanitizeHtml, ɵ_sanitizeUrl as _sanitizeUrl, ɵallowSanitizationBypassAndThrow as allowSanitizationBypassOrThrow, ɵbypassSanitizationTrustHtml as bypassSanitizationTrustHtml, ɵbypassSanitizationTrustResourceUrl as bypassSanitizationTrustResourceUrl, ɵbypassSanitizationTrustScript as bypassSanitizationTrustScript, ɵbypassSanitizationTrustStyle as bypassSanitizationTrustStyle, ɵbypassSanitizationTrustUrl as bypassSanitizationTrustUrl, ɵBypassType as BypassType, ɵgetSanitizationBypassType as getSanitizationBypassType, ɵunwrapSafeValue as unwrapSafeValue, ɵXSS_SECURITY_URL as XSS_SECURITY_URL} from '@angular/core';

export {SecurityContext};

Expand Down Expand Up @@ -182,10 +182,9 @@ export class DomSanitizerImpl extends DomSanitizer {
if (allowSanitizationBypassOrThrow(value, BypassType.ResourceUrl)) {
return unwrapSafeValue(value);
}
throw new Error(
'unsafe value used in a resource URL context (see https://g.co/ng/security#xss)');
throw new Error(`unsafe value used in a resource URL context (see ${XSS_SECURITY_URL})`);
default:
throw new Error(`Unexpected SecurityContext ${ctx} (see https://g.co/ng/security#xss)`);
throw new Error(`Unexpected SecurityContext ${ctx} (see ${XSS_SECURITY_URL})`);
}
}

Expand Down

0 comments on commit 414b1b2

Please sign in to comment.