如何避免request.getRequestURI()引发的SSRF漏洞?
解决Checkmarx SSRF告警的方案
你的现有校验存在两个核心问题:正则允许路径遍历字符(.),且未限制请求目标的合法性,导致Checkmarx判定存在SSRF风险。以下是具体修复步骤:
1. 收紧正则校验规则
原正则^\/[/.a-zA-Z0-9-?&=]+$允许.,攻击者可构造/../internal-api这类路径访问内部资源。替换为更严格的正则:
// 禁止路径遍历(../),仅允许合法路径字符和查询参数 decodedUri.matches("^(?!.*\\.\\./)\\/[a-zA-Z0-9-\\/?&=]+$");
如果仅允许指定前缀的路径(比如仅允许/api/开头),可进一步限制:
decodedUri.matches("^(?!.*\\.\\./)\\/api\\/[a-zA-Z0-9-\\/?&=]+$");
2. 增加路径白名单校验
仅靠正则不足以完全规避风险,需配合白名单限制允许访问的路径:
// 预定义合法路径或路径模式 Set<String> allowedPaths = Set.of("/api/users", "/api/products"); // 允许动态路径(比如/api/items/{id})可使用路径匹配器 AntPathMatcher matcher = new AntPathMatcher(); boolean isAllowed = allowedPaths.contains(decodedUri) || matcher.match("/api/items/*", decodedUri); if (!isAllowed) { throw new IllegalArgumentException("非法请求路径"); }
3. 限制请求目标的协议与主机
如果你的代码会用decodedUri构造HTTP请求发起调用,必须严格校验目标地址:
// 假设baseUrl是你允许的基础地址 URL targetUrl = new URL(baseUrl + decodedUri); // 仅允许HTTP/HTTPS协议 if (!Set.of("http", "https").contains(targetUrl.getProtocol())) { throw new IllegalArgumentException("不允许的协议"); } // 校验目标主机是否在白名单内 Set<String> allowedHosts = Set.of("your-domain.com", "api.your-domain.com"); if (!allowedHosts.contains(targetUrl.getHost())) { throw new IllegalArgumentException("不允许的目标主机"); } // 限制端口为标准端口 int port = targetUrl.getPort() != -1 ? targetUrl.getPort() : (targetUrl.getProtocol().equals("https") ? 443 : 80); if (!Set.of(80, 443).contains(port)) { throw new IllegalArgumentException("不允许的端口"); }
4. 安全构造请求URI
避免直接拼接字符串构造请求地址,使用URI.resolve()方法确保路径解析安全:
URI baseUri = new URI("https://your-domain.com"); URI safeUri = baseUri.resolve(decodedUri); // 后续使用safeUri发起请求
内容的提问来源于stack exchange,提问作者CoderAkki
相关产品推荐
相关产品推荐

