Skip to content

security: restrict upload_attachment file access to upload root#113

Merged
paradoxbound merged 3 commits intomainfrom
paradoxbound/security-upload-root
Mar 26, 2026
Merged

security: restrict upload_attachment file access to upload root#113
paradoxbound merged 3 commits intomainfrom
paradoxbound/security-upload-root

Conversation

@paradoxbound
Copy link
Copy Markdown
Owner

Summary

  • upload_attachment previously accepted any filesystem path with no restriction, allowing arbitrary file reads when write mode was enabled
  • Now validates paths against a configurable upload root directory (BOOKSTACK_UPLOAD_ROOT env var, defaults to cwd)
  • Blocks path traversal via .. segments using path.resolve()

Security

  • Finding: CSO audit identified that a prompt injection attack in BookStack page content could instruct the LLM to exfiltrate local files (SSH keys, AWS creds, .env) via upload_attachment
  • Severity: HIGH (9/10 confidence, independently verified)
  • Fix: Path traversal protection with configurable BOOKSTACK_UPLOAD_ROOT
  • Tests: 2 new tests verify protection (path outside root + traversal attack)

Changes

  • packages/core/src/types.ts — add uploadRoot to BookStackConfig
  • packages/core/src/bookstack-client.ts — validate file path against upload root before reading
  • packages/stdio/src/index.ts — read BOOKSTACK_UPLOAD_ROOT env var, log it at startup
  • packages/core/tests/api-methods.test.ts — 2 new tests for path restriction + traversal

Test plan

  • npm run build — compiles without errors
  • npm test — 111 tests pass (2 new security tests)
  • npm audit — 0 vulnerabilities

🤖 Generated with Claude Code

paradoxbound and others added 3 commits March 26, 2026 22:35
Prevent arbitrary filesystem reads via upload_attachment by validating
file paths against a configurable root directory (BOOKSTACK_UPLOAD_ROOT
env var, defaults to cwd). Uses path.resolve() to block traversal
attacks via .. segments.

Signed-off-by: Jim <paradoxbound@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Jim <paradoxbound@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The upload_attachment functional test writes to os.tmpdir(), which is
outside cwd. Set uploadRoot to os.tmpdir() in the test config so the
path validation allows it.

Signed-off-by: Jim <paradoxbound@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@paradoxbound paradoxbound merged commit c1dce82 into main Mar 26, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants