HarperFast / HarperFast/harper

[security] checkAllowedModulePath uses prefix match without a path-separator boundary

Open Beginner friendly
#1,929 1 comment 0 reactions 0 assignees View on GitHub
area:security
Dominant language
JavaScript
Stars
89
Forks
10
Avg merge
2d 6h
Merged PRs (30d)
200

Description

**Severity:** LOW · **Category:** `path-traversal` · **CWE-22**
**Location:** `security/jsLoader.ts:1091` in `checkAllowedModulePath`

## Impact
A component could read/execute another component's module source that resides in a sibling directory sharing a name prefix, breaking per-component file confinement.

## Details
The module-path confinement uses `path.startsWith(allowedPath)` with no trailing-separator boundary, so a sibling path whose name merely begins with allowedPath (e.g. allowedPath `/opt/harper/app1` vs `/opt/harper/app1-evil`) is treated as inside the allowed directory, letting a component load/execute module source outside its intended directory.

## Exploit scenario
Component confined to /opt/harper/components/app imports a relative/absolute specifier resolving to /opt/harper/components/app-shared/secret.js; realpath starts with the allowed prefix, so the guard passes and the out-of-scope file is loaded.

## Preconditions
- A sibling directory exists whose absolute path starts with the allowed path string
- Component-supplied module specifiers resolve into that sibling directory

## Recommended fix
Normalize allowedPath to end with the platform path separator (or compare with `path === allowedPath || path.startsWith(allowedPath + sep)`) before the prefix comparison.

---
Found by an automated multi-agent security review (Claude Security) against `origin/main` @ `2615b092b`, confirmed by a three-lens verification panel. Line numbers are as of that commit. No code was executed; derived from source review, so validate before remediation.

Contributor guide

Open the contributing guide

Research direction

Start in security/jsLoader.ts at checkAllowedModulePath around line 1091 and inspect how resolved paths are compared with allowedPath. Validate the boundary behavior using the sibling-directory scenario described in the issue. Done means descendants of the allowed directory remain accepted while similarly prefixed sibling paths are rejected.

Written by the indexing model from the issue text.

Assessment

Tech stack
nodejs, typescript
Domain
backend, security
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
77/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.