lxbme opened a new pull request, #3455:
URL: https://github.com/apache/apisix-dashboard/pull/3455

   Please answer these questions before submitting a pull request, **or your PR 
will get closed**.
   
   **Why submit this pull request?**
   
   - [x] Bugfix
   - [ ] New feature provided
   - [ ] Improve performance
   - [ ] Backport patches
   
   **What changes will this PR take into?**
   
   Opening a credential's plugin card in the read-only **View** drawer rendered 
its secret verbatim — a key-auth `key`, a basic-auth `password`, a jwt-auth 
`secret` — with no interaction beyond opening the card. The same drawer shows 
plugin configs on routes, services and global rules, so any plugin embedding a 
token appeared the same way.
   
   Those values now render as `••••••`, with a **Show secrets** button to 
reveal them. This takes secrets out of the default read path: shoulder-surfing, 
screenshots, screen shares, and a browser left open on a detail page.
   
   **The list of sensitive fields comes from the gateway.** `GET 
/apisix/admin/plugins?all=true` — the request that already drives the plugin 
editor — returns `encrypt_fields` inside each plugin's `schema` and 
`consumer_schema`. On 3.17.0 that covers 40 plugins:
   
   | plugin | `encrypt_fields` |
   | --- | --- |
   | `key-auth` | `["key"]` |
   | `basic-auth` | `["password"]` |
   | `jwt-auth` | `["secret"]` |
   | `hmac-auth` | `["secret_key"]` |
   | `limit-count` | `["redis_password", "sentinel_password"]` |
   | `openid-connect` | `["client_secret", "client_rsa_private_key", 
"session.secret", "session.redis.password"]` |
   | `ai-proxy` | `["auth.header", "auth.query", 
"auth.gcp.service_account_json", "auth.aws.secret_access_key", …]` |
   | `kafka-logger` | `["brokers.sasl_config.password"]` |
   
   …plus `clickhouse-logger`, `elasticsearch-logger`, `splunk-hec-logging`, 
`aws-lambda`, `azure-functions`, `authz-keycloak`, `saml-auth`, 
`google-cloud-logging`, and others. Reading the mask from the gateway means it 
stays correct as plugins change, third-party plugins are covered as soon as 
they declare it, and no extra request is made — the data already arrives with 
the schema the drawer receives.
   
   One detail worth flagging for review: the gateway emits **flat dotted paths 
even when a segment crosses an array** — `kafka-logger`'s 
`brokers.sasl_config.password` where `brokers` is `type: array`, and 
`ai-proxy-multi`'s `instances.auth.header`. A walker that treats every segment 
as an object property finds nothing there, returns the config untouched, and 
leaves the password in plaintext — a failure that looks exactly like success. 
`redactByPaths` fans out over arrays, and a unit test pins it with a 
two-element array so a first-element-only bug also fails.
   
   ### The SSL private key field
   
   The Admin API does not return private keys: `GET /apisix/admin/ssls/{id}` 
yields `cert`, `sni`, `id` and timestamps. The field is therefore always empty, 
and since it is `required`, Save is blocked by the browser's generic "please 
fill out this field" — so changing an SSL's SNI requires re-pasting a private 
key, with nothing on the page explaining why. 
`e2e/tests/ssls.crud-required-fields.spec.ts` works around this today ("Click 
Cancel instead of Save to avoid validation issues with empty key").
   
   Both private-key fields now carry a `••••••` placeholder and the note *"The 
gateway never returns private keys. Enter the key again to save any change."*
   
   **Related issues**
   
   #3416
   
   **Checklist:**
   
   - [x] Did you explain what problem does this PR solve? Or what new features 
have been added?
   - [x] Have you added corresponding test cases?
   - [ ] Have you modified the corresponding document?
   - [x] Is this PR backward compatible? If it is not backward compatible, 
please discuss on the mailing list first
   
   ### Tests
   
   Unit tests cover `redactByPaths`: nested paths, the array fan-out above, a 
declared path absent from the config, non-string leaves, no mutation of the 
input, and tolerance of a malformed `encrypt_fields` — the field crosses the 
network, so its shape is validated rather than assumed.
   
   An e2e spec covers both directions. One test asserts the plaintext secret is 
**absent** from the page while `••••••` is present, that view mode exposes no 
Save control, and that Show secrets brings the real value back. The other 
asserts that **edit mode receives the real config** — the direction that 
matters, since redaction leaking into a mutable mode would write `••••••` over 
a live credential on save.
   
   Both were mutation-tested: reverting the drawer change makes the first fail; 
removing the view-mode guard so redaction reaches edit mode makes the second 
fail. Each fails only for its own regression.
   
   Verified: `pnpm test` 93/93, `pnpm lint`, `pnpm exec tsc -b`, and a 
production `pnpm build` all clean; e2e green across `e2e/tests/regression/` and 
both `ssls.crud-*` specs. Checked by hand in Chrome in English and Chinese — 
including that revealing a secret and reopening the drawer starts masked again.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to