HarperFast / HarperFast/harper

GraphQL returns HTTP 500 on auth/authz denials instead of 401/403

Open Beginner friendly
#1,299 2 comments 0 reactions 0 assignees View on GitHub
area:auth area:GraphQL bug
Dominant language
JavaScript
Stars
89
Forks
10
Avg merge
1d 23h
Merged PRs (30d)
215

Description

## Summary
On the GraphQL surface, authentication/authorization denials surface as **HTTP 500** instead of the correct 401/403 (REST and the operations API return the right codes):

| token | OPS API | REST | GraphQL |
|---|---|---|---|
| valid | 200 | 200 | 200 |
| **expired** | 401 | 401 | **500** |
| tampered payload / signature | 401 | 401 | 401 |
| **under-privileged (valid, no perm)** | 403 | 403 | **500** |

**This is not a security bypass** — expired/tampered tokens are never accepted and no data leaks (verified: the protected value never appears in any response body). It is a wrong-status-code bug on a security-relevant path: a client can't distinguish "re-authenticate / refresh token" from "server error," which breaks auth-retry logic.

## Root cause
`server/graphqlQuerying.ts` (~613-647 / 681-688) maps an `HTTPError` to its status but a plain `Error` to **500**. The resource-layer auth errors (`AccessViolation`, `ClientError` "Must login" / "token expired") carry `statusCode` 401/403 but are **not** `instanceof HTTPError` in that module, so they hit the generic 500 fallthrough and the statusCode is discarded. REST (`auth.ts` / `REST.ts`) honors `error.statusCode`. Reproduced on two independent denial causes, so it's systematic.

(Signature verification itself is correct — `jwt.verify` pins `algorithms:['RS256']`, blocking alg-confusion; tampered tokens are rejected on every surface.)

## Suggested fix
In `graphqlQuerying.ts`, honor `error.statusCode` (or treat `AccessViolation`/`ClientError` like `HTTPError`) so GraphQL returns 401/403 consistent with REST.

## Repro
`integrationTests/qa-scratch/jwt-auth.test.ts` (the one failing assertion is the GraphQL-500 case).

---
_Found via the exploratory QA campaign (qa-explorer), scenario QA-090. Harper `001bf7b9c` (v5.1.0, main)._

Contributor guide

Open the contributing guide

Research direction

Start in server/graphqlQuerying.ts around lines 613-647 and 681-688, then compare status handling in auth.ts and REST.ts. Run integrationTests/qa-scratch/jwt-auth.test.ts and verify that expired-token and under-privileged GraphQL cases return 401 and 403 rather than 500.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, javascript
Domain
api, authentication, authorization
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.