security(http-server): validate every present Origin - #249
Conversation
Coverage: 94.72% (was 94.75%)
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| BestPractice | 1 medium |
🟢 Metrics 4 complexity · 4 duplication
Metric Results Complexity 4 Duplication 4
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
There was a problem hiding this comment.
Pull request overview
This PR tightens HTTP transport security by enforcing strict Origin validation at the /mcp boundary and by switching non-hardened deployments to a loopback-only default allowlist unless explicitly configured.
Changes:
- Add an early
/mcpmiddleware that rejects any present invalidOriginwith a fixed, non-reflecting 403 JSON-RPC error before parsing/CORS/auth/limits/server construction. - Change HTTP security defaults so
restrictOriginsis always enabled, with non-hardened mode defaulting to exact loopback origin allowlists (optionally including the configured port), and explicit env allowlists replacing defaults. - Expand documentation and tests to cover the new behavior and upgrade requirements.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/http-server.ts | Adds /mcp origin boundary middleware and aligns CORS origin evaluation with strict Origin handling. |
| src/http-security.ts | Introduces loopback default origin allowlists and makes origin restriction always-on (with explicit allowlist replacement semantics). |
| SECURITY.md | Documents origin validation behavior, hardened-mode requirements, and upgrade implications. |
| README.md | Adds an upgrade notice describing the new origin validation and defaults. |
| CONFIGURATION.md | Adds an origin validation and upgrade notice in configuration docs. |
| tests/unit/http-security.test.ts | Adds unit coverage for loopback defaults, explicit allowlist replacement, and exact-match origin behavior. |
| tests/integration/http-server.test.ts | Adds integration coverage ensuring early rejection occurs before parsers/CORS/rate limiting/auth/server construction, and validates allowed/absent origin behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Coverage: 94.72% (was 94.72%)
|
Review findings for
|
Coverage: 94.72% (was 94.72%)
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/http-server.ts:216
Vary: Originis added by a later global middleware, butoriginBoundarycan terminate the request early with a 403 before that middleware runs. That means the 403 response can be cached without varying by Origin, even though the response behavior depends on whether an Origin header is present/what it is. SettingVary: OrigininsideoriginBoundaryavoids incorrect caching and aligns with the later CORS reflection behavior for allowed Origins.
const originBoundary: express.RequestHandler = (req, res, next) => {
if (!isOriginAllowed(req.headers.origin, security)) {
res.status(403).json({
jsonrpc: "2.0",
error: { code: -32000, message: "Invalid Origin header" },
|
Review update for
|
Summary
/mcpboundary before parsing, CORS, authentication, rate limiting, or server constructionTesting
npm exec -- tsx __tests__/unit/http-security.test.ts(28 passed)npm exec -- tsx __tests__/integration/http-server.test.ts(59 passed)npm test(711 passed)npm run test:coverage(94.72% lines, 91.9% branches)npm run lintnpm run buildnpm run test:e2e(26 passed)npm run verify:packed-consumernpm audit --audit-level=moderatenpm audit --omit=dev --audit-level=moderate