XSS
什么是 XSS 攻击?如何防范 XSS 攻击?什么是 CSP?
XSS 简单点来说,就是攻击者想尽一切办法将可以执行的代码注入到网页中。 总体上我认为分为两类:持久型和非持久型
。
持久型
举个例子,对于评论功能来说,就得防范持久型 XSS 攻击。评论区输入以下js代码
javascript
<script>alert('xss攻击');</script>
非持久型
一般通过修改URL参数的方式
加入攻击代码,诱导用户访问链接从而进行攻击。 举个例子,如果页面需要从 URL 中获取某些参数作为内容的话,不经过过滤就会导致攻击代码被执行。
javascript
<!-- http://www.domain.com?name=<script>alert(1)</script> -->
<div>{{name}}</div>
注意:Chrome 这类浏览器能自动帮助用户防御攻击。其他浏览器未知
如何防御XSS攻击
转义字符
针对普通输入框
javascript
function escape(str) {
str = str.replace(/&/g, '&')
str = str.replace(/</g, '<')
str = str.replace(/>/g, '>')
str = str.replace(/"/g, '&quto;')
str = str.replace(/'/g, ''')
str = str.replace(/`/g, '`')
str = str.replace(/\//g, '/')
return str
}
escape('<script>alert(1)</script>') // -> <script>alert(1)</script>
针对富文本 转义字符的方式会把需要的格式也过滤掉,所以推荐使用白名单的方式。
javascript
const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1><script>alert("xss");</script>
console.log(html)
CSP
两种方式来开启 CSP
后端设置 HTTP Header 中的 Content-Security-Policy
php
/*
default-src:设置默认加载资源的策略(例如,自身的源、任何地方的源、或者不加载任何外部资源)。
script-src:定义哪些脚本可以执行, 例如script标签, a标签的JavaScript:location.href="" 等.
style-src:定义哪些样式表可以加载。
img-src:定义哪些图片资源可以加载。
connect-src:限制可以通过脚本接口进行连接的URL(例如,AJAX 请求、WebSocket)。
font-src:定义哪些字体资源可以加载。
object-src:限制可以加载哪些插件。
media-src:定义哪些媒体资源(音频和视频)可以加载。
frame-src:定义哪些iframe可以加载。
*/
<?php
// 只允许加载来自同源的所有资源
header("Content-Security-Policy: script-src 'self'");
// 允许执行来自同源以及http://192.168.112.183的脚本。
header("Content-Security-Policy: script-src 'self' http://192.168.112.183");
// 允许执行来自同源以及http://http://192.168.112.183的行内脚本
// 比如 <a javascript:location.href="http://192.168.112.183/hack.php"></a>
header("Content-Security-Policy: script-src 'self' http://192.168.112.183 'unsafe-inline'");
前端设置 meta
标签的方式 <meta http-equiv="Content-Security-Policy">
html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://apis.example.com; img-src 'self' https://images.example.com; style-src 'self' 'unsafe-inline';">
<title>My Secure Page</title>
</head>
<body>
<!-- 页面内容 -->
</body>
</html>
运维全局配置CSP 修改服务器配置文件
举例
html
// Apache
<IfModule mod_headers.c>
Header set Content-Security-Policy "default-src 'self';"
</IfModule>
// Nginx
server {
add_header Content-Security-Policy "default-src 'self';";
...
}
CSRF
什么是 CSRF 攻击?如何防范 CSRF 攻击?
跨站请求伪造。原理就是攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑。
举个例子,假设网站中有一个通过 GET
请求提交用户评论的接口,那么攻击者就可以在钓鱼网站中加入一个图片,图片的地址就是评论接口
html
<img src="http://www.domain.com/xxx?comment='attack'"/>
防御 CSRF的方法包括:
CSRF令牌:
- 为每个用户会话生成唯一的 CSRF 令牌,并将其添加到每个可能引发状态更改的请求(例如表单提交)中。
- 服务器在接收到请求时检查令牌的有效性,确保请求是来自合法用户。
验证 HTTP Referer头部
- 检查 HTTP 请求中的
Referer
头部,确保请求来自预期的来源。
Get 请求不对数据进行修改
合理设置用户会话过期时间
设置 Cookie 的 SameSite
属性 该属性表示 Cookie 不随着跨域请求发送
注意:该属性目前并不是所有浏览器都兼容
点击劫持
什么是点击劫持?如何防范点击劫持?
点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过 iframe
嵌套的方式嵌入自己的网页中,并将 iframe
设置为透明,在页面中透出一个按钮诱导用户点击。
X-FRAME-OPTIONS
html
/*
该响应头有三个值可选,分别是
- `DENY`,表示页面不允许通过 `iframe` 的方式展示
- `SAMEORIGIN`,表示页面可以在相同域名下通过 `iframe` 的方式展示
- `ALLOW-FROM`,表示页面可以在指定来源的 `iframe` 中展示
*/
<meta http-equiv="X-Frame-Options" content="SAMEORIGIN">
JS 防御
html
<head>
<style id="click-jack"> html { display: none !important; } </style>
</head>
<body>
<script>
if (self == top) {
var style = document.getElementById('click-jack')
document.body.removeChild(style)
} else {
top.location = self.location
}
</script>
</body>