XSS(Cross-site scripting),给人的第一种感觉好像可以简写为CSS,但由于其容易和层叠样式表(Cascading Style Sheets,CSS)的缩写混淆,所以为其命名时取了cross的谐音x用于区分,这就是XSS这个名称的由来!
其中文名称是“跨站脚本攻击”,是一种网站应用程序的安全漏洞攻击。XSS攻击的原理为:恶意攻击者通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意的script代码到Web网页。当用户加载并执行攻击者恶意制造的网页程序时,嵌入到页面中的script代码会自动执行,从而达到恶意攻击用户的目的。
XSS攻击分为如下几类:反射型、存储型、DOM型,反射型和DOM型可以归类为非持久的XSS攻击,由于存储型XSS攻击会将恶意代码字符串存储到数据库中并被其他用户获取到,所以其也被归类为持久性的XSS攻击。
原理:
攻击者将url中插入xss代码,载体一般是恶意链接,其对应的参数被script代码代替,当用户点击了该链接后,服务端将url中的参数(恶意代码)解析出来并将其与html拼接,输出到页面上并执行。
反射型xss又叫非持久性xss,为什么叫反射型是因为这种攻击方式的注入代码是从目标服务器通过错误信息,搜索结果等方式反射回来的,交互的数据一般不会被存在数据库里面,一次性,所见即所得,一般出现在查询页面等。
实际案例:
用户搜索的关键字会在请求的参数中出现并被服务端解析出来,将其与其他html字符串拼接在一起后渲染到浏览器中,如果发现服务端对关键字没做处理的话,那么就可以在输入框中输入script代码。这样一来,搜索结果渲染到页面的同时,你植入的代码也会被执行。这就完成了一次最简单的XSS攻击。
现在黑客比较常用的套路就是:利用这样的原理,通过电子邮箱等向被攻击者发送一个恶意链接(疑似某著名网站的链接),故意将链接对应的参数改成了恶意js代码,当被攻击方点击并浏览相关的网页,对应的恶意javascript代码被执行。也就在不知情的情况下被获取到了相关的cookie或篡改页面内容.
漏洞成因:
当用户的输入(例如搜索功能的输入框)或者一些用户可控参数(例如提交form表单的操作),这些请求url中的参数被服务端捕捉后未经处理地输出到了页面上,这样就产生了XSS漏洞。
攻击步骤:
1、攻击者在url后面的参数中加入恶意攻击代码
2、当用户打开恶意代码的url的时候,网站服务器端将恶意代码从服务器端提取,拼接在html中并返回给浏览器端
3、用户浏览器接收到响应后执行解析,其中恶意代码就被执行
4、攻击者将通过恶意代码来窃取到用户数据并发送到攻击者网站,攻击者会获取到比如cookie等信息,然后使用信息来冒充用户的行为
原理:
存储型XSS和反射型XSS形成的原因是一样的,不同的是存储型XSS下攻击者的可以将脚本注入到后台存储起来,其他的用户在访问到相关页面时,浏览器会发送请求将服务器中的数据拉到页面时会执行脚本,从而构成更加持久的危害,所以也被归类为持久性的XSS攻击。
实际案例:
存储型XSS 攻击最常发生在由社区内容驱动的网站或 Web 邮件网站,简单来说存储型XSS攻击一般存在于那些具有共享功能的网页中,其不需要点击特制的链接来触发。黑客仅仅需要到一个网站上其他用户可能访问的地方(比如说博客评论,用户评论,留言板,聊天室,HTML 电子邮件,wikis等等许多地方)提交 XSS 攻击代码。一旦用户访问受感染的页,恶意代码是自动执行的。
图 | 存储型XSS攻击后在用户页面下的痕迹(一般来说是直接执行的,这里我为了方便观看制作成了链接)
漏洞成因:
存储型XSS漏洞的成因与反射型的根源类似,不同的是恶意代码会被保存在服务器中,导致其它用户(前端)和管理员(前后端)在访问资源时执行了恶意代码。简而言之,提交的代码会存储在服务器端,不用再提交XSS代码,所以其被称为持久性攻击。
攻击步骤:
1、攻击者在网站的评论等功能模块将恶意代码伪造成评论发送请求至服务端,该恶意代码会被存储在数据库中
2、当其他用户打开含有该恶意代码的页面时,浏览器会发送请求将恶意代码从服务器端获取并渲染到页面中
3、浏览器渲染到恶意代码时会将其执行,窃取到用户数据后发送到攻击者网站,攻击者会获取到比如cookie等信息,然后使用信息来冒充用户的行为
原理:
我们客户端的js可以对页面dom节点进行动态的操作,比如插入、修改页面的内容,比如客户端从输入框中提取数据并且在本地执行、如果用户在输入框输入的数据包含了恶意的js脚本的话,但是这些脚本又没有做任何过滤处理的话,那么我们的应用程序就有可能受到DOMXSS攻击。
漏洞成因:
DOM型XSS是基于DOM文档对象模型的。对于浏览器来说,DOM文档就是一份XML文档,当有了这个标准的技术之后,通过JavaScript就可以轻松的访问DOM。当确认客户端代码中有DOM型XSS漏洞时,诱使(钓鱼)一名用户访问自己构造的URL,利用步骤和反射型很类似,但是唯一的区别就是,构造的URL参数不用发送到服务器端,可以达到绕过WAF、躲避服务端的检测效果。
实际案例:
这里有段JS代码,它通过 getElementById 获取到了标签 Id 为 text的内容赋值给str,然后又把 str 的内容通过字符串拼接的方式写到了 a 标签的 href 属性中,a标签会写到 Id 为 dom的 div 标签中,整个过程并没有服务端的参与。
预防方法:
满足XSS攻击的基础条件有两个:1. 攻击者提交恶意代码。 2. 浏览器执行恶意代码。所以要尽可能的对这两种情况进行防范,下面提供几种预防方案!
1.对用户的输入进行合理验证(如年龄只能是数字),对特殊字符(如<
、>
、'
、"
以及 、
javascript
等进行过滤。
2.根据数据将要置于 HTML上 下文中的不同位置(HTML 标签、HTML 属性、JavaScript 脚本、CSS、URL),对所有不可信数据进行恰当的输出编码。在使用 .innerHTML、.outerHTML、document.write()时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用.textContent、innerText、.setAttribute() 等。
3、DOM 中的内联事件监听器,如 location、onclick、onerror、onload、onmouseover等, 标签的href属性,JavaScript 的eval()、setTimeout()、setInterval()等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易 产生安全隐患,请务必避免。
4.设置 HttpOnly 属性,这样客户端脚本将无法访问cookie,可以避免攻击者利用跨站脚本漏洞进行 Cookie 劫持攻击。
(其实简单理解就是,返回参数不要和请求参数一致,对用户输入的参数进行验证,确保没有包含 HTML 或 JS 等代码)
防范 XSS 是不只是服务端的任务,前端的过滤在此过程中也起到了至关重要的作用,所以防范操作需要后端和前端共同参与。虽然很难通过技术手段完全避免XSS,但我们原则上减少漏洞的产生。
原理:
CSRF(Cross-Site Request Forgery)中文名为跨站请求伪造,相信从名字中你大概猜到它是干什么的:攻击者(黑客,钓鱼网站)盗用了你的身份,通过伪装来自受信任用户的请求来利用受信任的网站,以你的名义发送恶意请求,这些钱请求包括发送邮件、发送信息、盗取账号、购买商品、银行转账等等一系列恶意操作。
通俗的说就是攻击者利用了你的身份,发送了恶意请求。就好比黑客盗用了你的qq然后假装是你,骗你朋友要钱。
依赖条件:
1、一些HTML标签具有原生的跨域能力,例如超链接标签a的href属性、img标签的src属性、script标签和style标签等等
2、浏览器向对应API发送请求时会自动携带上cookie
3、用户已经登录受信任的网站A,并且在本地生成了cookie
4、在不登出网站A的情况下,访问危险网站B
图 | CSRF大致的攻击流程图
攻击流程:
1、用户在一个正常的页面下浏览并且登录了该网站
2、在这个网站没有关闭的情况下,用户又打开了一个恶意的网页(上面植入了一些恶意的代码),它会伪造一个正常的报文去向正常服务器发送请求,由于用户的cookie处于登录态,所以只要伪造的请求跟正常的一样,浏览器在发送请求的时候就会自动携带上cookie,从而也就能够实现删除帖子、发布帖子等一系列操作
实际案例:
通常是用户浏览一个处于登录状态下的页面,在没有关闭该页面的情况下,用户点击了黑客提前或恰好发送的电子邮件,其中具有包含恶意网页的url的链接(这里利用了href的原生跨域能力),当用户点击链接后,恶意网页会联系其服务器一起去仿造一个请求报文去向正常服务器中发送请求伪造成用户去执行恶意操作(这里利用了浏览器发送请求自动携带cookie的特性)
预防方法:
1、为请求头加上一个referer字段,其指向跳转页面之前或者发送请求的那个页面url,这样服务端就知道请求源在哪里,对其进行验证即可知道是在哪个页面发送的请求,要不要为其执行操作和响应数据。但有一些低版本的浏览器,比如说ie6,黑客可以将referer抹平后进行攻击,这样服务器就没有办法识别了
2、由于浏览器发送请求的时候会携带cookie,但因为攻击者在恶意网站中由于同源政策的限制,其并不可以跨域访问到另一个域下面的cookie,所以我们可以跟后台进行协商,通过在cookie中取某一个字段作为验证的筹码,这样就可以判断请求是不是恶意发送的了,这种方法也被称为cookie双重验证
3、第三种方法比较直接干脆一点,直接使用token代替cookie,由于每次发送需要用户权限的请求都需要携带token或者将token放置在请求头的某处,浏览器不会自动携带。通常token会以本地存储的方式寄存到浏览器中,而恶意网页不具备跨域访问token的能力,自然也不能成功的执行操作,这也是现在市面上大部分API接口的使用方法
概念的区别:
CSRF:因为该攻击是通过仿造请求去访问需要用户权限的API,这个操作必须要携带上cookie。而只有在用户处于登录态下才会生成cookie,所以执行该类攻击的基础操作是用户已经登录页面并未关闭
XSS:因为该类攻击的操作不一定是获取cookie模仿用户操作,还有可能是利用js代码篡改网页的内容等等,所以不一定需要用户一定处在登录状态
原理上的区别:
CSRF:是利用网站本身的漏洞,比如发送请求自动携带cookie,html标签的原生跨域能力等等
XSS:向网站中注入JS代码,篡改网站的内容,调节恶意服务器请求头上的某个字段可以使得所有网页均可访问该服务器,让恶意代码获取到用户信息后可以发送到其设置好的服务器上进行后续操作
以上就是我对CSRF攻击和XSS攻击的基本了解,可能有部分地方还存在疏漏和错误,欢迎大家前来指正!