|
| 1 | +# Security Policy |
| 2 | + |
| 3 | +## Reporting a Vulnerability |
| 4 | + |
| 5 | +**This is a public repository. Do not open a public GitHub issue for a security |
| 6 | +vulnerability** — that discloses it to everyone before a fix is available. |
| 7 | + |
| 8 | +Instead, report privately through GitHub's **Private Vulnerability Reporting**: |
| 9 | + |
| 10 | +1. Go to the **Security** tab of this repository. |
| 11 | +2. Click **Report a vulnerability**. |
| 12 | +3. Describe the problem, including steps to reproduce, affected version(s), and |
| 13 | + the impact. |
| 14 | + |
| 15 | +We will acknowledge the report, keep you informed as we investigate, and |
| 16 | +coordinate the disclosure timeline and a fixed release with you. Please give us |
| 17 | +a reasonable window to ship a fix before any public disclosure. |
| 18 | + |
| 19 | +## Scope |
| 20 | + |
| 21 | +This repo is the **MarketData Java SDK** — a client library published to Maven |
| 22 | +Central and pulled into consumers' applications. It runs on the consumer's |
| 23 | +machine (or their servers), not on MarketData infrastructure. The security |
| 24 | +concerns that matter here are therefore about how the library treats *its |
| 25 | +consumers*: |
| 26 | + |
| 27 | +- **Credential handling** — the caller's API token must never be logged |
| 28 | + verbatim, leaked in exception messages, or written to disk. Query strings are |
| 29 | + stripped from log output; tokens are redacted (`Tokens.redact`). Regressions |
| 30 | + here are in scope. |
| 31 | +- **Transport security** — TLS is validated by default and the SDK exposes no |
| 32 | + skip-verify option. Anything that weakens this is in scope. |
| 33 | +- **Injection into outbound requests** — request-building that lets caller |
| 34 | + input smuggle headers, path segments, or query parameters it shouldn't. |
| 35 | +- **Deserialization safety** — the Jackson-based response decoding path handling |
| 36 | + hostile or malformed API responses without RCE, resource exhaustion, or |
| 37 | + crashes that a consumer can't defend against. |
| 38 | +- **Supply-chain integrity of the published artifact** — the build, signing, and |
| 39 | + Maven Central publish pipeline (`tag-and-release.yml`, `publish.yml`), and the |
| 40 | + dependency tree of the shipped JAR. |
| 41 | + |
| 42 | +Out of scope: |
| 43 | + |
| 44 | +- **The MarketData API backend** itself. Report API/server vulnerabilities |
| 45 | + through the API's own channel, not here. |
| 46 | +- **Third-party dependencies.** Vulnerabilities in Gradle-resolved dependencies |
| 47 | + are tracked by Dependabot (see `.github/dependabot.yml`); report them upstream. |
| 48 | + We will bump the affected dependency here once a fixed version exists. |
| 49 | + |
| 50 | +## Security Fix Policy |
| 51 | + |
| 52 | +This policy governs how security fixes are applied to this repository, including |
| 53 | +fixes made by automated agents (e.g. Claude Code) working in the repo. It sorts |
| 54 | +every security fix into one of two tiers. |
| 55 | + |
| 56 | +The dividing line for a **library** is *consumer compatibility*. A fix that any |
| 57 | +consumer can pick up by upgrading, with no source or behavior change on their |
| 58 | +side, is low-risk. A fix that forces consumers to change their code, recompile |
| 59 | +against a changed API, or adapt to changed runtime behavior is a breaking change |
| 60 | +and follows SemVer — those get the maintainer gate. |
| 61 | + |
| 62 | +### Tier 1 — Fix immediately (no approval needed) |
| 63 | + |
| 64 | +Security fixes that are **API- and behavior-compatible for legitimate |
| 65 | +consumers**. Existing callers keep compiling and keep working the same way after |
| 66 | +upgrading; only the vulnerability is closed. |
| 67 | + |
| 68 | +These may be fixed, tested, and committed right away. Every Tier 1 fix must be |
| 69 | +called out in its commit message, in `CHANGELOG.md`, and in the summary reported |
| 70 | +to the maintainer, so nothing ships silently. |
| 71 | + |
| 72 | +Typical Tier 1 fixes: |
| 73 | + |
| 74 | +- Tightening credential redaction, or plugging a token/secret/PII leak into logs |
| 75 | + or exception messages |
| 76 | +- Fixing injection in request building (header/path/query smuggling) where valid |
| 77 | + caller input is unaffected |
| 78 | +- Hardening the response-deserialization path against malformed or hostile API |
| 79 | + responses (bounds, resource limits, null handling) |
| 80 | +- Correcting a logic flaw in an existing security check without changing its |
| 81 | + public contract |
| 82 | +- Patching a vulnerable dependency by bumping to a compatible version — no |
| 83 | + public API or behavior change for consumers |
| 84 | +- Hardening internal, non-public code paths (package-private infra: transport, |
| 85 | + retry, rate-limit, status-cache) that consumers cannot observe or depend on |
| 86 | +- Fixing the build/publish/signing pipeline (CI workflows, artifact signing) |
| 87 | + |
| 88 | +### Tier 2 — Requires maintainer approval first |
| 89 | + |
| 90 | +Any security fix that **breaks consumer compatibility or changes observable |
| 91 | +runtime behavior**. These must NOT be applied unilaterally. The agent or |
| 92 | +contributor stops, writes up the issue, the proposed fix, and the specific |
| 93 | +consumer impact, and waits for the maintainer's approval before proceeding. |
| 94 | + |
| 95 | +A fix is **Tier 2** if it does any of the following: |
| 96 | + |
| 97 | +- Removes, renames, or changes the signature of any **public** type, method, or |
| 98 | + parameter (a source/binary-incompatible change — SemVer major) |
| 99 | +- Tightens input validation so that requests the SDK previously accepted are now |
| 100 | + rejected (could break existing callers) |
| 101 | +- Changes a user-visible default (request/connect timeouts, retry counts or |
| 102 | + backoff, rate-limit behavior, base URL, API version, `validateOnStartup`) |
| 103 | +- Changes an API/response contract — the shape of response records, exception |
| 104 | + types thrown, or the sealed `MarketDataException` hierarchy — that consumers |
| 105 | + compile against or `switch` over exhaustively |
| 106 | +- Raises the minimum JDK, changes the published coordinates, or otherwise forces |
| 107 | + a consumer to change their build to keep using the SDK |
| 108 | +- Adds a new required dependency to the published JAR, or changes shading/relocation |
| 109 | + |
| 110 | +### Classification rules |
| 111 | + |
| 112 | +- **When in doubt, it's Tier 2.** If it is unclear which tier a fix falls into, |
| 113 | + treat it as Tier 2 and ask for approval. |
| 114 | +- **No urgency exception.** Even for a critical, actively-exploitable |
| 115 | + vulnerability, a compatibility-breaking (Tier 2) fix waits for maintainer |
| 116 | + approval. Flag the urgency loudly, propose the fix, and wait. The maintainer is |
| 117 | + always the gate for changes that break consumers. (If a break is genuinely |
| 118 | + unavoidable to close a critical hole, that's a maintainer decision about |
| 119 | + cutting a major version — not an agent's.) |
| 120 | + |
| 121 | +### Release of security fixes |
| 122 | + |
| 123 | +Tiering governs *what* may be changed; the repo's normal release rules govern |
| 124 | +*what ships to consumers*. A Tier 1 fix may be committed to a branch and merged |
| 125 | +via the usual PR flow. **Publishing a release to Maven Central** — cutting the |
| 126 | +tag and running the publish pipeline (`tag-and-release.yml` → `publish.yml`) — |
| 127 | +requires explicit maintainer confirmation, exactly like every other release. |
| 128 | +Automated agents never cut or publish a release on their own. |
0 commit comments