Skip to content

Security: GodHelpThisCoder/PCPartPicker-MCP

Security

docs/security.md

Security

Security Development Rules

These rules apply to all code changes:

  1. Never add Puppeteer flags that disable security features (sandbox, web security, CORS). If you believe a flag is needed, document the justification and get explicit approval.
  2. All browser navigation must use safeNavigate() -- never call page.goto() directly. This validates the URL hostname against PCPP_DOMAIN_PATTERN.
  3. All tag inputs must use validateTag() -- pattern: /^[A-Za-z0-9]{6}$/. Never inline checks.
  4. All category inputs must use validateCategory() -- validates against CATEGORY_SLUGS keys.
  5. Never log full error objects -- use sanitizeErrorForLog(error) for stderr, sanitizeErrorForClient(error) for MCP responses.
  6. Never expose filesystem paths in error messages -- use generic messages with setup instructions.
  7. Cookie files must be validated -- the Zod cookie schema in cookie loading validates structure and rejects non-PCPP domains.
  8. Mock exports must be sanitized -- always wrap HTML with sanitizeMockHtml() before writing to disk.
  9. CSRF tokens must never be logged or included in error messages -- extract via extractCsrfToken(), use in /qapi/ POST headers only.
  10. All build-list identifier inputs must use validateIdentifier() -- validates max 200 chars and character allowlist /^[A-Za-z0-9 :.\-_()]+$/.

Threat Model

This server runs as a local MCP server on the developer's machine. It:

  • Launches headless Chrome instances with anti-detection spoofing
  • Navigates to pcpartpicker.com URLs constructed from user-provided parameters (tags, categories, search terms)
  • Reads and parses full page HTML, including JavaScript-rendered content
  • Executes AJAX POSTs to /qapi/ endpoints with CSRF tokens for build mutations
  • Writes mock HTML files to disk when export mode is enabled
  • Persists session cookies to disk (build server)
  • Logs operational details to stderr (captured by MCP host)

Primary attack surface: The browser. If Chrome navigates to a compromised page with disabled sandboxing, escape to the host is possible. CSRF token leakage could enable unauthorized build list mutations from external scripts.

Secondary surfaces: Cookie file handling (path injection, domain spoofing), error message leakage (internal paths/stack traces), mock export mode (PII written to disk).

PCPP-specific risks: robots.txt blocks AI user agents -- our browser automation bypasses this but may trigger additional scrutiny. Cloudflare WAF may challenge or block automated requests. The _scr() fingerprint validation may detect automation and reject /qapi/ calls.


Vulnerability Register

Phase 7 security audit completed on 2026-03-07.

Audit coverage:

  1. Navigation audit: passed (page.goto() only inside safeNavigate()).
  2. Tag/category validation audit: passed (validateTag() / validateCategory() guards present on user inputs).
  3. Error audit: passed (server handlers route logging and client responses through sanitizers).
  4. Browser cleanup audit: passed (createBrowserAndPage() call sites close browser in finally).
  5. Mock sanitization audit: passed (maybeExportMockHtml() and capture script sanitize HTML before write).
  6. CSRF audit: passed after fix (src/pcpp.navigation.test.ts now logs presence boolean, never token-derived text).
  7. Cookie audit: passed (cookie-file loader rejects non-PCPP domains via Zod refine).
  8. Dependency audit: passed after remediation (npm audit --audit-level=high reports 0 vulnerabilities).

Tier 1: CRITICAL

| ID | Description | Severity | Status | |---|---|---|

Tier 2: HIGH

| ID | Description | Severity | Status | |---|---|---| | PCPP-SEC-001 | express-rate-limit advisory GHSA-46wh-pxpv-q5gq (IPv4-mapped IPv6 bypass) was present in lockfile dependency tree. | High | Resolved on 2026-03-07 by npm audit fix (package-lock.json updated; audit now clean). |

Tier 3: MEDIUM

| ID | Description | Severity | Status | |---|---|---| | QA-R1-001 | pcpp_get_guide missing outputSchema in listTools response (protocol compliance bug). | Medium | Resolved on 2026-03-07 by adding guideToolSchema and wiring it in src/servers/research.ts. |

Tier 4: LOW

| ID | Description | Severity | Status | |---|---|---| | PCPP-SEC-002 | Navigation smoke test logged CSRF token prefix to stderr (src/pcpp.navigation.test.ts). | Low | Resolved on 2026-03-07 by replacing token-prefix logging with CSRF token present: true/false. |


Key Design Decisions

  1. Sandbox enabled by default. PCPP_MCP_DISABLE_SANDBOX=true env var for container deployments. A startup warning is logged when sandbox is disabled.

  2. Domain allowlist is a regex constant, not config. PCPP_DOMAIN_PATTERN in src/constants.ts is hardcoded. A configurable list could be tampered with.

  3. safeNavigate() is a wrapper, not middleware. Each page.goto() call is replaced with safeNavigate(page, url) which validates the URL hostname before navigating. More explicit and auditable than request interception.

  4. Cookie validation uses Zod. The same Zod library used for MCP tool schemas validates the cookie file structure, including domain validation against the PCPP allowlist.

  5. Error sanitization is centralized. Two shared functions (sanitizeErrorForLog and sanitizeErrorForClient) in src/utils.ts centralize the logic.


Container / CI Notes

Chrome sandbox requires kernel features (user namespaces, seccomp-bpf) that may not be available in Docker containers or CI environments running as root. In these environments:

PCPP_MCP_DISABLE_SANDBOX=true node build/servers/research.js

A [WARNING] message is logged to stderr when sandbox is disabled. This is the only supported way to disable sandbox -- never add --no-sandbox to the Puppeteer launch args directly.

There aren’t any published security advisories