ShareXP has two different security postures, and they should not be conflated:
- the local MCP server is local-first and opt-in for sharing
- the hub is an authenticated shared service with scoped credentials, moderation state, and rate limiting
This repo is not claiming that an open public deployment is safe by default.
By default, the local server stores data locally and does not publish anything unless you configure a shared or global destination.
Local data includes:
- failure events and resolution candidates
- the SQLite registry at
data/registry.dbunless you overrideER_DB_PATH - workflow state under
.sharexp/
If you run the local server over streamable-http, ER_HTTP_AUTH_TOKEN is required at startup.
The hub is the shared-service surface in hub/.
Runtime expectations:
POST /api/v1/global/publishrequires a credential withpublishPOST /api/v1/global/searchrequiressearchPOST /api/v1/global/outcomerequiresoutcome- moderation and metrics routes require
moderate GET /healthzis unauthenticatedGET /reviewserves an unauthenticated page shell, but all data access still depends on a bearer token entered in the browser- delegated enrollment exchange and signed-source ingestion have separate auth flows and are rate-limited
By default, ShareXP only publishes fixes from public repositories. Before any outgoing payload is sent to the hub, the local tier queries the appropriate public API to confirm the repo is publicly accessible:
- GitHub:
GET /repos/{owner}/{repo}— checksprivate: false - GitLab:
GET /projects/{id}— checksvisibility: "public" - Bitbucket:
GET /2.0/repositories/{workspace}/{slug}— checksis_private: false
The remote URL is resolved from git remote get-url origin. If the host is not recognized (self-hosted GitLab, Gitea, Bitbucket Server, or any other host), the repo is treated as private by default and publishing is blocked.
Visibility results are cached for 7 days in the repo_visibility table to avoid repeated API calls.
| Variable | Effect |
|---|---|
SHAREXP_NO_PUBLISH=true |
Disables ALL hub connectivity regardless of repo visibility |
SHAREXP_PUBLISH_PRIVATE=true |
Allows publishing from private repos (overrides the default-deny) |
In addition to the standard secret/PII/path pipeline, ShareXP applies a second redaction pass that strips internal identifiers from outgoing payloads before transmission. The four redaction categories are:
| Category | Pattern | Example (raw → redacted) |
|---|---|---|
| Function names | CamelCase symbols | getUserProfile → [func:0] |
| File paths | Any path segment with extension | src/billing/invoice-service.ts → [file:0:ts] |
| Scoped packages | @scope/name |
@acme/payments-sdk → [package:scoped:0] |
| Repo URLs | github.com/org/repo style |
github.com/acme/monorepo → [repo:0] |
Before: "getUserProfile threw TS2345 in src/billing/invoice-service.ts"
After: "[func:0] threw TS2345 in [file:0:ts]"
pull_request_urlis dropped entirely from all outgoing payloads.repo_scopeandrepo_idare replaced with a 12-character SHA-256 hash prefix of the original value. The original is never transmitted.
Before data leaves the local tier, ShareXP applies a mandatory sanitization pipeline that targets:
- secrets and bearer tokens
- high-entropy strings
- common PII
- absolute local paths
The hub performs a second sanitization pass on ingress as defense in depth.
This matters because the shared hub can receive data from multiple publishers. Do not assume local hygiene alone is enough.
Use .sharexpignore to exclude files or directories from capture. The syntax matches .gitignore.
Set ER_REQUIRE_MANUAL_APPROVAL=true to require explicit review before sanitized data can be published.
Set ER_REDACT_ON_INGEST=true if you want redaction at capture time. Otherwise, payloads containing secrets are rejected instead of silently stored.
Run the built-in audit against a local registry:
npm run sharexp:audit
npm run sharexp:audit -- --jsonThe audit scans stored records for:
- known secret patterns
- high-entropy strings
- PII
- absolute paths
Status: Accepted residual risk. No patched upstream release available as of 2026-04-30.
Chain: @xenova/transformers@2.17.2 → onnxruntime-web@1.14.0 → onnx-proto@0.3.8 → protobufjs<7.5.5
CVE summary: protobuf.load() and Root.fromJSON() with attacker-controlled input can execute arbitrary code via prototype pollution.
Exploitability in ShareXP: Low. The vulnerable protobufjs is invoked internally by onnxruntime-web to parse bundled ONNX model .proto files that ship with @xenova/transformers. User-supplied data (error text for vector search) flows into the query path, not into protobuf parsing. There is no network-facing surface that processes attacker-controlled proto definitions.
Upgrade path: None available. @xenova/transformers latest is 2.17.2 (current). npm audit --fix would downgrade to 2.0.1 — a major regression with no benefit. Pinning via npm overrides to protobufjs≥7.5.5 risks silent wire-format breakage in onnxruntime-web's internal protobuf parsing (6→7 was a breaking API change).
Mitigation path: File issue with @xenova/transformers to bump onnxruntime-web. Monitor for a release with a fixed dep tree. If urgency increases, gate @xenova/transformers behind an ER_EMBEDDINGS_ENABLED=true env var (default false) to prevent loading the vulnerable code path for users who don't use vector search. Note: ER_EMBEDDINGS_ENABLED is a proposed mitigation and has not yet been implemented in src/config.ts or the embeddings import path.
| Advisory | Severity | Package | Fix |
|---|---|---|---|
| GHSA-26pp-8wgv-hjvm, GHSA-r5rp-j6wh-rvv4, GHSA-xf4j-xp2r-rqqx, GHSA-wmmm-f939-6g9c, GHSA-458j-xx4x-4375, GHSA-xpcf-pg52-r92g | Moderate | hono≤4.12.13 |
Fixed in 4.12.14; blocked on @modelcontextprotocol/sdk upgrade |
| GHSA-92pp-h63x-v22m | Moderate | @hono/node-server<1.19.13 |
Same chain as hono |
| GHSA-j3q9-mxjg-w52f, GHSA-27v5-c462-wpq7 | High | path-to-regexp 8.0.0–8.3.0 |
Fixed in 8.4.0; transitive via MCP SDK |
If you discover a vulnerability, open a GitHub issue with the security label or use a private reporting channel if one is available. Do not post exploit details or live secrets publicly.
- Local by default for the MCP tier.
- Explicit auth and scoped credentials for the hub tier.
- Fail closed when sensitive content is detected.
- Defense in depth with both local and hub-side sanitization.
- Honest claims: moderation, trust, and source attestation are alpha controls, not proof of safe open-network operation.