apache / apache/apisix-dashboard

bug: credential secrets, SSL private keys, and plugin tokens are displayed in plaintext in view mode

Open
#3,416 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
TypeScript
Stars
1.2k
Forks
617
Avg merge
4d 18h
Merged PRs (30d)
1

Description

### Issue description

Sensitive values are rendered in **plaintext** across the dashboard's read paths. The masking added in d32c945 covers only the secret-manager forms (Vault token, AWS keys, GCP private key) and the Settings admin-key field; the most common credential paths are unprotected:

1. **Consumer credential secrets** — a key-auth `key`, basic-auth `password`, jwt-auth `secret`, hmac-auth `secret_key` are fully visible: open the credential's detail page → the plugin card's **View** drawer shows e.g. `{"key": "SUPER-SECRET-KEY-12345"}` verbatim in the Monaco editor, in read-only *view* mode, with zero interaction needed beyond opening the card. (Verified live on master `9979b31`.) Path: `FormPartCredential.tsx` → `FormItemPlugins` → `PluginEditorDrawer` — no masking concept exists anywhere in the Monaco render path.
2. **SSL private keys** — the SSL detail page renders `key` / `keys[i]` through `FormItemTextareaWithUpload`, a plain textarea showing whatever the Admin API returns, unmasked, expanded via autosize in view mode (`FormPartSSL/FormItemCertKeyList.tsx`).
3. **Plugin configs containing tokens** — any plugin whose config embeds secrets (`ai-proxy`/`ai-proxy-multi` API keys, `limit-*` `redis_password`, logger auth headers, `forward-auth`, …) displays them verbatim in the same editor drawer on routes/services/global rules detail views.
4. **Transient echo in error toasts** — the interceptor toasts raw Admin API error bodies (`error_msg`), which for schema-validation failures can include the submitted secret value (`src/config/req.ts`).

### Expected behavior

- In **view** mode, known-sensitive JSON paths are redacted by default (`"key": "•••••"`) with an explicit reveal affordance, mirroring how `FormPartSecret` already treats vault/aws/gcp fields.
- SSL private key fields use a masked control in view mode (certs can stay plaintext).
- Error toasts truncate long bodies rather than echoing full submitted payloads.

### Suggested implementation

Maintain a small per-plugin sensitive-path registry (`key-auth.key`, `basic-auth.password`, `jwt-auth.secret`, `hmac-auth.secret_key`, `ai-proxy.auth.*`, `*.redis_password`, …) and apply it as a display-transform in `PluginEditorDrawer`'s view mode before handing the JSON to Monaco. Edit mode can stay unmasked (an editor must show what it edits), which still removes the shoulder-surfing/screen-share exposure from the default read path.

### Environment

- apisix-dashboard: master (`9979b31`)

Related: #3218 (the original report; this issue records the verified residual scope after d32c945)

Contributor guide

Open the contributing guide

Research direction

Start by reading PluginEditorDrawer and the FormPartCredential.tsx → FormItemPlugins path, comparing its view rendering with FormPartSecret. Then inspect FormPartSSL/FormItemCertKeyList.tsx and src/config/req.ts for the SSL and error-toast paths. Done means sensitive plugin and SSL values are masked in view mode with explicit reveal behavior, while error toasts no longer echo submitted secrets.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.