# Web 安全

# 关于前端

# XSS

:跨站脚本攻击(Cross Site Scripting)

  • 原理:
    • 攻击者向网页源代码中注入恶意代码,然后被浏览器执行。
  • 按注入方式分类:
    • 反射型:如果网页源代码会从 URL 中提取参数,则可以把恶意代码写入到 URL 中,诱使用户点击该链接,当用户跳转之后就被注入了恶意代码。
    • 存储型:将恶意代码作为表单内容(比如留言栏)上传到服务器。当其他用户在浏览器中查看该内容时,恶意代码就会被执行。
  • 按攻击来源分类:
    • 恶意网站 B 与网站 A 不在同一个域名下。
    • 恶意网站 B 与网站 A 在同一个域名下,比如子应用。
  • 对策:
    • 服务器不应该信任前端发来的数据,总是要检查该数据是否合法。

# CSRF

:跨站请求伪造(Cross-site request forgery)

  • 原理:
    • 用户访问网站 A 时,一般会保持 session 或留下 cookies 。此时攻击者诱使用户点击网站 B 中的一个链接,该链接是向网站 A 发送一个 HTTP 请求,这样就能冒用用户的身份访问网站 A ,执行冒名操作。
  • 对策:
    • 服务器检查每个 HTTP 请求的 Origin 或 Referer 字段,如果是跨站发来的请求就拒绝。
      • 不过这可能拦截从搜索引擎跳转过来的正常用户请求,也无法防御客户端故意伪造的请求。
    • 向网页源代码中加入一个随机 token ,当用户发出 HTTP 请求时都要带上该 token ,证明请求是从该网页发出的。
      • 例如在请求的 URL 中加入 token :http://www.test.com?csrftoken=123456
      • 例如在 POST 表单里加入 token :<input type="hidden" name="csrftoken" value="123456"/>

# 关于后端

# DoS

  • 拒绝服务(Distributed Denial of Service ,DoS)攻击
    • :攻击者发出大量请求到服务器,使服务器处于忙碌状态,消耗带宽、CPU、内存等资源,导致不能处理其他正常用户的请求。
  • 分布式拒绝服务(Distributed Denial of Service ,DDoS)攻击
    • :与 DoS 相比,攻击者会操纵大量 IP 不同的主机作为客户端,或者使用大量 IP 不同的代理。
  • 攻击方法举例:
    • Smurf :攻击者冒充目标主机的 IP 地址向大量主机发送广播消息,导致目标主机被大量的应答消息冲击。
    • Land :发送源地址和目的地址都是目标主机的 IP 地址的数据包,导致目标主机反复接收和发送该数据包,浪费资源。
    • ICMP Flood :向服务器发出大量 ICMP 数据包,产生流量洪水。
    • UDP Flood
    • NTP Flood
    • DNS Query Flood
    • SYN Flood :向服务器发出大量 SYN=1 的 TCP 包,请求建立连接,但并不完成 TCP 握手的第三步。导致服务器上产生大量等待握手的连接,消耗大量资源。
    • CC 攻击 :向服务器发出大量合法的 HTTP 请求,导致服务器处于忙碌状态。
  • 对策:
    • 提高服务器本身的性能,比如网络带宽。
      • 缺点:性价比很低,因为服务器扩容的成本比 DDoS 攻击的成本高很多。
    • 租用某些平台的高防 IP ,让该平台对访问流量进行清洗、过滤之后再发给服务器处理。
      • 优点:容易使用,可以防御常见类型的 DDoS 攻击。
      • 缺点:价格较贵。
    • 对访问 IP 设置黑名单。
      • 优点:成本很低。
      • 缺点:容易防御 DoS 攻击,但难以防御 DDoS 攻击,因为难以区分攻击者的 IP 与正常用户的 IP 。
    • 将一些经常被访问的资源通过 CDN 缓存,从而减轻源服务器的负载。
      • 缺点:效果低,只能防御少数类型的攻击。

# 非授权访问

  • 原理:

    • 攻击者没有访问权限,但是通过服务器的某个漏洞非法访问了服务器资源,比如私密数据。
    • 授权用户越权访问也属于非授权访问。
  • 对策:

    • 做渗透测试,修补漏洞。

# 冒名访问

  • 原理:

    • 攻击者冒充某个用户的身份,获得其对服务器的访问权限。
    • 最严重的情况是,攻击者窃取到某个用户的用户名及密码,通过正常流程登录,难以判断出该用户是冒充的。
  • 对策:

    • 保证正确鉴定每个访问者的身份,按身份给他们分配权限。(比如分成未登录者、普通用户、管理员)
    • 服务器可以根据登录 IP 异常、敏感操作等信息推测出登录的用户是否为本人,

# 越权访问

  • 原理:

    • 攻击者作为一个正常用户登录之后,访问到该用户无权访问的资源。
  • 对策:

    • 保证对所有资源(比如文件、端口)加上权限控制,收到访问请求时总是验证其访问权限。

# SQL 注入

  • 原理:

    • 攻击者在客户端上传的表单数据中,插入恶意的 SQL 代码,等待被服务器误执行。
  • 对策:

    • 服务器不能相信客户端或前端发来的数据,必须先检查其格式是否正确、是否包含非法字符。

# 关于密码

Web 服务器不应该直接储存用户的明文密码,而应该储存密码的哈希值,这样既可以检验用户输入的密码是否正确,还能防止 Web 服务器泄露用户的明文密码。

# 暴力破解密码

  • 原理:

    • 当攻击者只知道用户的账号、不知道密码时,可能反复尝试用各种可能的密码登录,直到猜出用户的正确密码。
  • 攻击方法举例:

    • 穷举法
      • 原理:生成所有可能的密码字符组合,逐个尝试。
      • 缺点:需要尝试的次数太多,耗时久。
    • 字典法
      • 原理:将人们常用的密码保存为一个字典,逐个尝试。
      • 缺点:需要用大量的存储空间来保存字典。
  • 对策:

    • 要求用户使用强密码。 比如使用大小写字母加数字,每位字符有 26+26+10=62 种可能性,密码长度为 12 时有 3*10e21 种可能性,即使每秒尝试 1 亿次,也要 100 万年才能穷举完所有可能的密码。
    • 当客户端连续三次输错密码之后就冻结其账号,禁止登录。在一段时间之后才解锁,或者只能通过更安全的身份认证方式登录,比如手机验证码。
    • 要求客户端在登录时输入验证码,使得攻击者难以用软件自动化尝试大量密码。

# 加密密码

  • Web 服务器可以将用户明文密码的哈希值存储在数据库中,只要用户下次输入的密码的哈希值相同,就判断密码正确。
    • 这种情况下,即使攻击者入侵了 Web 服务器,得到数据库的访问权限,也只能看到密码的哈希值,无法知道对应的明文密码。
  • 不过,通过以下攻击方法,依然可能暴力破解出哈希值对应的明文密码:
    • 穷举法
    • 字典法
      • 原理:事先记录人们常用的密码及其对应的哈希值。当目标哈希值与字典中某项匹配时,就可以知道对应的明文密码。
    • 彩虹表
      • 原理:
        • 先探明 Web 服务器采用的是哪种 Hash 算法,表示成函数 H() 。再拟定函数 R(),用于将哈希值 h 转换成另一个字符串 p 。然后选择一个字符串 p1 作为起点,依次计算出 h1=H(p1)、p2=R(h1)、h2=H(p2)、…… ,这样就得到了一条哈希链,记录其中的所有 p 。
        • 选取多个 p1 ,就可以算出多条哈希链,得到一个彩虹表。
        • 想破解某个哈希值 s 时,先计算 R(s) ,然后到彩虹表中寻找是否有与之相同的 p 值。假设 pn 的值与 R(s) 相同,则 s 对应的明文密码就是 pn-1 。
      • 使用彩虹表时比字典法少了一半的存储空间,又比穷举法快。
  • 针对上述攻击方法,Web 服务器可采用以下对策:
    • 选用哈希值更长、加密更慢的 Hash 算法,增加暴力破解的试错成本。
    • 每次计算密码的哈希值时,加上一个随机的、无法预测的值,称为盐。
      • 这样即使攻击者知道了服务器采用的 Hash 算法,也不能事先准备一个破解字典。
      • 服务器应该将每个用户密码与盐值一起保存到数据库中。
    • 判断两个哈希值是否相同时,无论结果是 True 还是 False 甚至出错,都应该控制在相同的处理时长。
      • 如果使用一般的字符串比较方法(从左到右逐位比较,遇到某一位的字符不同时就返回 False),就可能被攻击者根据处理时长的微小差异逐位试出哈希值的每一位应该是什么值。
      • 使用异或运算就可以控制在相同的处理时长。比如:a ^ b == 0

# 关于通信

# 报文截获

  • 原理:

    • 攻击者截取到客户端与服务器的通信报文,从其中窃取重要数据。
  • 对策:

    • 使用 HTTP 协议通信会暴露报文内容,应该使用 HTTPS 协议进行加密通信。

# 报文丢失

:Web 服务器通信过程中的某些报文被丢失。可能是网络原因,也可能是遭到攻击者攻击。

# 关于客户端

即使 Web 网站本身足够安全,用户也可能在访问该网站之前就被攻击,因此还需要考虑客户端的安全问题。

# 钓鱼网站

  • 原理:

    • 攻击者建立一个恶意网站(可能还会伪装成正常网站),诱使用户访问该网站。当用户访问该网站时,一不小心就下载了木马或病毒。
    • 或者攻击者将恶意网站伪装成目标网站(页面、域名相像),诱使用户登录该网站。当用户登录时,就将自己的用户名、密码泄露给了攻击者。
  • 对策:

    • 使用安全工具检测用户的电脑运行环境。

# 挂马攻击

  • 原理:

    • 攻击者成功入侵网站服务器,在网页中嵌入恶意代码。当用户访问网页时,就会植入木马。
  • 对策:

    • 用户在电脑上安装安全工具,保护自己。

# 键盘记录

  • 原理:

    • 攻击者用工具记录用户的键盘输入,窃取到用户输入的密码。
  • 对策:

    • 让用户使用 Web 网页上的位置随机的图形键盘输入密码。

# 破解客户端

  • 原理:

    • 攻击者下载了客户端程序或 Web 网页之后,看穿其运行原理,绕过其中的访问限制或截取重要信息。
  • 对策:

    • 不要将重要的信息保存在客户端,不要依靠客户端进行安全验证等操作,因为那不可靠。