我实际上正在为SafeValue
s 创建管道并且对此感兴趣。所以我开始挖掘,这就是我发现的:
DomSanitizationService:sanitization()
:
case SecurityContext.URL:
const type = getSanitizationBypassType(value);
if (allowSanitizationBypassOrThrow(value, BypassType.Url)) {
return unwrapSafeValue(value);
}
return _sanitizeUrl(String(value));
case SecurityContext.RESOURCE_URL:
if (allowSanitizationBypassOrThrow(value, BypassType.ResourceUrl)) {
return unwrapSafeValue(value);
}
所以这里unwrapSafeValue
的函数在两种类型中都被调用,但下面我们有:
DomSanitizationService:
bypassSecurityTrustUrl(value: string): SafeUrl {
return bypassSanitizationTrustUrl(value);
}
bypassSecurityTrustResourceUrl(value: string): SafeResourceUrl {
return bypassSanitizationTrustResourceUrl(value);
}
所以这里调用了 2 个不同的函数,让我们更深入。
在sanitization/bypass.ts我们可以找到:
export function bypassSanitizationTrustUrl(trustedUrl: string): SafeUrl {
return new SafeUrlImpl(trustedUrl);
}
export function bypassSanitizationTrustResourceUrl(trustedResourceUrl: string): SafeResourceUrl {
return new SafeResourceUrlImpl(trustedResourceUrl);
}
几行我们可以发现它们之间的唯一区别在于返回的类:
class SafeUrlImpl extends SafeValueImpl implements SafeUrl {
getTypeName() { return BypassType.Url; }
}
class SafeResourceUrlImpl extends SafeValueImpl implements SafeResourceUrl {
getTypeName() { return BypassType.ResourceUrl; }
}
并且因为
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 http://g.co/ng/security#xss)`);
}
现在我们知道ResourceUrl
在任何地方Url
都允许这样做。