# 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 网站被入侵,泄露了数据库中存储的用户明文密码。则可以用这些用户名、密码尝试登录其它 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 算法,也不能事先准备一个破解字典。
    • 判断两个哈希值是否相同时,无论结果是 True 还是 False ,都应该控制在相同的耗时。
      • 如果使用一般的字符串比较方法(从左到右逐位比较,遇到某一位的字符不同时就返回 False),就可能被攻击者根据处理时长的微小差异,逐位试出哈希值的每一位应该是什么值,大幅降低暴力破解的难度。
      • 使用异或运算就可以控制在相同的处理时长。比如:a ^ b == 0

# 关于通信

# 报文截获

  • 原理:

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

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

# 报文丢失

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

# 关于客户端

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

# 钓鱼网站

  • 原理:

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

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

# 挂马攻击

  • 原理:

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

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

# 键盘记录

  • 原理:

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

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

# 破解客户端

  • 原理:

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

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