fix(tools): pin resolved IP in DB connectors to prevent DNS-rebinding SSRF#4725
Conversation
… SSRF `validateDatabaseHost` resolved an IP that was then discarded — drivers re-resolved the hostname at connect time, enabling DNS-rebinding TOCTOU. - mongodb: pass resolved IP via MongoClient `lookup` option - mysql: pin TCP socket via `stream` factory; keep hostname for TLS servername - postgresql: connect to resolved IP; pass `ssl` object with `servername` for SNI - redis: parse URL explicitly and pass options-only (URL+options breaks override due to ioredis's lodash.defaults); pin host and set `tls.servername` for rediss - neo4j: pin IP for plain `bolt://`; leave `bolt+s`/`neo4j+s` unchanged to keep Aura cert validation working (driver hardcodes servername with no override)
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview MongoDB now uses a custom Reviewed by Cursor Bugbot for commit 32c4b1a. Configure here. |
Greptile SummaryThis PR closes the DNS-rebinding TOCTOU window across all five database connectors by ensuring the IP resolved during the SSRF validation phase is the same IP used for the actual TCP connection — each driver's pinning mechanism is chosen to be compatible with its TLS SNI requirements.
Confidence Score: 5/5Safe to merge; each connector's pinning mechanism correctly preserves TLS SNI semantics and the overall security posture is meaningfully improved. All five connectors correctly thread the resolved IP into the underlying TCP connection while keeping the original hostname available for TLS SNI. The one concrete finding (Redis db-index validation accepting negative integers) is a minor UX issue that surfaces as a Redis-level error rather than a security or data-integrity problem. No regressions in SSL behaviour were introduced. apps/sim/app/api/tools/redis/execute/route.ts — the db-index path parsing accepts negative numbers; all other files look correct. Important Files Changed
Sequence DiagramsequenceDiagram
participant Client
participant Validator as validateDatabaseHost
participant DNS
participant Connector as DB Connector
participant DB as Database Server
Client->>Validator: host string
Validator->>DNS: dns.lookup(host)
DNS-->>Validator: resolvedIP
Validator->>Validator: isPrivateOrReservedIP check
Validator-->>Client: resolvedIP
rect rgb(200, 230, 255)
Note over Connector,DB: MongoDB - lookup option
Client->>Connector: createMongoDBConnection
Connector->>DB: MongoClient with lookup pinned to resolvedIP
end
rect rgb(220, 245, 200)
Note over Connector,DB: MySQL - stream factory
Client->>Connector: createMySQLConnection
Connector->>DB: net.connect to resolvedIP then TLS SNI via config.host
end
rect rgb(255, 235, 200)
Note over Connector,DB: PostgreSQL - host override plus servername
Client->>Connector: createPostgresConnection
Connector->>DB: postgres host set to resolvedIP with ssl servername config.host
end
rect rgb(240, 220, 255)
Note over Connector,DB: Redis - explicit options object
Client->>Connector: Redis POST route
Connector->>DB: new Redis with host resolvedIP and tls servername hostname
end
rect rgb(255, 215, 215)
Note over Connector,DB: Neo4j - URI host replacement
Client->>Connector: createNeo4jDriver
alt bolt plain
Connector->>DB: bolt://resolvedIP:port
else bolt+s or neo4j+s TLS
Connector->>DB: bolt+s://config.host:port no IP pinning
end
end
Reviews (4): Last reviewed commit: "fix(tools): reject non-numeric Redis URL..." | Re-trigger Greptile |
|
@greptile |
|
@cursor review |
|
@greptile |
|
@cursor review |
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 32c4b1a. Configure here.
Summary
validateDatabaseHostresolved an IP that was then discarded; the drivers re-resolved the hostname at connect time, leaving a DNS-rebinding TOCTOU windowlookupoptionstreamfactory; keepconfig.hostfor TLS servernamesslas object withservernameso SNI works against the pinned IPhostdue to ioredis'slodash.defaults); settls.servernameforrediss://bolt://; leavebolt+s/neo4j+sunchanged so Aura cert validation keeps working (driver hardcodes servername with no override)Type of Change
Testing
Tested manually. Type-check, biome lint, and
bun run check:api-validationall pass. Driver source code reviewed to verify each pinning mechanism reaches the underlyingnet.connect/tls.connectcall.Pre-merge verification still needed against live managed providers (Atlas, RDS, Heroku PG, ElastiCache TLS, Aura).
Checklist