高危漏洞的修复,核心逻辑不是“见招拆招”,而是在数据从“不可信”流向“危险操作”的路径上,设置一道或多道可靠的拦截机制。修复动作必须落到具体的代码或配置上,而不是停留在“建议加强校验”的层面。

漏洞扫描修复措施
修复资源永远有限,优先级不能只看CVSS分数。一个CVSS 8.5但位于内网、且需要高权限才能触发的漏洞,实际风险可能低于一个CVSS 6.5但直接暴露在互联网、无需认证即可利用的漏洞。
科学的排序逻辑是:互联网可达 + 无需认证 + 可直接利用的漏洞优先处理。行业实践通常将这类高危漏洞的修复时限控制在3天以内。修复顺序上,越权访问、支付逻辑篡改这类直接影响业务和资金的漏洞,应排在纯粹的代码质量缺陷之前。
以下修复措施均指向具体的代码或配置改动,可直接作为开发修复的依据。
根因:用户输入被当作SQL代码的一部分执行了。
修复:绝对不要使用字符串拼接SQL。统一改为参数化查询(预编译语句),让数据库驱动把输入严格当作“数据”处理。
Java (JDBC):使用 PreparedStatement 和 ? 占位符。
MyBatis:使用 #{} 而不是 ${} 来绑定参数。
Python:使用参数化查询(如 cursor.execute("... WHERE name = %s", (name,))),避免f-string拼接。
补充措施:关闭详细的SQL错误回显,避免攻击者通过报错信息获取数据库结构。
根因:不可信数据被浏览器当作HTML或JavaScript代码执行了。
修复:按输出上下文进行编码是首要防线,CSP是纵深防御的兜底。
输出编码:根据数据将要放置的位置(HTML标签内、HTML属性内、JavaScript内、URL中),使用对应的编码函数。例如,使用 OWASP Java Encoder 的 Encode.forHtml()、Encode.forJavaScript() 等。
框架默认值:Spring/Thymeleaf、ASP.NET Core Razor默认会对输出进行编码,不要随意关闭(如避免使用 th:utext 或 Html.Raw)。
启用严格CSP:配置 Content-Security-Policy 响应头,限制脚本只能从可信来源加载。避免使用 unsafe-inline,它会使CSP对XSS的防护基本失效。
富文本场景:如果业务必须渲染用户提供的HTML,使用 DOMPurify 这类经过严格测试的库进行清洗,而不是自行编写过滤规则。
根因:浏览器在跨站请求中自动携带了用户的身份Cookie。
修复:核心是让攻击者无法伪造出“服务端认可”的请求。
同步令牌模式:在状态变更的请求(如POST)中,要求携带一个服务端生成、与用户会话绑定的防伪令牌(CSRF Token)。ASP.NET Core中的 [ValidateAntiForgeryToken] 或 UseAntiforgery() 是标准实现。
Cookie属性加固:为身份认证Cookie设置 SameSite=Strict (或至少 Lax),这是从浏览器层面阻止跨站携带Cookie的有效措施。同时确保 Secure 和 HttpOnly 属性已启用。
根因:服务端只校验了“你是谁”(认证),或只校验了“你的角色是什么”(垂直授权),但没有校验“这条数据到底归不归你”(资源级授权)。
修复:在每一个涉及具体资源ID的接口中,强制实施服务端的资源归属校验。
身份来源:用户ID必须仅从经过验证的会话/Token中解析,绝不能信任请求参数中传入的 userId 或类似的标识。
校验逻辑:在执行操作(读取、修改、删除)之前,用“当前用户ID + 目标资源ID”去查询数据库,确认存在有效的归属关系。例如,在播放课程接口中,必须确认当前用户存在该课程的有效订购记录,且未过期。
水平越权:确保用户只能操作 WHERE user_id = :current_user_id 范围内的数据。
垂直越权:在网关或统一拦截器中强制执行角色权限检查,避免在每个接口中“靠自觉”。
根因:用户输入被拼接进了系统命令字符串。
修复:杜绝拼接,使用参数化调用方式,并辅以严格的白名单校验。
使用参数列表:使用 ProcessBuilder 或 Runtime.exec(String[] cmdarray) 的形式,将命令和参数作为独立的数组元素传入,让操作系统层面区分“命令”和“数据”。
白名单校验:对传入的参数进行严格的白名单过滤。例如,如果参数本应是IP地址,就用严格的IPv4正则表达式进行全匹配校验,不合规的直接拒绝。
避免Shell:在不需要Shell特性(如管道、重定向)时,避免通过 sh -c 或 cmd /c 来执行命令,减少攻击面。
根因:服务端信任了客户端提交的文件类型,或把文件存到了可被Web访问并执行的位置。
修复:采用“类型校验 + 重命名 + 隔离存储 + 禁用执行”的组合策略。
服务端校验类型:基于文件内容签名(Magic Bytes) 和服务端白名单来验证文件类型,绝不能依赖客户端提交的 Content-Type 或文件扩展名。
重命名文件:使用服务端生成的随机名称(如UUID)保存文件,剥离原始文件名中的路径信息,防止路径遍历。
隔离存储:将上传文件存储在Web根目录之外,通过一个受控的、安全的脚本来提供访问,确保文件内容永远不会被服务器当作脚本执行。
禁用执行:在Web服务器配置中,明确禁用上传目录的脚本执行权限。
根因:服务端接受了用户提供的URL,并发起了请求,导致攻击者可以借助服务器访问内网或云元数据。
修复:核心是严格限制服务端可以访问的目标地址范围。
地址黑名单/白名单:默认拒绝访问 localhost、回环地址(127.0.0.0/8、::1)、私有IP地址段(如 10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、100.64.0.0/10)以及云元数据地址(如 169.254.169.254)。
处理重定向:禁用或严格限制HTTP重定向,防止攻击者通过一个允许的URL跳转到内网地址。
DNS解析与规范化:在发起请求前,将目标域名解析为IP地址,并对IP地址进行黑名单校验。同时,处理IPv4映射的IPv6地址等特殊格式,防止绕过。
漏洞工单上标记“已修复”没有意义,唯一的验收标准是复测证据。
修复完成后,必须用原扫描工具或等效的技术手段进行复测,确认漏洞条件已经从受影响资产上消失。对于越权、逻辑漏洞这类工具难以完全覆盖的问题,还需要用两个不同权限的账号进行交叉验证(例如,用账号A的令牌去请求账号B的数据,必须被拒绝)。

漏洞扫描
复测通过后,再将原始扫描报告、修复代码片段/配置截图、复测报告一并归档。这份闭环证据链,才是向甲方或审计方证明“高危漏洞已清零”的唯一有效材料。
高危漏洞的修复,本质上是在和攻击者争夺“数据流向控制权”。把校验和拦截放在正确的位置,比堆砌更多的安全设备更直接有效。行业里反复验证的规律是:缺陷发现得越晚,修复成本越高。上线后再改要走变更评审、回归测试、重新发版,综合代价是编码阶段的几十倍。所以漏洞整改这笔钱,花得越早越省。
标签:漏洞扫描、安全测试报告