Web应用防火墙(WAF)

2017 年,某电商平台遭遇了一次大规模数据泄露,数千万用户的账户信息被窃取。事后分析发现:攻击者利用了 Web 应用中的一个 SQL 注入漏洞,而平台已经部署了防火墙和 IDS。

问题出在哪里?传统防火墙和 IDS 针对的是网络层攻击,它们无法理解 HTTP 协议的应用层语义。SQL 注入的恶意请求伪装成正常的数据库查询语句,通过了所有网络层检测。

Web 应用防火墙(WAF)就是为了解决这个问题而诞生的。它是 Web 应用的安全门卫,理解 HTTP 语义,能够识别和阻止应用层攻击。

WAF 的定义与作用

WAF 是一种专门用于保护 Web 应用的安全设备或服务。它位于 Web 服务器之前,检查 HTTP/HTTPS 请求和响应,识别并阻止恶意流量。

WAF 与传统防火墙的区别

维度传统防火墙WAF
协议层网络层/传输层应用层
检测对象IP、端口、包HTTP URL、参数、Header、Cookie
规则类型端口、IP 访问控制签名、行为、机器学习
防护场景网络层攻击应用层攻击
SSL/TLS透传或简单终止深度检测加密流量

WAF 的部署模式

1. 反向代理模式

WAF 作为反向代理部署在 Web 服务器之前:

  • 所有客户端请求先到 WAF
  • WAF 检测后转发给后端服务器
  • 服务器响应先到 WAF,WAF 检查后再返回客户端

优点:完整检测和过滤,保护范围广 缺点:所有流量经过 WAF,是性能瓶颈点

2. 透明桥接模式

WAF 以「透明网桥」方式串接在网络中:

  • 对客户端和服务器都是透明的
  • 不改变网络拓扑
  • 需要物理旁路保护

优点:部署简单,不影响现有网络 缺点:无法终止 SSL,只能检测明文流量

3. 旁路模式(镜像检测)

WAF 通过镜像流量进行检测:

  • 交换机/ TAP 复制流量到 WAF
  • WAF 只检测,不阻断
  • 发现攻击时发送 RST 阻断或联动防火墙

优点:不影响正常业务,对性能无影响 缺点:无法实时阻断,依赖联动机制

4. 云 WAF 模式

流量通过 DNS 牵引到云端 WAF:

  • 攻击流量在云端清洗
  • 正常流量回源到源站

优点:弹性扩展,防御大规模 DDoS 缺点:需要 DNS 改造,延迟略有增加

WAF 的检测技术

签名检测(Signature-Based)

基于已知攻击特征库进行匹配:

# 简化示例:SQL 注入检测规则
rules:
  - name: sql-injection-classic
    pattern: "(?i)(union.*select|select.*from|insert.*into|delete.*from|drop.*table)"
    action: block
    severity: high
    
  - name: sql-injection-encoded
    pattern: "(%27|%22|%3D|%3E|%3C|%2D|%2B|%2F|%5C)"
    context: url_param
    action: block
    severity: medium

优点:检测准确率高,误报率低 缺点:无法检测未知攻击

行为检测(Behavior-Based)

基于正常用户行为建立基线:

  • 正常请求的 URL 模式、参数类型、访问频率
  • 异常行为:短时间内大量请求、异常参数、超长请求
// 简化示例:基于速率的异常检测
public class RateLimitDetector {
    private final Map<String, RateWindow> clientStats = new ConcurrentHashMap<>();
    private static final int MAX_REQUESTS_PER_MINUTE = 100;
    
    public DetectionResult detect(String clientIp, String requestUri) {
        RateWindow window = clientStats.computeIfAbsent(
            clientIp, k -> new RateWindow()
        );
        
        if (window.incrementAndGet() > MAX_REQUESTS_PER_MINUTE) {
            return DetectionResult.builder()
                .threat(true)
                .reason("Rate limit exceeded")
                .score(0.9)
                .build();
        }
        
        // 检测异常扫描行为
        if (window.getUniqueUris().size() > 1000) {
            return DetectionResult.builder()
                .threat(true)
                .reason("Possible directory scanning")
                .score(0.8)
                .build();
        }
        
        return DetectionResult.builder().threat(false).build();
    }
}

机器学习检测

现代 WAF 使用 ML 模型识别新型攻击:

  • 学习正常流量模式
  • 检测偏离正常模式的请求
  • 自动适应应用的变化

优点:能检测未知攻击 缺点:需要大量训练数据,误报率可能较高

WAF 的核心功能

1. SQL 注入防护

识别试图在 SQL 查询中注入恶意代码的请求:

// 攻击示例
// 正常查询: SELECT * FROM users WHERE id = 1
// 注入攻击: SELECT * FROM users WHERE id = 1 OR 1=1

// WAF 检测点
public class SqlInjectionDetector {
    // 检测常见的 SQL 注入模式
    public boolean isSqlInjection(String input) {
        String[] sqlKeywords = {
            "union", "select", "insert", "update", "delete",
            "drop", "exec", "execute", "script", "javascript"
        };
        
        String lowerInput = input.toLowerCase();
        for (String keyword : sqlKeywords) {
            if (lowerInput.contains(keyword)) {
                // 进一步分析上下文,区分正常内容和注入
                if (looksLikeInjection(lowerInput, keyword)) {
                    return true;
                }
            }
        }
        return false;
    }
}

2. XSS(跨站脚本)防护

检测试图在网页中注入恶意 JavaScript 的请求:

  • 反射型 XSS:URL 参数中嵌入脚本
  • 存储型 XSS:表单提交中嵌入脚本
  • DOM 型 XSS:客户端 JavaScript 处理用户输入

3. CSRF(跨站请求伪造)防护

验证请求是否来自合法的来源:

// CSRF Token 验证
public class CsrfProtectionFilter {
    public boolean validateRequest(HttpRequest request) {
        String csrfToken = request.getHeader("X-CSRF-Token");
        String sessionToken = sessionManager.getCsrfToken(request.getSessionId());
        
        // Token 存在且匹配
        if (csrfToken != null && csrfToken.equals(sessionToken)) {
            // 验证 Referer/Origin 头
            String referer = request.getHeader("Referer");
            String origin = request.getHeader("Origin");
            return isValidOrigin(referer, origin, request.getHost());
        }
        
        return false;
    }
}

4. 命令注入防护

检测试图在系统命令中注入恶意命令的请求:

  • Shell 注入:; cat /etc/passwd
  • 命令替换:`whoami`
  • 管道注入:| ls -la

WAF 的绕过技术简介

知己知彼,了解 WAF 绕过技术才能更好地防御:

编码绕过

  • URL 编码:%27 = '%3D = =
  • 双重编码:%2527
  • Unicode 编码:\u0027

大小写混合

  • SQL 不区分大小写:UnIoN SeLeCt
  • 过滤器只检查小写时可用

注释注入

  • 内联注释:UN/**/ION SEL/**/ECT
  • 注释替代空格:SELECT/**/*/**/FROM

HTTP 协议混淆

  • 分块传输编码
  • HTTP/2 协议头部注入
  • 协议版本混淆

WAF 的性能影响

组件性能影响说明
SSL/TLS 终止中等需要解密/加密流量
规则匹配低-中等取决于规则数量
机器学习中等实时推理开销
日志记录异步处理可降低影响

优化策略:

  • 使用硬件加速(SSL 卸载)
  • 规则预编译
  • 白名单跳过不检测的路径
  • 异步日志处理

云 WAF vs 自建 WAF

维度云 WAF自建 WAF
部署速度快(分钟级)慢(周级)
扩展性弹性受限于硬件
DDoS 防护内置需要单独方案
成本订阅制,可预测前期投入大
自定义规则支持完全可控
数据隐私部分出站完全可控
维护负担云厂商负责自行维护

代表产品:Cloudflare WAF、AWS WAF、Azure Application Gateway、阿里云 WAF

关键洞察

WAF 不是银弹。它只能保护 Web 应用,无法防止业务逻辑漏洞(如垂直越权、水平越权)。真正的安全需要 WAF + 安全编码 + 渗透测试 + 员工培训的综合防护。

思考题

问题 1:WAF 的误报可能阻断正常用户的请求。在不影响安全性的前提下,如何降低 WAF 的误报率?

参考答案

误报管理是 WAF 运营的核心挑战。以下是系统性降低误报的方法:

第一阶段:学习模式

  • 上线初期使用「检测模式」(只告警不阻断)
  • 收集所有告警,分析是否为真实攻击
  • 根据分析结果调整规则

第二阶段:精细化规则

# 避免误报的精细化规则示例
# 宽泛规则(误报率高)
- name: "block-sql-keywords"
  pattern: "select.*from"
  action: block  # 误报:正常用户搜索 "select from"
  
# 精细化规则(低误报)
- name: "block-sql-injection"
  pattern: "(union.*select|select.*from.*where.*=.*['\"])"
  context: 
    - parameter_name: ["id", "user_id", "category"]
    - content_type: ["application/x-www-form-urlencoded"]
  negative_pattern: "^\\d+$"  # 排除纯数字参数
  action: block

第三阶段:建立白名单

  • 内部工具的正常请求模式
  • 第三方集成的特殊 Header
  • 监控探针的健康检查请求

第四阶段:用户画像

  • 识别不同用户群体的正常行为
  • 对高信任用户降低检测强度
  • 对异常用户提高检测强度

第五阶段:渐进式阻断

  • 发现可疑请求时,不直接阻断
  • 先返回验证码或挑战页面
  • 通过验证后才放行

问题 2:在 API 保护场景下,WAF 如何处理 API 的参数校验和协议合规性?

参考答案

API 保护需要 WAF 具备协议层和语义层的检测能力:

协议层合规性

# API 协议合规规则示例
api_compliance:
  - name: "enforce-json-content-type"
    condition: "request.content_type != 'application/json'"
    action: block
    severity: high
    
  - name: "enforce-api-version"
    condition: "request.header['API-Version'] not in ['v1', 'v2']"
    action: block
    
  - name: "rate-limit-per-api-key"
    limit: 1000
    window: 60  # per second
    key: "request.header['X-API-Key']"

参数校验

# 参数校验规则
parameter_validation:
  - name: "validate-user-id"
    path: "/users/{userId}"
    parameter: "userId"
    type: "integer"
    min: 1
    max: 1000000
    
  - name: "validate-email-format"
    path: "/users"
    parameter: "email"
    pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
    
  - name: "validate-json-schema"
    path: "/orders"
    parameter: "body"
    schema: "order.schema.json"

API 速率控制

# 速率控制策略
rate_limiting:
  - name: "per-user-rate-limit"
    key: "authenticated_user"
    limit: 100
    window: 60
    
  - name: "per-api-endpoint-limit"
    key: "request.path"
    limits:
      "/api/search": 20  # 更严格的限制
      "/api/batch": 5
      "/api/export": 1

异常行为检测

  • 检测 API 参数结构的异常变化
  • 检测异常的批量请求模式
  • 检测 API 密钥的滥用

推荐产品:AWS WAF + API Gateway、Kong、Apigee