← back to Visual Factory
use DNS-aware SSRF gate on /runs/:id/post-ig
5de52a6b25858ede402777d0735824ac1ab5e3ec · 2026-04-30 23:26:47 -0700 · temp
Files touched
Diff
commit 5de52a6b25858ede402777d0735824ac1ab5e3ec
Author: temp <temp@local>
Date: Thu Apr 30 23:26:47 2026 -0700
use DNS-aware SSRF gate on /runs/:id/post-ig
---
server.js | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/server.js b/server.js
index 029c3ab..4dc595a 100644
--- a/server.js
+++ b/server.js
@@ -550,9 +550,12 @@ app.post('/runs/:id/post-ig', async (req, res) => {
// ranges, file://, or AWS metadata. Only public http(s) hosts allowed.
let imageUrl = `http://127.0.0.1:${PORT}/runs/${runId}/png`;
if (req.body && typeof req.body.image_url === 'string' && req.body.image_url.length) {
- if (!isAllowedExternalUrl(req.body.image_url)) {
+ // Use the DNS-aware validator: blocks both literal-private hosts AND
+ // hostnames that *resolve* to private/loopback/metadata addresses
+ // (DNS rebinding). The route is already async, so the await is free.
+ if (!(await isAllowedAfterDns(req.body.image_url))) {
return res.status(400).json({
- error: 'image_url rejected — must be public http(s); private/loopback/metadata addresses blocked',
+ error: 'image_url rejected — must be public http(s); private/loopback/metadata addresses blocked (DNS-resolved)',
});
}
imageUrl = req.body.image_url;
← 287ac34 apply codex p2/p2/p3 abort-handling fixes
·
back to Visual Factory
·
B: pre-fetch user image_url and re-host on loopback (closes 30c6d24 →