清理不安全 URL 时出现意外行为?

Unexpected behavior when sanitizing unsafe URLs?

我需要清理我网站上的不安全 URL。尝试使用 DomSanitizer 的清理方法,但得到了意想不到的结果。文档似乎很清楚应该对方法 sanitize() 进行某种清理,但我没有看到任何东西。 “实现负责确保在给定的上下文中绝对可以安全地使用该值。”

为什么将保险箱 url 清理为 RESOURCE_URL 会引发错误?

为什么将不安全的 url 清理为 URL 不会清理字符串?

奖励:为什么我看到有人在做 bypassSecurityTrustUrl( sanitize() ) ? sanitize 方法不应该使字符串安全吗?

safeURL:string = "android.com";
unsafeURL:string = "android.com?param=<script>alert('xss!');</script>";
outputURL:string | null;


constructor(private sanitizer: DomSanitizer) {

    this.outputURL = sanitizer.sanitize(SecurityContext.URL, this.safeURL);
    console.log(this.outputURL) //android.com

    this.outputURL = sanitizer.sanitize(SecurityContext.RESOURCE_URL, this.safeURL);
    console.log(this.outputURL) //Error: unsafe value used in a resource URL context

    this.outputURL = sanitizer.sanitize(SecurityContext.URL, this.unsafeURL);
    console.log(this.outputURL) //android.com?param=<script>alert('xss!');</script>

    this.outputURL = sanitizer.sanitize(SecurityContext.RESOURCE_URL, this.unsafeURL);
    console.log(this.outputURL) //Error: unsafe value used in a resource URL context
}

来自 docs:

Sanitization is the inspection of an untrusted value, turning it into a value that's safe to insert into the DOM. In many cases, sanitization doesn't change a value at all. Sanitization depends on context: a value that's harmless in CSS is potentially dangerous in a URL.

重要的是要注意,在许多情况下,清理根本不会改变值;什么是安全的或不安全的取决于上下文

Why would sanitizing a safe url to RESOURCE_URL throw an error?

了解 URL 和 RESOURCE_URL 之间的区别很重要。

资源 URLs 可以是那些包含 Base64 数据或 html 元素 <script src><iframe src> 的资源,它们确实加载了一些资源(可执行代码)。此类数据是任意数据,框架无法知道此类资源 URL 是否安全,因此无法清理资源 URL。

使用 SecurityContext.RESOURCE_URL 上下文调用 sanitize,总是会抛出错误,除非该值被标记为可信。这是一种框架方式,告诉我们作为应用程序开发人员的我们需要确保资源 URL 可以安全使用。

可能是我们正在从我们自己的服务器加载资源,因此我们知道它可以安全使用,在这种情况下我们可以调用 bypassSecurityTrustResourceUrl() 告诉 Angular 我们信任该资源URL 和 Angular 将不会为那些资源 URL 抛出错误。使用可能包含不受信任的用户数据的 URL 调用 bypassSecurityTrustResourceUrl() 可能会导致我们的应用程序存在安全风险。


Why would sanitizing an unsafe url to URL not sanitize the string?

您使用的字符串在 URL 上下文中并非不安全,即当将其用作

  • <img [src]="unsafeURL">
  • <a [href]="unsafeURL">Link</a>

但是在 SecurityContext.HTML 上下文中使用相同的字符串是不安全的,即可能在 [innerHTML].

中使用时
unsafeHTML = "android.com?param=<script>alert('xss!');</script>";

// The value is stripped in HTML context
this.outputURL = sanitizer.sanitize(SecurityContext.HTML, this.unsafeHTML);
console.log(this.outputURL) // android.com?param=

SecurityContext.URL 上下文中,字符串值在匹配 SAFE_URL_PATTERN or DATA_URL_PATTERN 正则表达式时按原样返回。

一个不安全的例子url:

unsafeURL = "javascript:alert('Lottery!')";

this.outputURL = sanitizer.sanitize(SecurityContext.URL, this.unsafeURL);
console.log(this.outputURL) //unsafe:javascript:alert('Lottery!') */

我还建议您完成 Sanitization and security contexts