一、前言
HTTP 协议具有无状态、不连接、尽最大努力的特点,对于 Web 网站的攻击基本也是针对 HTTP 协议的这些特点进行的。比如无状态的特点,就要求开发者需要自行设计开发"认证"和"会话管理"功能来满足 Web 应用的安全,而形形色色的自行实现,也为用户会话劫持、SQL 注入等攻击埋下了风险;而不连接的特点表示客户端可以肆意的修改 HTTP 的请求内容,而服务端可能会接收到与预期数据不相同的内容。
Web 漏洞中,逻辑漏洞占比最大,逻辑漏洞是指由于程序逻辑不严或逻辑太复杂,导致一些逻辑不能够正常处理或处理错误,一般出现在支付金额、越权访问、信息查询、登陆认证等地方。逻辑漏洞很大的一部分原因是因为对代码的不够认真和对客户的过于信任,比如返回数据中包含用户敏感信息、登录认证存在撞库风险等
技术漏洞攻击指的是用户通过一定的技术手段,利用攻击代码达到自己非法获取信息、身份伪装等目的。技术漏洞攻击可以分为主动攻击和被动攻击。
主动攻击(active attack)是指攻击者通过直接访问 Web 应用,把攻击代码植入的攻击模式。具有代表性的攻击是 SQL 注入攻击和 OS 命令注入攻击。
被动攻击(passive attack)是指利用圈套策略执行攻击代码的攻击模式,比如利用钓鱼网站诱使用户点击等。具有代表性的攻击是跨站脚本攻击(XSS)和跨站点请求伪造(CSRF)。
二、主动攻击
1. SQL 注入
SQL注入(SQL Injection) 是指针对 Web 应用使用的数据库,通过运行非法的 SQL 而产生的攻击。简单点来说,就是通过表单输入的内容,诱使服务器拼接成一个非法的 SQL。比如有一个正常的 SQL 语句如下:
SELECT * FROM user WHERE name='张三' and password = '123456'
正常情况下,用户输入用户名“张三”和密码“123456”(正常来说,密码要 MD5 加密处理)完成认证过程。
假设用户名输入的用户名是“张三'--”,我们来看看 SQL 会变成啥样?SQL 语句中的 -- 之后全视为注释,用户就成功绕过了认证。
SELECT * FROM user WHERE name='张三'--' and password = '666666'
常见的预防 SQL 注入的手段就是 SQL 语句预编译处理。
2. OS 命令注入攻击
OS 命令注入攻击(OS Command Injection)是指通过 Web 应用,执行非法的操作系统命令达到攻击的目的。OS 命令注入攻击可以向 Shell 发送命令,让 Windows 或 Linux 操作系统的命令行启动程序。也就是说,通过 OS 注入攻击可执行 OS 上安装着的各种程序。
OS 命令注入和 SQL 注入类似,SQL 注入伪造的是非法 SQL,OS 命令注入伪造的是非法 shell 命令。
常见的预防 OS 注入的手段是对 shell 执行的符号进行转码替换(比如 &&、&、| 等)。
3. Dos 攻击
DoS 攻击(Denial of Service attack)是一种让运行中的服务呈停止状态的攻击。有时也叫做服务停止攻击或拒绝服务攻击。DoS 攻击的对象不仅限于 Web 网站,还包括网络设备及服务器等。
Dos 攻击简单点理解就是发送大量的合法请求,造成服务器资源过载耗尽,从而使服务器停止服务。(由于服务器很难分辨何为正常请求,何为攻击请求,因此很难防止 DoS 攻击。)
Dos 攻击还可通过攻击安全漏洞使服务停止。
三、被动攻击
1. XSS 攻击
跨站脚本攻击(Cross-Site Scripting, XSS)是指通过在用户的浏览器内运行非法的 HTML 标签或 JavaScript 向存在安全漏洞的 Web 网站进行的一种攻击。攻击者编写脚本设下陷阱,用户在自己的浏览器上运行时,一不小心就会受到被动攻击。
常见的 XSS 攻击比如虚假输入表单骗取用户个人信息、窃取用户 Cookie 发送恶意请求 等。
常见的预防 XSS 攻击的手段比如对 HTML 标签、JavaScript 进行转义处理、禁止 JavaScript 读取 Cookie 等。
2. CSRF 攻击
跨站点请求伪造(Cross-Site Request Forgeries,CSRF)攻击是指攻击者通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信息或设定信息等某些状态更新。
常见的预防 CSRF 攻击的手段比如:验证 Referer + POST 提交、增加 token 认证等。
3. HTTP 首部注入攻击
HTTP 首部注入攻击(HTTP Header Injection)是指攻击者通过在响应首部字段内插入换行,添加任意响应首部或主体的一种攻击。比如重定向至任意的 URL、替换掉要返回的主体内容等。
比如存在某个需要重定向的页面,本来的 header 信息是这个样子的:
Location: http://example.com/?cat=101
因为重定向需要带回参数,攻击者就诱使用户在参数中加入攻击代码 —— 加入或替换任意的 header 信息。(下面这个 Location 可能不会生效,不同的浏览器对重复的 header 字段有不同的处理方式)
Location: http://example.com/?cat=101(%0D%0A:换行符)
Location: http://xxx.com
常见的预防 header 注入攻击的方式就是添加 SSL/TLS 认证,也就是启用 HTTPS。
4. 会话劫持攻击
会话劫持(Session Hijack)攻击是指攻击者通过某种手段拿到了用户的会话 ID,并非法使用此会话 ID 伪装成用户,达到攻击的目的。
常见的预防会话劫持的手段比如:将会话 ID 和用户设备信息绑定在一起,当用户在其他设备上使用该会话 ID 时,就会提示被盗用风险,要求用户重新登录。
四、我们能做什么?
- 输入值验证。检查数值是否符合系统业务逻辑或检查字符编码,永远不要相信用户的输入,注意不要依赖客户端验证,客户端验证的目的只是为了尽早的辨识输入错误,起到提高 UI 体验的作用(客户端验证可被修改绕过)。
- 输出值转义。比如对 HTML 标签、JavaScript 进行转义处理再输出,避免存在攻击代码。
- Web 应用不直接抛出异常,或谨慎输出错误提示,防止被攻击者利用。
- 敏感字段,比如密码,进行加 salt 加密处理,防止被暴力破解(比如常见的 彩虹表)。
- 签名认证,防止数据被篡改。客户端设置签名,服务端校验签名是否正确。
- 禁止开放重定向(Open Redirect)功能,防止被攻击者选中并用来作为钓鱼攻击的跳板。
- 涉及到登录口的地方,增加图形验证码,防止爆破机器人。
- 上线前将一些测试接口或后门程序删除,避免被攻击者利用。
- 不要将公司代码传到公共仓库。