一个刻意设计存在漏洞的Web应用程序,演示文件上传绕过如何与存储型XSS结合,即使在CSP、CORS和CSRF防护措施到位的情况下,也能创建后门管理员账户。
完整博客文章:KurtiseBear博客
这是一个用于防御安全培训的教育性实验环境。请勿将其部署在任何可公开访问的位置。
该应用程序具有实际的安全控制措施:
'self'(但允许'unsafe-inline'和'unsafe-eval')拥有低权限用户账户的攻击者通过链式利用两个漏洞来绕过所有这些防护措施:
文件上传绕过 —— 上传表单通过客户端accept属性限制为.pdf,但服务器未进行任何文件类型验证。攻击者上传一个包含JavaScript的.js文件。下载端点从同一源提供该文件,因此CSP和CORS不会阻止它。
通过消息主题实现的存储型XSS —— 消息功能存储用户输入时未进行净化。管理员收件箱将消息主题渲染为原始HTML。XSS载荷使用``处理程序来获取上传的脚本并执行eval()。CSP允许此操作,因为允许'unsafe-inline'和'unsafe-eval'。
API端点缺少CSRF保护 —— 用户管理API(/api/manage-user.php)即使表单端点有CSRF验证,它本身不验证CSRF令牌。XSS载荷使用管理员同源会话调用此API。即使存在CSRF,同源JavaScript也可以从DOM中读取令牌。
结果:当管理员打开收件箱时,XSS触发,JavaScript利用管理员的会话创建一个后门管理员账户。所有防御措施都已到位且正常运行。链式攻击之所以成功,是因为它从未离开源站。
docker-compose up -d
等待10-15秒让MySQL初始化,然后访问 http://localhost:8080
| 角色 | 邮箱 | 密码 |
|---|---|---|
| 管理员 | [email protected] | admin |
| 用户 | [email protected] | user |
导航至 http://localhost:8080 并使用 [email protected] / user 登录。
进入 上传文件。表单显示"仅PDF",但仅在客户端强制执行。你可以:
accept=".pdf" 属性,或者上传提供的 payload.js(或你自己的)。注意返回的文件ID(例如 1)。
上传的文件现在从同一源的 /api/download.php?file_id=1 提供服务。CSP不会阻止对此端点的请求,因为它属于'self'。
进入 发送消息。在主题字段中输入:
r.blob()).then(b=>b.text()).then(eval)">
(将 1 替换为步骤2中的实际文件ID。)
正文部分填写任意内容。如果希望消息出现在收件箱顶部,可勾选优先级。然后发送。
onerror 处理程序之所以生效,是因为CSP允许'unsafe-inline'。eval() 之所以生效,是因为CSP允许'unsafe-eval'。对下载端点的fetch请求之所以生效,是因为它是同源的。
退出登录。以 [email protected] / admin 登录。进入 收件箱。
消息主题被渲染为原始HTML。`` 标签加载失败,onerror 处理程序触发,获取上传的载荷并执行eval()。载荷使用管理员的会话cookie(同源请求会自动附带)向 /api/manage-user.php 发送POST请求。由于API端点不检查CSRF令牌,因此无需CSRF令牌。
进入 用户管理。你应该能看到一个新用户:BackdoorAdmin,角色为 admin,邮箱为 [email protected]。
退出登录,使用 [email protected] / Compromised1! 登录以确认。
CSP阻止外部脚本
--> 但载荷通过文件上传托管在同一个源上
--> 而且 unsafe-inline/unsafe-eval 允许 onerror 处理程序和 eval()
CORS阻止跨源请求
--> 但链中的每个请求都是同源的
CSRF令牌保护表单提交
--> 但API端点不验证它们
--> 即使它验证了,同源JavaScript也可以从DOM中读取令牌
会话cookie具有标准保护
--> 但同源请求会自动携带它们
所有防御措施都正常工作。它们旨在阻止跨源攻击。而这个链式攻击从未离开源站。
以下措施能够真正打破这个攻击链:
htmlspecialchars()。收件箱直接渲染 $row['subject'] 原始内容。这会完全扼杀XSS。'unsafe-inline' 和 'unsafe-eval'。对合法的内联脚本使用nonce或哈希。这将阻止 onerror 处理程序和 eval()。docker-compose down -v
此应用程序是故意存在漏洞的。它仅用于教育和防御性安全培训目的。请勿将其部署在任何不受信任用户可以访问的网络上。未经明确书面授权,请勿将这些技术用于任何系统。