Wayfare is pre-MVP and has no released versions. The only supported version is
the current main branch, and that is what fixes land on.
Report privately, through GitHub's private vulnerability reporting form on the repository's Security tab. Please do not open a public issue for a suspected vulnerability.
Include, as far as you can:
- what the flaw is, and which package it lives in;
- the corridor, send amount, and source responses that reproduce it — a
cmd/ladderinvocation or an/api/corridorrequest is ideal; - what a sender loses because of it.
You should get an acknowledgement within a week. There is no bug bounty — Wayfare is an early open-source project and cannot offer payment. If a report is confirmed, we'll agree a disclosure timeline with you and credit you in the advisory unless you'd rather we didn't.
Wayfare holds no funds, no keys, and no user data — it is read-only by design, so the usual list does not map cleanly. What Wayfare produces is a claim about how much of someone's money survives a corridor. The security-relevant failures are the ones that make that claim wrong in the direction that costs the sender money.
These are the bugs that matter most, because someone sends money on the output.
- A quote reporting a higher receive amount, or a lower all-in cost, than the source actually offers.
- Fee arithmetic that adds units of one currency to another, or that applies a
fee.assetdenomination the wrong way round — the SEP-38 fee identity documented in the README is load-bearing, and breaking it produces a number that looks plausible and is meaningless. - A verdict of "viable" for a route whose loss against the mid-market rate says otherwise, or any path where a missing reference rate results in a ranking rather than a refusal to score. Scoring against an independent mid is the point; degrading to "cheapest of what we found" is a vulnerability, not a fallback.
- A failed or unreachable source rendered as a priced route, or silently dropped from the set so the survivors look like the whole market.
- Reading a price from a
stellar.tomlor SEP-38 response for an asset the anchor does not actually issue — including a code-only match passing as a verified issuer. - Any use of
float64in a pricing path. Money is decimal; a rounding artefact here is a wrong quote, not a cosmetic bug. This extends to the wire: money crosses it as decimal strings, and emitting a JSON number invites a client to reintroduce the same bug downstream. - Corridor integrity reported better than it is: a
DERIVATIVEcorridor presented asDIRECT, a dependency dropped fromdepends_on, or aNO-MARKETcorridor rendered as a priced one. The absence of a market and a bad price are different findings, and collapsing them hides the reason a corridor failed.
- Presenting an anchor's or Horizon's number as a Wayfare conclusion, or dropping the source and timestamp from a quote.
- Divergence between the HTTP API and
cmd/ladder -jsonfor the same measurement. They shareroute.ToCorridorJSONprecisely so one cannot understate what the other reports; a second, drifting shape is a finding. - Injection through issuer-controlled content — asset codes,
home_domain,stellar.tomlfields — into CLI output or into the UI served bywayfared. Issuer-controlled strings are untrusted input, and the TOML salvage path in particular parses hostile, malformed documents. - Denial of service in the fetch layer: unbounded reads, missing timeouts, or a hostile domain able to stall a quote indefinitely.
- A corridor being terrible. Wayfare reporting that the best route loses 56% is Wayfare working. That is a measurement, not a bug.
- An anchor's rate being bad, or its quote expiring. Quotes are point-in-time and carry a timestamp; the anchor owns its pricing.
- Horizon or a third-party rate provider returning wrong data. Those are consumed and attributed, not curated by us. Report them upstream.
- Missing corridors or missing anchors. A source Wayfare does not price yet is a feature request — open an issue.
The service ships as a static binary on
gcr.io/distroless/static-debian12:nonroot, so its third-party surface is two
things: the base image, and whatever the Go toolchain compiles into the binary.
CI scans the image it has just built. The report covers OS packages and language
packages; a fixable HIGH or CRITICAL finding in the image's own packages
fails the build, because the fix is a newer base image and that is a change this
repository can make.
Measured 2026-09-25 (before) against the image this repository builds with
Go 1.22.12: the image's own packages were clean, and /wayfared carried 22
HIGH/CRITICAL advisories with fixes — one CRITICAL — all in stdlib at
Go 1.22.12. Every fix is on the 1.24, 1.25, 1.26 or 1.27 line; none is on the
1.22 line the Dockerfile, go.mod and CI were pinned to.
Measured 2026-10-17 (after) against the image built with Go 1.27.2: 0
HIGH/CRITICAL advisories — the image's own packages are clean and the
compiled standard library carries no known-bad versions (#564).
Go 1.22 reached end of life, so the toolchain moved to a supported release in
the single toolchain definition (.github/workflows/ci.yml, GO_VERSION),
propagated to go.mod and the Dockerfile. This was a deliberate decision,
not a quiet bump: #467 deliberately returned CI to 1.22, and staying there
would keep carrying known-bad stdlib advisories on the service's trust
boundary (net/http and crypto/tls). While on 1.22 the findings were
recorded by the scan and deliberately not gated: no change in this
repository could fix them, and a required check that is always red teaches
people to ignore it. Now that the toolchain is supported, the scan is clean.
Those findings have been fixed by the toolchain move rather than accepted.
Both invocations pass --ignore-unfixed, so an advisory with no available
patch cannot fail a build either.
A finding you believe is a false positive can be accepted deliberately: put its
identifier in a .trivyignore file at the repository root and say in the pull
request why it does not apply. Accepting a finding is a decision, and a decision
belongs in a diff rather than in a re-run.
What the scan cannot see is behaviour — it names known-bad versions, not flaws in how this code uses them. Those are the findings below.
Wayfare is non-custodial and read-only: it never issues tokens, never holds reserves, never takes possession of funds, and never signs or submits a transaction. There is no key material in the codebase and nothing to drain. If you find a code path that submits anything to the network, that is itself a critical finding — report it.