Fork me on GitHub

web常见的安全问题及解决方法

前端安全问题

XSS 漏洞

定义:
    跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。
    恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
举例:
1.HTML DOM
    视图(textContent)
        <a href="/user/1">{{ user_name }}</a>
    数据
        <script>alert(1)</script>
    结果
        <a href="/user/1"><script>alert(1)</script></a>
    最基本的例子,如果此处不对 user_name 中的特殊符号进行 escape,就会造成 XSS。
2.HTML Attribute
    视图(attribute)
        <img src="{{ image_url }}">
    数据
        onerror="alert(1)"
    结果
        <img src="" onerror="alert(1)">
    这个例子表明,如果只对尖括号进行 escape 是不够的,很多时候引号也需要被 escape。
    简单来说,对不同输出场景,需要使用不同的 escape 规则。
3.Javascript
        <script>var user_data = {{ user_data|json_encode }};</script>
    数据
        {"exploit": "</script><script>alert(1);//"}
    结果
        <script>var user_data = {"exploit": "</script><script>alert(1);//"};</script>
    这是一个特别的例子,大多数人觉得,对于输出在 <script> 中的内容,json_encode 一下就安全了,其实不然。在这个例子中,XSS 仍然发生了。
解决方案:
    1.在不同上下文中,使用合适的 escape 方式
    2.不要相信任何来自用户的输入,(不仅限于 POST Body,还包括 QueryString,甚至是 Headers)

CSRF 漏洞

定义:    
    CSRF(Cross-site request forgery)跨站请求伪造通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。
    它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。
    与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。
    CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......
    造成的问题包括:个人隐私泄露以及财产安全。    
CSRF攻击攻击原理及过程如下:
   1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
   2. 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
   3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
   4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
   5. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。
   网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。 
举例:    
1.跨站转账
    银行网站A,它以GET请求来完成银行转账的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000
  危险网站B,它里面有一段HTML的代码如下:
  <img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
  首先,你登录了银行网站A保存了cookie,然后访问危险网站B,噢,这时你会发现你的银行账户少了1000块......
  为什么会这样呢?原因是银行网站A违反了HTTP规范,使用GET请求更新资源。
    在访问危险网站B的之前,你已经登录了银行网站A,而B中的<img>以GET的方式请求第三方资源(这里的第三方就是指银行网站了,
    原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站A的Cookie发出Get请求,
    去获取资源“http://www.mybank.com/Transfer.php?toBankId=11&money=1000”,结果银行网站服务器收到请求后,
    认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作......    
解决方案:(让服务器分辨出是真实用户还是攻击者)    
    1.为请求带上 token
    2.验证HTTP Referer字段
        根据HTTP协议,在HTTP头中有一个字段叫Referer,它记录了该HTTP请求的来源地址。
    3.在HTTP头中自定义属性并验证

a链接的安全问题

阐述问题:当a链接有target=”_blank”属性时,必须添加rel=”noreferrer noopener”,不然新产生的页面可以通过window.opener来获取到父窗口的window对象。

1
<a href="www.baidu.com" target="_blank" rel="nofollow me noopener noreferrer" >

聊聊 rel=noopener
关于a标签target=“_blank”使用rel=noopener

后端安全问题

SQL 注入漏洞

问题展示:
    <?php $user = mysql_query('SELECT * FROM USERS WHERE UserName="'.$_GET['user'].'"'); ?>
    那么当请求中 user 参数为 ";DROP TABLE USERS;-- 时,合成的 SQL 语句是:
    SELECT * FROM USERS WHERE UserName="";DROP TABLE USERS;--"
    // 这样将删除表 users
解决方案:
    所有 SQL 语句都使用参数化查询(推荐)或对参数进行 escape(不推荐)

权限控制漏洞

问题展示:
    未经授权可以进行的操作都是权限控制漏洞。
    例如,某些网站的后台操作就仗着「以为用户不知道入口地址」不进行任何权限检查,
    又例如,某些操作可能出现不允许更改的字段被用户递交更改(往往是那些网页上标记为 disabled 或者 hidden 的字段),
    再例如,允许通过 ../ 访问到不应该被访问的文件等(一般存在于 include 中)。
解决方案:
    所有地方都要进行权限检查(如是否已登录、当前用户是否有足够权限、该项是否可修改等),
    总之,不要相信任何来自用户的数据,URL 当然也是。
问题展示:
    Session 和 Cookie 是两种用于存储用户当前状态的工具。
    某些开发者不了解 Session 与 Cookie 的区别,误用或者混用,导致敏感信息泄露或者信息篡改。
    Cookie 存储在浏览器上,用户可以查看和修改 Cookie。
解决方案:
    Session 是存储在服务端的数据,一般来说安全可靠;大多数 Session 都是基于 Cookie 实现的
    (在 Cookie 中存储一串 SESSION_ID,在服务器上存储该 SESSION_ID 对应的内容)。

IP 地址

问题展示:
    首先,用户的 IP 地址一般存储在 REMOTE_ADDR 中,这是唯一的可信的 IP 地址数据(视不同语言而定)。
    然后某些代理服务器,会将用户的真实 IP 地址附加在 header 的 VIA 或 X_FORWARDED_FOR 中(因为REMOTE_ADDR 是代理服务器自身的 IP)。
    所以,要获取用户 IP 地址,一般做法是,判断是否存在 VIA 或者 X_FORWARDED_FOR 头,
    如果存在,则使用它们,如果不存在则使用 REMOTE_ADDR。
    这就产生问题了,X_FORWARDED_FOR 或 VIA 是 HTTP Header,换句话说,它们是可以被伪造的。
    例如,在投票中,如果采信了 X_FORWARDED_FOR,往往意味着被刷票。
解决方案:
    只使用 REMOTE_ADDR 作为获取 IP 的手段。

验证码

问题展示:
    验证码里常见的问题有:非一次性、容易被识别。
解决方案:
    非一次性指的是,同一个验证码可以一直被用下去。一般来说,每进行一次验证码校对(无论正确与否),
    都应该强制更换或清除 Session 中的验证码。
    关于识别问题,在当前科技水平下,不加噪点不加扭曲的验证码几乎是 100% 可识别的。

其他

nodeJs项目重新安装依赖包

rm -rf node_modules
rm package-lock.json
npm cache clear –force
npm install

参考文档:
Web 开发常见安全问题
浅谈CSRF攻击方式

-------------本文结束感谢您的阅读,如果本文对你有帮助就记得给个star-------------
Donate comment here