https://bu1.github.io/2021/01/12/第十二周:XSS漏洞学习实战/

后端绕开了前端,直接调用接口入库:
<select οnchange="alert(1)">12
前端拿到这个文本后,再富文本编辑器中,会将其解析为js脚本,从而实现xss攻击。
原始方案一:
1、前端调用接口的时候,不进行转义
2、后端入库的时候转义
3、后端返回给前端,前端对转义的数据进行反转义,这样就保证了不会有问题。
这个方案理解上存在的问题:
1、前端进行反转义是浏览器的行为,而不是什么拦截器或者代码,组件的行为机制;
2、为什么给后端的数据会自动的进行转义,这个是Angular框架自动的行为,类似的Vue也存在这种机制。
在前端开发中,自动转义的目的是为了 防止 XSS 攻击 和 确保用户输入的内容不会被浏览器误解析为 HTML 或 JavaScript 代码。当用户通过表单、URL 参数或其他方式输入数据时,如果这些输入数据未经处理直接插入到页面中,可能会导致恶意用户通过注入脚本来执行攻击。
前端自动转义的原因
-
防止 XSS 攻击 :
XSS (跨站脚本攻击) 是一种常见的安全漏洞,攻击者可以通过注入恶意的 JavaScript 代码来执行一些不安全的操作,比如窃取用户信息或篡改页面内容。如果浏览器将用户输入的内容(如<script>alert('XSS')</script>
)直接渲染为 HTML 代码,那么攻击者的脚本就会被执行。为了防止这种情况,很多现代框架和工具会对用户输入进行自动转义,确保它被当作纯文本呈现,而不是被执行。
-
确保数据的安全性 :
转义字符(如
<
,>
,&
,"
)会将特殊字符转换成 HTML 实体,使它们无法作为 HTML 或 JavaScript 执行。这就能确保无论数据如何传递,浏览器都只会将其当作普通文本处理。
Angular 中的自动转义
Angular 是一个现代的前端框架,具有 自动防止 XSS 攻击 的机制。Angular 在将模板中的用户输入渲染到 DOM 时,会自动对数据进行转义,从而防止恶意脚本注入。具体来说,Angular 使用了一个叫做 安全上下文(Security Context) 的概念。
1. Angular 默认的自动转义
Angular 会对绑定到模板中的用户输入进行自动转义。无论是通过 {``{ expression }}
或 [innerHTML]
插值,Angular 都会确保将用户提供的数据视为纯文本,而不会执行其中的 HTML 或 JavaScript 代码。
例子:
html
<div>{{ userInput }}</div>
如果 userInput
是来自用户的输入,Angular 会自动转义其中的 HTML 实体,如 <
被转义为 <
,>
被转义为 >
,从而避免用户输入的内容被浏览器解释为 HTML 标签或 JavaScript 代码。
2. 插值绑定和属性绑定
- 插值绑定 :如
{``{ userInput }}
,Angular 会自动将数据转义为文本。 - 属性绑定 :如
[innerHTML]="userInput"
,如果直接将用户输入的内容绑定到innerHTML
,Angular 默认 不转义,而是将其作为 HTML 渲染。这时,你需要小心处理用户输入,避免 XSS 攻击。
3. ng-bind 和 ng-bind-html
ng-bind
:Angular 自动转义绑定的文本内容,类似于插值绑定{``{}}
,并防止执行其中的 HTML 和 JavaScript。ng-bind-html
:Angular 在将内容绑定到innerHTML
时不会进行转义,需要手动处理 用户输入来防止 XSS。为了防止不安全的 HTML 被渲染,你可以使用 Angular 提供的DomSanitizer
服务来清理内容。
DomSanitizer 防止 XSS
在 Angular 中,如果你必须通过 innerHTML
渲染用户输入的内容,推荐使用 DomSanitizer
来清理不安全的 HTML,确保内容不会被执行。DomSanitizer
允许你标记安全的 HTML 内容。
示例:
typescript
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
@Component({
selector: 'app-component',
template: `<div [innerHTML]="safeHtmlContent"></div>`
})
export class MyComponent {
safeHtmlContent: SafeHtml;
constructor(private sanitizer: DomSanitizer) {}
ngOnInit() {
const userInput = '<script>alert("XSS")</script>';
this.safeHtmlContent = this.sanitizer.bypassSecurityTrustHtml(userInput);
}
}
在这个例子中,bypassSecurityTrustHtml
将用户输入的 HTML 标记为 信任的 HTML ,Angular 不会对其进行自动转义。但通常,如果可能,应该避免直接使用 innerHTML
,并考虑使用其他方式来安全地显示内容。
总结
- Angular 自动转义:对于大多数插值绑定,Angular 会自动对用户输入进行转义,确保它们不会被浏览器解释为 HTML 或 JavaScript。
- 手动控制转义 :如果使用
innerHTML
或类似方法直接渲染用户输入,需要小心 XSS 问题,可以使用 Angular 提供的DomSanitizer
进行处理。 - 为什么自动转义:转义的目的是为了防止 XSS 攻击,确保用户输入不会执行恶意代码。
最终方案:
前端不变,后端在入库的时候,再进行一次转义。
前端进行转义后,后端再继续转义,不会有问题!因为转义只是对<等符号进行处理,两次转义后应该结果是相同的。
前端拿到转义的文字,在渲染的时候进行渲染,也不会有问题。
xss攻击基本知识:
未经转义的文本 会被浏览器解析并执行其中的 JavaScript(例如 )。
已转义的文本(例如 <script>alert('XSS')</script>)会被浏览器当作普通文本显示,而不会执行其中的 JavaScript 代码。
双重转义不会造成安全问题,因为浏览器会把转义后的字符当做普通文本处理,不会执行其中的 JavaScript。
前端和后端的双重转义 可以确保更高的安全性,但它是冗余的,并且会增加字符的长度和复杂度。
前端渲染 转义后的内容时,浏览器会正确显示转义字符,不会有问题。