5 hours ago
a
Pinned Solution
5 hours ago
Railway doesn’t support outbound rules. You’d need to implement something in your code for that.
4 Replies
5 hours ago
This thread has been opened as a bounty so the community can help solve it.
Status changed to Open Railway • about 5 hours ago
5 hours ago
Railway doesn’t support outbound rules. You’d need to implement something in your code for that.
0x5b62656e5d
Railway doesn’t support outbound rules. You’d need to implement something in your code for that.
5 hours ago
Thanks for confirming. We’ll enforce SSRF protections in the application and evaluate a dedicated egress proxy for additional isolation. This answers our question, so I’ll mark it as the solution.
Status changed to Solved 0x5b62656e5d • about 5 hours ago
4 hours ago
Thanks
Status changed to Awaiting Conductor Response Railway • about 4 hours ago
2 hours ago
Adding detail for anyone who lands here later, since the fix really does have to live in the app.
IN THE APP (SSRF guard): allow only http/https (optionally only ports 80/443). Resolve the hostname yourself and reject private/reserved IPs: 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 (cloud metadata), 100.64.0.0/10, 0.0.0.0/8, ::1, fc00::/7 (also covers Railway's IPv6 private network) and fe80::/10. Also block *.railway.internal by name. Connect to the IP you validated, not the hostname again, so DNS rebinding can't swap the address between check and request. Disable automatic redirects, or re-run the checks on every hop. Set a hard timeout and a max response size.
EXTRA ISOLATION: run Stripe's open-source Smokescreen as its own Railway service and route the fetcher's traffic through it over the private network (HTTPS_PROXY=http://smokescreen.railway.internal:4750). It enforces the IP deny-list at the proxy, so a bug in the app check doesn't expose your internal services. Better still, put the fetcher in its own service with no secrets in its env vars.
