一 XSS
XSS(Cross-site scripting),指的是跨站脚本攻击,攻击者通过向页面A注入代码,达到窃取信息等目的,本质是数据被当作程序执行。XSS危害是很大的,一般XSS可以做到以下的事情:
- 获取页面的数据,包括dom、cookies、localStorage等
- 劫持前端逻辑
- 发送请求
- ...
1 XSS的类型
- 反射型(非持久):通过URL参数直接注入
- 存储型(持久):存储到数据库后读取时注入
- 基于DOM:被执行的恶意脚本会修改页面脚本结构
2 XSS的注入点
- HTML的节点内容或属性
- javascript代码
- 富文本
3 XSS的防御
XSS demo
public async submit(ctx) {
const { content, id } = ctx.request.body;
// 没有对 content 过滤
await db.save({
contnet,
id
});
}
public async render(ctx) {
const { content } = await db.query({
id: ctx.query.id
});
// 没有对 content 过滤
ctx.body = `<div>${content}</div>`;
}
- 永远不要相信用户提交的任何内容
- 不要将用户提交内容直接转换为 DOM
XSS 现成防御工具
前端
- 主流框架(React、Vue) 默认防御 XSS
- google-closure-library
服务端(Node)
- DOMPurify
【用户需求】必须动态生成 DOM
- string -> DOM
使用 new DOMParser() 类似 API 前必须将字符串进行转译。
- 允许用户上传 svg
提前扫描 svg 标签,防止中间插入 script 脚本恶意代码。
- Blob 动态生成 script
- 自定义跳转链接
尽量不要让用户自定义跳转行为,如果做也一定要提前过滤。
- 自定义样式
攻击者通过伪造一个 CSS 代码在指定情况下发送一个请求,从而导致攻击。
CSRF
CSRF(Cross Site Request Forgery)指的是跨站请求伪造。与XSS不同的是,XSS是攻击者直接对我们的网站A进行注入攻击,CSRF是通过网站B对我们的网站A进行伪造请求。
举个例子,你登录购物网站A之后点击一个恶意链接B,B请求了网站A的下单接口,结果是你在网站A的帐号真的会生成一个订单。其背后的原理是:网站B通过表单、get请求来伪造网站A的请求,这时候请求会带上网站A的cookies,若登录态是保存在cookies中,则实现了伪造攻击。
1 CSRF的危害
- 用户的登录态被盗用
- 完成业务的请求
- ......
2 CSRF具有的特点
- 伪造请求不经过网站A
- 伪造请求的域名不是网站A
3 CSRF的防御
- 限制请求来源
服务器端开发人员可以校验接收的
Origin或者Referer进行校验,如果是当前服务器的域名那么就放行请求,如果不是则拒绝请求。
- token
在服务器接收到一个合法页面请求时,服务器可以通过标识来判断是否是一个合法来源的请求。
- iframe 攻击
限制
Origin,攻击者会使用同源请求来到达攻击。使用
iframe来到达绕过Origin限制达到攻击。
- 避免用户信息被携带 SameSite Cookie
CSRF 的攻击是由于携带了用户
cookie,如果不携带cookie,就从根源上解决了这种 CSRF 攻击。
总结
在学习了 Web 开发安全中的两个关键概念,即跨站脚本攻击(XSS)和跨站请求伪造(CSRF)之后,我对于构建安全可靠的 Web 应用程序有了更深刻的理解。这两种安全漏洞虽然不同,但都可能对用户数据和系统造成严重威胁,因此理解并掌握防范措施至关重要。
首先,学习了 XSS 攻击后,我意识到前端输入验证和数据过滤的重要性。XSS 攻击是指攻击者通过在网站注入恶意脚本,使其在用户浏览器中执行,从而窃取用户的敏感信息或执行恶意操作。为了预防 XSS 攻击,我学会了对用户输入进行充分的验证和过滤,确保任何用户输入的数据都经过正确的转义和处理,从而阻止恶意脚本的注入。此外,采用内容安全策略(CSP)也是一种重要的防御措施,它可以限制页面中可执行的脚本源,从而减少 XSS 攻击的风险。
其次,学习了 CSRF 后,我更加重视了用户身份验证和请求验证。CSRF 攻击是指攻击者利用用户已经登录的身份,在用户不知情的情况下发送恶意请求,执行未经授权的操作。为了防范 CSRF 攻击,我学会了在请求中包含随机生成的 token,并将其与用户会话关联,从而确保只有合法的请求才会被处理。此外,及时过期的会话、双因素认证等都是增加应用程序安全性的有效手段。
然而,学习 XSS 和 CSRF 也揭示了我一些挑战。首先,实际应用中,防范措施可能会增加开发的复杂性。例如,为了防范 XSS,可能需要频繁对用户输入进行转义和过滤,这可能增加代码的复杂性和维护成本。另外,虽然使用 token 防范 CSRF 可以有效降低风险,但在复杂的应用中,正确地管理和验证这些 token 也是一个挑战。
总的来说,学习了 XSS 和 CSRF 后,我对于 Web 开发的安全性和风险有了更深入的认识。我认识到安全不仅仅是开发人员的责任,还需要整个团队共同努力。在构建 Web 应用程序时,我将更加注重用户输入的验证和过滤,合理运用安全策略,确保数据的安全性和用户的隐私保护。通过不断地学习和实践,我相信我能够构建更加安全可靠的 Web 应用,为用户提供更好的在线体验。