SSRF (server-side request forgery)
Server-side request forgery is a vulnerability in which an attacker persuades a server to make an HTTP request to a destination of the attacker's choosing. Because the request originates from inside the server's network, it reaches things the attacker cannot reach directly — internal services, private address ranges, and cloud metadata endpoints.
| Defence | How it works | Defeated by | Adequate? |
|---|---|---|---|
| String blocklist | Reject URLs containing localhost, 127.0.0.1, 169.254 | Decimal and octal IP encodings, IPv6-mapped addresses, a hostname that resolves to a private address, redirects | No |
| Parse the URL and check the literal IP | Extract the host, reject if it parses as a private address | Any hostname — the check never resolves it. internal.attacker.com resolving to 10.0.0.5 passes | No |
| Resolve DNS, then check every resolved address | Resolve the hostname, reject if any answer is loopback, RFC1918, link-local or otherwise reserved | DNS rebinding, unless the connection is pinned to the checked address; redirects, unless each hop is re-checked | Yes, with pinning and redirect handling |
| Egress proxy with an allowlist | Outbound traffic can only reach approved destinations | An overly broad allowlist | Strongest, and operationally heaviest |
What an attacker gains from each target
- Loopback (
127.0.0.0/8). Admin interfaces and debug endpoints bound to localhost on the assumption that only local processes can reach them. - RFC1918 private ranges. Databases, caches, internal APIs and management consoles that authenticate by network position rather than by credential — still common on internal networks.
- Link-local (
169.254.0.0/16). On the major cloud providers,169.254.169.254is the instance metadata service. On a misconfigured instance it hands out temporary credentials for the machine's role. This single address is responsible for some of the largest cloud breaches on record. - Internal DNS names. Service discovery names that only resolve inside the network, giving an attacker a map as well as access.
- Non-HTTP schemes. Where the fetching library supports them,
file://reads local files andgopher://can be shaped to speak other protocols entirely. Restricting tohttpsis a cheap and necessary control.
DNS rebinding, the reason resolution timing matters
Suppose the platform validates a URL when the administrator saves it, resolving the hostname and confirming it points somewhere public. Some minutes later, the platform fetches it.
An attacker who controls the domain's DNS can serve a public address with a one-second TTL for the validation lookup, and a private address for the lookup that precedes the actual request. The URL that was checked and the URL that is fetched are the same string resolving to different addresses. This is DNS rebinding, and it defeats any design where validation and use are separate resolutions.
The mitigations are to resolve once, check every address returned, and then connect to the checked IP directly rather than to the hostname — pinning — and to re-run the check on every redirect hop, since a permitted URL can redirect to a forbidden one. Validate at fetch time, not only at save time.
Where SSRF appears in a school communications platform
Every place a district can supply a URL that the platform will fetch:
- Webhook destination URLs. The clearest case — an administrator supplies an address the server will POST to on every event.
- Roster import from a district-supplied URL. Fetching a CSV or an API endpoint on a schedule, from an address a user configured.
- Logo, avatar or branding image fetching. Frequently overlooked because it feels cosmetic.
- Link previews or URL unfurling in message composition.
- SIS or LMS API base URLs in integration configuration.
- Single sign-on metadata URLs, where SSO exists.
The pattern is the same in each: a user-supplied address plus a server that will fetch it. Any product with an integrations page has at least one of these.
The common misconception, and how Kastr guards it
"We validate the URL, so we are protected." Validation as usually implemented means checking the string, which stops nothing — http://2130706433/ is 127.0.0.1 in decimal, and http://internal.example.com/ is whatever its owner's DNS says it is at the moment of the lookup. What is required is resolving the hostname and inspecting the resulting addresses, at the moment of the request, with the connection pinned to what was checked.
Kastr's outbound webhook delivery resolves the destination and rejects loopback, RFC1918 and link-local targets after resolution rather than by string matching. Webhooks are additionally signed, so a receiver can verify origin — see HMAC signatures — and endpoints are disabled automatically after ten consecutive failures, which limits how long a misconfigured or hostile destination stays in the delivery path.
A related control on the same surface: roster connector configurations hard-reject literal credentials matching sk_, whsec_, AKIA, AIza, ghp_, xox[bp]- and PEM headers. Integration configuration is where secrets get pasted, and refusing them at the boundary is cheaper than discovering them in a support export later.
Questions people actually ask
Why is validating a URL string not enough to prevent SSRF?
Because the string is not the destination. http://2130706433/ is loopback in decimal notation, IPv6-mapped forms express the same addresses differently, and any hostname resolves to whatever its DNS says at the moment of lookup. Only resolving the name and inspecting the resulting addresses tells you where the request will actually go.
What is DNS rebinding?
An attack where a hostname resolves to a permitted address when the platform validates it and to a forbidden internal address when the platform fetches it, using very short DNS record lifetimes. It defeats any design that validates and fetches as two separate resolutions. The defence is to resolve once, check the answers, and connect to the checked address directly.
Why do cloud metadata endpoints matter in an SSRF attack?
Because on major cloud providers the link-local address 169.254.169.254 serves instance metadata, which on a misconfigured instance includes temporary credentials for the machine's role. An SSRF that reaches it can escalate from 'the server made a request' to 'the attacker holds cloud credentials', which is why link-local must be blocked explicitly and not merely as a side effect of blocking private ranges.
Where does SSRF appear in a school communications platform?
Anywhere a district supplies an address the platform fetches: webhook destinations, roster imports from a URL, logo and avatar fetching, link previews, and integration base URLs. The first is the most obvious and the middle two are the most often overlooked, because they do not feel like security-relevant features.
One price. Every feature. Locked for three years.
$3.50 per student per year under 5,000 students. No tiers, no add-on modules, no per-message fees. Published on the site because you should not have to book a call to learn a price.