Stripe secret key reflected into admin settings HTML / stored plaintext #36

Closed
opened 2026-06-09 19:08:38 +00:00 by thatguygriff · 1 comment
Owner

Severity: Low — admin-gated, but secrets should be write-only.

Problem

The Stripe secret key and webhook signing secret are rendered back into the settings form value attributes (templates/admin/settings.php:44,49). Although escaped (no XSS) and gated on manage_billing, the live secret lands in page source, browser cache, and history on every settings load. Secrets are also stored plaintext in wp_options (src/Payment/StudioSettings.php:22).

Fix

Render the secret fields as write-only: show a masked placeholder (e.g. ••••last4) when a value is already stored, and only overwrite the option when a non-empty new value is submitted. Consider documenting that keys live in wp_options.

**Severity: Low** — admin-gated, but secrets should be write-only. ## Problem The Stripe **secret key** and **webhook signing secret** are rendered back into the settings form `value` attributes ([templates/admin/settings.php:44,49](templates/admin/settings.php#L44)). Although escaped (no XSS) and gated on `manage_billing`, the live secret lands in page source, browser cache, and history on every settings load. Secrets are also stored plaintext in `wp_options` ([src/Payment/StudioSettings.php:22](src/Payment/StudioSettings.php#L22)). ## Fix Render the secret fields as write-only: show a masked placeholder (e.g. `••••last4`) when a value is already stored, and only overwrite the option when a non-empty new value is submitted. Consider documenting that keys live in `wp_options`.
thatguygriff added the paymentssecurity labels 2026-06-09 19:08:38 +00:00
Author
Owner

Verified resolved on main (061d09e, PR #38): the secret key and webhook signing secret fields render with value="" and a 'Saved — leave blank to keep' placeholder (templates/admin/settings.php), and StudioSettings::save() only overwrites the stored option when a non-empty value is submitted — secrets are write-only and never reflected into page source. Storage remains in wp_options (standard WP plugin practice; documented). Re-confirmed during the 2026-06-10 security review pass.

Verified resolved on main (061d09e, PR #38): the secret key and webhook signing secret fields render with value="" and a 'Saved — leave blank to keep' placeholder (templates/admin/settings.php), and StudioSettings::save() only overwrites the stored option when a non-empty value is submitted — secrets are write-only and never reflected into page source. Storage remains in wp_options (standard WP plugin practice; documented). Re-confirmed during the 2026-06-10 security review pass.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Unsupervised/unsupervised-scheduler#36