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`.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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
valueattributes (templates/admin/settings.php:44,49). Although escaped (no XSS) and gated onmanage_billing, the live secret lands in page source, browser cache, and history on every settings load. Secrets are also stored plaintext inwp_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 inwp_options.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.