docs(security): tighten responsible disclosure language (#3619)

Co-Authored-By: Diego <diegodearagao@gmail.com>
This commit is contained in:
Garry Tan
2026-08-01 10:06:17 +08:00
committed by Sina Matian
co-authored by Diego
parent c0b28f104d
commit a228776b8f
2 changed files with 19 additions and 24 deletions
+1 -1
View File
@@ -87,7 +87,7 @@ jobs:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: gitleaks/gitleaks-action@dcedce43c6f43de0b836d1fe38946645c9c638dc # v2 - uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+18 -23
View File
@@ -34,15 +34,18 @@ enforced structurally by actionlint on every workflow change.
## Remote MCP Security ## Remote MCP Security
### ⚠️ Do NOT use open OAuth client registration for remote MCP ### Keep dynamic client registration disabled unless explicitly needed
If you deploy GBrain's MCP server behind an HTTP wrapper with OAuth 2.1 GBrain disables Dynamic Client Registration (DCR) by default. Keep that
support, **never allow unauthenticated client registration**. An attacker default for internet-reachable deployments and pre-register trusted clients
who discovers your server URL can: with operator-approved scopes and source access. Enabling DCR lets network
callers create OAuth client records, so use it only when the deployment's
trust model requires self-service registration and browser approval remains
part of the authorization flow.
1. Register a new OAuth client via `POST /register` Do not enable `--enable-dcr-insecure` on an untrusted network. That option is
2. Use `client_credentials` grant to obtain a bearer token reserved for deployments that intentionally allow self-registered
3. Access all brain data via the MCP tools machine-to-machine clients without browser approval.
### Recommended: `gbrain serve --http` ### Recommended: `gbrain serve --http`
@@ -104,12 +107,10 @@ Auth methods (`--token-endpoint-auth-method`):
- `none` — public PKCE-only client (no secret minted; ChatGPT custom - `none` — public PKCE-only client (no secret minted; ChatGPT custom
connector, Claude Code, Cursor) connector, Claude Code, Cursor)
The validator rejects unknown methods at the registration boundary, and The same validator applies to CLI, admin, and DCR registration paths, so
the same gate applies to the admin endpoint `POST /admin/api/register-client` unknown authentication methods are rejected consistently. Browser-based
and the DCR `POST /register` path. Pre-v0.41.3 the CLI hard-coded clients can be configured entirely through the supported CLI flags; operators
`redirect_uris = []` and `token_endpoint_auth_method = NULL`, forcing do not need to edit OAuth database rows by hand.
operators to UPDATE `oauth_clients` rows by hand to make claude.ai work
without `--enable-dcr`. That footgun is gone.
### DCR consent default (v0.42.55+) ### DCR consent default (v0.42.55+)
@@ -186,16 +187,10 @@ When the request `Origin` matches the allowlist, the server echoes it
back in `Access-Control-Allow-Origin` (with `Vary: Origin`). Otherwise no back in `Access-Control-Allow-Origin` (with `Vary: Origin`). Otherwise no
CORS header is sent and the browser blocks the request. CORS header is sent and the browser blocks the request.
**v0.41.3:** the same allowlist now gates every OAuth endpoint (`/mcp`, The same allowlist gates the complete MCP and OAuth HTTP surface. Actual
`/token`, `/authorize`, `/register`, `/revoke`). Pre-v0.41.3 these used requests and browser preflight requests use one allowlist-gated policy, so
default-wide-open `cors()` middleware, leaking unlisted origins receive no cross-origin authorization. A startup stderr
`Access-Control-Allow-Origin: *` on every response — any web origin could warning fires when `--bind 0.0.0.0` is set without
complete a token exchange from a logged-in operator's browser. The CORS
preflight handler in the legacy bearer transport was also asymmetric
(actual-request path correctly default-deny, but OPTIONS preflight leaked
`Access-Control-Allow-Methods` + `Access-Control-Allow-Headers` to every
Origin); both are now consolidated through a single allowlist-gated path.
A startup stderr WARN fires when `--bind 0.0.0.0` is set without
`GBRAIN_HTTP_CORS_ORIGIN`, surfacing the default-deny posture before the `GBRAIN_HTTP_CORS_ORIGIN`, surfacing the default-deny posture before the
first request. first request.