fix: close SSRF bypass, make marketing surface reachable, replace fabricated AI assistant - #1016
Merged
Conversation
`WebhookDelivery` kept its own `net.BlockList` of private ranges, separate from the list in `UrlValidator`. The two drifted, and the copy guarding outbound deliveries was the weaker one: it omitted `0.0.0.0/8`, the IPv6 unspecified address, CGNAT `100.64.0.0/10` and `192.0.0.0/24`. Because each of those is an IP literal, `validateResolvedHostname` returned early and never re-checked them. So `http://0.0.0.0:8080/` passed validation and was fetched - and on Linux `0.0.0.0` routes to loopback, meaning a customer-registered webhook URL could reach services bound to 127.0.0.1 on the delivery worker. Verified end to end: `validateUrl` returned null for `0.0.0.0` while correctly blocking `127.0.0.1`, and a real fetch reached a loopback-bound server. Extract the range checks into `private-ip.ts` and have both callers use it, so there is nothing left to drift. `validateUrl` also picks up the `.localhost` suffix check it was missing - RFC 6761 reserves the whole suffix, not just the bare label. `UrlValidator` is now exported. Its own docs claimed consumers wire it in front of their own fetch, but it was never re-exported from index.ts, so nobody could - the claim was false and the class was unreachable. Adds 8 regression cases against the delivery path, not just the validator.
A first-time visitor landing on `/` could not get anywhere. Every nav link, both hero buttons, the CTA, and all nine footer links were `href="#"` - sixteen dead links on pages whose destinations (`/docs`, `/reference`, `/demo/contracts`, `/starters`, `/changelog`) all already existed and worked. Centralise every off-page destination in `lib/links.ts` so a renamed route breaks in one file instead of rotting silently in four. Also fixed, all in the same category of claiming more than is true: - `/starters` linked three repos that do not exist - `orbital-next-starter`, `orbital-express-starter`, `orbital-anchor-starter` all 404, so every source link and all six deploy buttons pointed at nothing. Repointed at the in-repo `examples/`, with the repo path now an actual link. Vercel's clone flow takes `root-directory`, so the Next.js starter keeps a working one-click; Railway's `templateUrl` has no subdirectory equivalent, so those two link to their README rather than ship a button that deploys the repo root by mistake. - The anchor starter was described as having "a live React dashboard". It is a CLI that writes an append-only JSON Lines audit log. Description now matches the code. - The footer hardcoded "● All systems operational" next to a Status link that went nowhere. There is no uptime monitor behind it, so it read green while the demo endpoint was returning 503. Removed rather than faked. - The footer listed 2 of the published packages as unlinked plain text. Now lists the 4 that are actually on npm, linked. `anchor-sdk` and `orbital-indexer` are deliberately absent - they 404 on the registry, and linking them would recreate the exact problem this commit fixes. - The product is called Orbital, not "Orbit Stellar" - including in the `<title>`, so the browser tab was wrong too. - Twitter is dropped: no account exists, and an invented handle is worse than an absent row. `examples/next-starter` was untracked and unfinished - no page, no layout, no README, and `lib/engine.ts` imported `./config.js`, which does not resolve under `moduleResolution: "bundler"`, so it could never have built. Completed and verified with a real `next build`.
The docs sidebar shipped an "AI Assistant" with no model behind it. It greeted every visitor with "Ask me anything about the SDK, webhooks, or real-time events", waited a hardcoded 1200ms to look like it was thinking, then returned a canned template string with the question interpolated into it. No "coming soon" label, mounted unconditionally, so it was live on every /docs page - a developer evaluating the SDK asked a real question and got a confident non-answer. Rewritten as what it can honestly be: a docs search panel over the existing /api/docs/search endpoint, using the same debounced fetch as SearchDialog. Every line it shows is now a real section with a real link, and when nothing matches it says so instead of inventing prose. Button relabelled AI -> Search. Two unmetered amplifiers on the same surface: - /api/docs/search re-read, re-parsed and re-stripped every markdown file in the corpus on every request, uncached, with no rate limit, on a route the UI calls on a 200ms debounce. The content is build-time static, so it is now parsed once per process. Query length is capped at 128 chars. - /api/webhook-sample read an unbounded JSON body and HMAC-ed over an unbounded caller-supplied secret. Body now capped at 4KB (413 past that), secret at 256 chars, address at 56. Also: clientIp() silently collapses every caller into a single "unknown" bucket when neither x-vercel-forwarded-for nor TRUSTED_PROXY_HOPS is available. Failing closed is right, but it turns perIpStreams: 1 into a global limit - one SSE slot for the whole internet on a non-Vercel deploy. Now warns once per process naming the fix.
…o suites `onCursor` fired `void this.persistUnifiedCursor(...)`, discarding the promise. Nothing tracked it, so `stop()` could not wait for it and two writes were never ordered against each other. Two consequences: a shutdown could lose the newest cursor, and on a store whose writes complete out of order (Postgres, Redis, the filesystem under load) the OLDER cursor could be the one that survived. Either way the next start replays events that were already delivered - which matters for a pipeline the anchor starter sells as "audit-grade, replay-safe". Writes are now chained, and `stop()` awaits the tail. The chain is null until the first write is queued, deliberately: making `stop()` await unconditionally deferred the teardown after it by a microtask and broke three callers that read engine state immediately after stopping. That also removes the race behind EventEngine.unifiedCursorResume.test.ts, which slept 20ms after `stop()` and hoped. It failed 2 of 3 local runs; now 3 of 3. The two DeadLetterStore flakes had a different cause: unlike its sibling pulse-webhooks.test.ts, that file never mocked `dns/promises`, so every delivery attempt did a real DNS lookup of example.com - on real time, inside `vi.useFakeTimers()`, where `vi.waitFor` could not wait for it. Mocked, as the sibling already does. examples/next-starter declared a `test` script with no tests, failing `pnpm -r test`. Covered the config validation instead, which is the part worth testing. Widened `loadConfig` to take the env shape it actually reads. abi-registry's CLI-only config loader is annotated so bundlers stop trying to trace a runtime path. This does NOT clear the "whole project was traced" warning in apps/web - that needs the module moved behind its own subpath export and dropped from index.ts, which is a public-API change, so the comment says so rather than implying it is fixed.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
href="#"links across nav/hero/CTA/footer plus three fake starter-repo links on the marketing site/api/docs/searchendpointTest plan
pnpm -r --if-present test)