1 浏览器安全
🍑 浏览器的同源策略:限制了来自不同源的document或脚本,对当前document读取或设置某些属性。在浏览器中scrpt、img、iframe、link等标签都可以跨域加载资源,而不受同源策略的限制,这些带src属性的标签每次加载时,实际上是由浏览器发起一次GET请求。
🍑 浏览器沙箱:让不受信任的网页代码、JavaScript代码运行在一个受限制的环境中,从而保护本地桌面系统的安全。
🍑恶意网址拦截:一个正常网页通过script或iframe等标签加载一个恶意网址。常见恶意网址分类:挂马网站(包含恶意脚本如Javascript或Flash,通过利用浏览器地漏洞执行shell Code,在用户电脑中植入木马)和钓鱼网站(模仿知名网站地相似页面来欺骗用户),恶意网址的拦截工作原理:浏览器周期性地从服务器端获取一份最新地恶意网址名单,如果用户上网时访问地网址存在于此黑名单中,浏览器就会弹出一个警告页面。
2 跨站脚本攻击(XSS)
- Cross-Site Scripting(XSS),俗称
跨站脚本攻击,一种代码注入攻击,攻击者通过给目标网站注入脚本,诱导用户点击,使得脚本最终在用户的浏览器上执行。XSS的本质是因为网站没有对恶意代码进行过滤,与正常代码混合在一起了,浏览器没有办法分辨那些脚本是可信的,从而导致了恶意代码的执行。
静态网页:纯前端代码,文件后缀为html的一般为静态页面
动态网页:由后端代码所参与的网页就是动态网页
伪静态:动态网页假装成静态页面(SQL注入),与动态页面唯一的区别在于传参
2.1 XSS攻击类型
🍑 存储型XSS攻击:恶意脚本存储在目标浏览器上,当浏览器请求数据时,脚本从服务器传回并执行。(提交的恶意数据实现了XSS,存入数据库或者写入日志,别人访问这个页面的时候就会自动触发)
存储型xss攻击需要经过以下步骤:
- 攻击者将恶意代码提交到目标网站的数据库中
- 用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在HTML中返回给浏览器。
- 用户浏览器接收到响应后解析执行,混在其中的恶意代码被执行
- 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
🍑 反射型XSS攻击:攻击者诱导用户访问一个带有恶意代码的URL后,服务器端接收数据后处理,然后带有恶意代码的数据发送到浏览器端,浏览器端解析这段带有XSS代码的数据后当作脚本执行,最终完成XSS攻击。(提交的恶意数据实现了XSS,但仅仅是对你这次访问产生了影响,非持久攻击)
反射型XSS攻击需要经过以下步骤:
- 攻击者构造出特殊url,其中包含恶意代码。
- 用户打开带有恶意代码的url时,网站服务端将恶意代码从URL中取出,拼接在HTML中返回给浏览器。
- 用户浏览器接收到响应后解析执行,混在其中的恶意代码被执行
- 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
🍑 基于DOM(DOM-based)的XSS攻击:通过修改页面的DOM节点形成的攻击。通过DOM可以让脚本动态访问、控制网页,同过js去对网页进行修改、变化执行产生的XSS漏洞。DOM-based XSS漏洞是基于文档对象模型的一种漏洞,客户端的脚本程序可以通过和修改页面内容,它不依赖于提交数据到服务器端,从客户端获得DOM中的数据在本地执行,如果DOM中的数据没有经过严格确认就会产生DOM-based。比如以下属性就是客户端可以修改的内容。
基于DOM(DOM-based)的XSS攻击需要经过以下步骤:
- 攻击者构造出特殊url,其中包含恶意代码。
- 用户打开带有恶意代码的url。
- 用户浏览器接收到响应后解析执行,混在其中的恶意代码被执行
- 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。 .write //向文档写HTML表达式或JavaScript代码
它们的区别在哪? DOM型XSS攻击中,去除和执行恶意代码由浏览器端完成,属于前端js自身的安全漏洞,而其他两种XSS都属于服务端的安全漏洞。
2.2 XSS常见的攻击方式
🍑 绕过XSS-Filter,利用script标签注入Html/JavaScript代码。
🍑 利用HTML标签的属性值进行XSS攻击。不是所有web浏览器都支持JavaScript伪协议,但此类XSS攻击具有一定的局限性。如
<img src="javascript:alert('xss')"/>
🍑 用户可以利用空格、回车和Tab键来绕过过滤。
🍑 利用时间来执行跨站脚本。
<img src="#" onerror="alert(1)"/>
<!--当src错误的视乎就会执行onerror时间-->
🍑 利用css跨站。
body{
background-image:url("javascript:alert('xss')");
}
🍑 利用字符编码,通过这种技巧,不仅能让XSS代码绕过服务端的过滤,还能更好地隐藏Shellcode;
🍑 拆分跨站法,将XSS攻击的代码拆分开来,适用于应用程序没有过滤XSS关键字符如(<、>)却对输入字符长度有限制的情况下;
🍑 DOM型的XSS主要是由客户端的脚本通过DOM动态地输出数据到页面上,它不依赖于提交数据到服务器,而是从客户端获得DOM中的数据在本地执行。容易导致DOM型的XSS的输入源如
document.cookie // 设置或返回与当前文档有关的cookie
document.domain // 返回当前文档的域名
document.lastModified //返回文档被最后修改的日期和时间
document.referred //返回载入当前文档的url
document.title // 返回当前文档的title
document.url //返回当前文档的url
document.name,localStorage/globalStorage
2.3 XSS的防御方式
无论何种类型的XSS攻击,它们都是要首先在浏览器中注入恶意脚本,然后在通过恶意脚本,然后再通过恶意脚本将用户信息发送至黑客部署的恶意服务器上。所以组织XSS攻击,可以通过组织恶意脚本的注入和恶意消息的发送来实现。
🍑 HttpOnly:这个属性是存在于cookie中的,然后通过后端响应回来的cookie中设置的,不用每个cookie都设置,只是设置我们关键的cookie,比如登录api涉及用户隐私的。以nodejs为例:
app.use(cookieParser("miyao"));
app.get('/api/setcookie', (req, res) => {
res.cookie("username", "swk", {
maxAge: 24 * 60 * 60 * 1000,
signed: true, // 加密(签名)
httpOnly:true
});
res.send({ msg: "设置cookie成功!" });
})
🍑 CSP通用策略:内容安全策略,是一个附加的安全层,用于帮助检测和缓解某些类型的攻击,包括xss和数据注入等攻击。csp的实质就是白名单制度,开发者明确告诉客户端,那些外部资源可以加载和执行,等同于提供白名单。可以由两种方式指定。由两个字段控制:Content-Security-Policy(配置好并启用之后,不符合csp的外部资源就会被阻止加载)和Content-Security-Policy-Report-Only(不执行限制选项,只是记录违反限制的行为,必须配合report-uri(一种指令指示用户代理报告违反内容安全策略的企图)使用)
-
HTTP Header(响应头)指定:
// HTTP header: "Content-Security-Policy":策略 "Content-Security-Policy-Report-Only":策略// 限制所有的外部资源,都只能从当前域名加载 Content-Security-Policy: default-src 'self' // default-src 是 CSP 指令,多个指令之间用英文分号分割;多个指令值用英文空格分割 Content-Security-Policy: default-src https://host1.com https://host2.com; frame-src 'none'; object-src 'none' -
html的meta标签指定:
<meta http-equiv="content-security-policy" content="策略"> <meta http-equiv="content-security-policy-report-only" content="策略"><meta http-equiv="Content-Security-Policy" content="default-src 'self' *.xx.com *.xx.cn 'unsafe-inline' 'unsafe-eval';">注意地, 如果 HTTP 头与 Meta 定义同时存在,则优先采用 HTTP 中的定义;如果用户浏览器已经为当前文档执行了一个 CSP 的策略,则会跳过 Meta 的定义;如果 META 标签缺少 content 属性也同样会跳过。
如果meta、响应头里都指定了content-security-policy,则会优先使用响应头里的。 csp的策略格式如下:常见的csp指令有哪些?
CSP指令 作用 default-src 默认所有资源加载策略 script-src 对Javascript的加载策略 style-src 对样式的加载策略 img-src 对图片的加载策略 connect-src 对ajax、webSocket等请求的加载策略 font-src 针对webFont的加载策略 object-src <object>,<embed>和<applet>元素设置允许的类型策略media-src 针对媒体引入的HTML多媒体的加载策略 frame-src 针对frame的加载策略 它们的值可以为
'self','none'等,其他csp指令详细信息请查看:HTTP开发手册
🍑 XSS Filter:对于用户的输入和服务器的输出进行检查,查询输入输出数据中是否包含<、>、、、<script>、javascript等敏感字符,针对用户提交的数据进行有效的验证,只接受我们规定的长度的数据的提交,过滤掉其他的输入内容。如:
- 表单数据指定值的类型:年龄只能是int、name只能是字母数字等
- 过滤或移除特殊的html标签:
<script>、<iframe>、<base>等。 - 过滤js事件的标签:onclick、onerror、onfocus等
🍑 HTML编码或转义: 针对html中不同代码进行对应的编码,实现对抗xss。
- HTML编码函数
HtmlEncode:将字符转换成HTML实体。如&(转&)、<(转<)、>(转>)、"(转")、'(')等。 - script编码函数
JavascriptEncode:将js的事件函数中特殊字符进行编码。 - css编码函数
encodeForCSS:尽可能禁止用户可控制的变量在style标签、html标签的style属性、css文件中输出。 - url地址编码函数
URLEncode:对url中path(路径)或者search(参数)部分进行相应编码,注意地,url的protocol和host部分是不能够使用编码函数的,否则会改变url的语义。
🍑 防御DOM Based XSS:DOM Based XSS产生的原因是从JavaScript中输出数据到HTML页面里,如以下例子
<script>
var x="$var";
document.write("<a href='"+x+"' >test</a>");
</script>
为保护"$var"输出在script标签内,服务器做了一次javaScriptEncode,但是document.write还是会产生XSS,所以对于document.write里的内容分情况处理,如果是输出到事件或者脚本,则要再做一次javascriptEncode;如果是输出到HTML内容或者属性,则要做一次HtmlEncode。
3 跨站点请求伪造(CSRF)
- CSRF(Cross Site Request Forgery):跨站点请求伪造,攻击者诱导受害者访问
第三方网站(WebB),在第三方网站中,向被攻击网站(WebA)发送跨站请求。利用受害者(用户)在被攻击网站(WebA)已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击网站执行某项操作的目的。
🍑 常见的CSRF攻击类型
-
GET类型的CSRF:
<img src="http://bank.example/withdraw?amount=10000&for=hacker" >受害者访问含有这个img的页面后,浏览器会自动向
http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker发出一次HTTP请求。bank.example就会收到包含受害者登录信息的一次跨域请求。 -
POST类型的CSRF:用户访问改页面后,表单会自动提交,相当于模拟用户完成一次POST操作。
<form action="http://bank.example/withdraw" method=POST> <input type="hidden" name="account" value="xiaoming" /> <input type="hidden" name="amount" value="10000" /> <input type="hidden" name="for" value="hacker" /> </form> <script> document.forms[0].submit(); </script> -
链接类型的CSRF:前面两种情况用户打开页面就中招,而链接类只有用户点击链接才会触发。需要一些夸张信息诱导用户点击。,比如:
<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank"> 重磅消息!! <a/>
🍑 CSRF的防御方式
CSRF的两个特点:
1、CSRF通常发生在第三方网站,被攻击的网站无法防止攻击发生
2、CSRF攻击者是不能获取到Cookie等信息,只是使用。
针对这两点,制定相应的附加防御策略:阻止不明外域的访问(同源检测、Samesite Cookie)和提交时要求附加本域才能获取的信息(CSRF Token、双重Cookie验证)。
-
同源检测:
Origin标头和Referer标头来判断url的来源。这两个标头在浏览器发起请求时,大多数情况会自动带上,并且不能由前端自定义内容,服务器可以通过解析这两个标头域名,确定请求的来源域。Referer:会告知服务器请求的原始资源的URL,包含服务器和路径的详细的url,它是存在于所有类型的请求中 缺点:
Referer头不够详尽,哪个请求应该发送Referer,没有清楚说明;Referer请求头会泄露整个URL给别的域,很多时候防病毒方案中都会将Referer请求头直接去掉,以防止URL泄漏敏感数据。Referer:http://example.com/index.htmlOrigin:只包含url的格式、主机名、和端口,Origin字段只存在于POST请求,与Referer不一样的是,Origin字段并没有包含涉及到用户隐私的URL路径和请求内容。
Origin:http://example.com -
SameSite:这是Cookie中的一个属性,它有三个值:
strict(表示完全禁止第三方cookie,也就是在跨站时,均不会携带cookie,只有当前站点的url和访问站点的url一致时,才会携带cookie),Lax(允许我们在跨站的时候使用get请求时携带cookie),None(chrome默认将Lax设置为默认值,将其设置为none,此时必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效)。 -
CSRF Token:csrf无法直接窃取用户的信息,csrf攻击成功原因是服务器误把攻击者发送的请求当成了用户的自己请求。所以要求所有用户请求都携带一个csrf攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常请求和攻击的请求分开。
-
双重Cookie验证:利用CSRF攻击不能获取到用户Cookie,我们可以要求Ajax和表单请求携带一个Cookie的值。采用流程以下:在
用户访问网站页面时,向请求域名注入一个Cookie,内容为随机字符串(csrfcookie=adjaksdjakls);在前端向后端发起请求时,取出Cookie,并添加到url参数上,后端接口验证Cookie中的字段与url参数中的字段是否一致,不一致则拒绝。
🍑 CSRF和XSS的区别?
- CSRF需要用户先登录网站A,获取Cookie;XSS不需要登录。
- CSRF是利用网站A本身的漏洞,去请求网站A的api。XSS是向网站A注入JS代码,然后执行JS里的代码,篡改网站A的内容。
4 点击劫持(ClickJacking)
- 点击劫持(ClickJacking):一种视觉上的欺骗手段,利用透明的按钮或链接做成陷阱,覆盖在web页面之上,然后诱使用户在不知情的情况下,点击链接访问内容的一种攻击手段。这种行为又叫做
界面伪装(UI-Redressing)
🍑 点击劫持有两种攻击方式:
-
攻击者使用一个透明的iframe,覆盖在网页上,然后诱使用户在该页面上进行操作,此时用户在该页面上进行操作,此时用户将在不知情的情况下点击透明的iframe页面。
-
攻击者使用一张图片覆盖在网页,遮挡网页原有位置的含义。
🍑 点击劫持的防御:通过设置HTTP响应首部字段X-Frame-Options,用于控制网站内容在其他Web网站的Frame标签内的显示问题。它有三个值可以配置:
- DENY:浏览器会拒绝当前页面加载任何frame页面。
- SAMEOPTION:frame页面的地址只能为同源域名下的页面。
- ALLOW-FROM origin:允许任何网页通过iframe加载该网页。
5 HTML5安全
🍑 iframe的sandbox:限制iframe执行脚本的权限,使用sandbox属性后,iframe标签加载的内容将被视为一个独立的源,其中的脚本被禁止执行,表单被禁止提交,插件被禁止加载。sandbox有四个值可选:
- allow-same-origin:允许同源访问
- allow-top-navigation:允许访问顶层窗口
- allow-forms:允许提交表单
- allow-script:允许执行脚本
🍑LinkTypes:noreferrer:html5新增的a表签和area标签新增的一个属性:
<a href="xxx" rel="noreferrer">test</a>
# 学习来源
#白帽子讲Web安全(纪念版) -吴翰清