HarperFast / HarperFast/harper
[security] Login trusts server-controlled response.target to pick the credential storage key and last_target
- Dominant language
- JavaScript
- Stars
- 89
- Forks
- 10
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 200
Description
**Severity:** LOW · **Category:** `improper-authorization` · **CWE-807**
**Location:** `bin/login.ts:95` in `login`
## Impact
A malicious or compromised login endpoint (or one able to influence its JSON response body) can cause the issued JWT to be stored under an attacker-chosen key and set last_target to an attacker-chosen host, so a subsequent bare `harper ` silently connects to and sends a bearer token to that host instead of the one the user logged into.
## Details
The untrusted HTTP JSON login response (parsed at cliOperations.ts:457 and returned to login.ts) supplies response.target, which takes precedence over the user-supplied req.target and is then used as the credential-store key and last_target in saveCredentials — an authorization/routing decision derived from server-controlled data.
## Exploit scenario
User runs `harper login https://cluster.example`. The server returns valid operation_token/refresh_token plus target="https://evil.example/". The CLI stores the token under the evil key and sets last_target=evil. The next `harper deploy` (no target=) resolves last_target and POSTs with Authorization: Bearer to evil.example.
## Preconditions
- The login/authentication server is malicious or its response body can be influenced by an attacker
- User later runs a default (no-target) CLI operation that resolves last_target
## Recommended fix
Persist credentials and last_target under the client-verified target (target.resolvedTarget the CLI computed / the user-supplied normalized URL), not under a value taken from the server response body. Ignore response.target for storage-key selection.
---
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
Research direction
Start in bin/login.ts:95 and trace the login response returned from cliOperations.ts:457 into saveCredentials and last_target handling. Verify that storage-key and default-target decisions use the client-verified login target rather than response.target, then validate that a server-supplied target cannot redirect a later bare CLI operation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nodejs, typescript
- Domain
- authentication, cli, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100