クローラーからのアクセスが変らしい!
import express from "express";
import rateLimit from "express-rate-limit";
const FLAG = process.env.FLAG ?? console.log("No flag") ?? process.exit(1);
const app = express();
app.use(express.json());
app.use(express.static("public"));
app.use("/api", rateLimit({ windowMs: 60 * 1000, max: 4, }));
app.post("/api/crawl-request", async (req, res) => {
const url = req.body?.url;
if (typeof url !== "string" || (!url.startsWith("http://") && !url.startsWith("https://")))
return res.status(400).send("Invalid url");
try {
const r = await fetch(url, { headers: { FLAG }, signal: AbortSignal.timeout(5000) }); // !!
if (!r.ok) return res.status(502).send("Fetch failed");
return res.sendStatus(200);
} catch (e) {
return res.status(500).send(`Something wrong: ${e.name}`);
}
});
app.listen(3333);
The endpoint performs a server-side fetch() to a user-supplied URL (SSRF). It also attaches the secret FLAG as an outgoing request header, so forcing a request to an attacker-controlled URL leaks the flag.
http:// or https://, no allowlistfetch(url, { headers: { FLAG } }) exfiltrates the flag via request headers/api/crawl-requestFLAG header from the captured request on your endpoint
