Skip to content

enhancement(settings): hide Subscription Token value on settings page#4324

Open
faisalahammad wants to merge 2 commits into
10up:developfrom
faisalahammad:fix/4305-hide-subscription-token
Open

enhancement(settings): hide Subscription Token value on settings page#4324
faisalahammad wants to merge 2 commits into
10up:developfrom
faisalahammad:fix/4305-hide-subscription-token

Conversation

@faisalahammad

@faisalahammad faisalahammad commented Jun 19, 2026

Copy link
Copy Markdown

Summary

The Subscription Token for ElasticPress.io users was displayed in plain text on the Settings page. This change hides the value by using a password field, and it preserves the existing token when the form is submitted without a new value.

Fixes #4305

Changes

includes/partials/settings-page.php

Before:

<input type="text" value="<?php echo esc_attr( $credentials['token'] ); ?>" name="ep_credentials[token]" id="ep_token">

After:

<input type="password" value="" autocomplete="new-password" placeholder="<?php echo esc_attr( $credentials['token'] ? '••••••••' : '' ); ?>" name="ep_credentials[token]" id="ep_token">

Why: Type password alone was not enough because the browser could still expose the value via DevTools. Leaving the value empty and using a placeholder means the token is never sent back to the browser.

includes/classes/Screen/Settings.php

Before:

if ( isset( $post['ep_credentials'] ) ) {
    $credentials = Utils\sanitize_credentials( $post['ep_credentials'] );
    Utils\update_option( 'ep_credentials', $credentials );
}

After:

if ( isset( $post['ep_credentials'] ) ) {
    $credentials = Utils\sanitize_credentials( $post['ep_credentials'] );

    if ( empty( $credentials['token'] ) ) {
        $prev_credentials     = Utils\get_epio_credentials();
        $credentials['token'] = $prev_credentials['token'];
    }

    Utils\update_option( 'ep_credentials', $credentials );
}

Why: Since the token input is always empty on page load, an empty POST value means the user did not change it. This prevents overwriting the stored token with an empty value on every save.

Testing

Test 1: Token is not exposed in the page

  1. Load ElasticPress > Settings with an existing token.
  2. Inspect the token input element.
  3. Confirm value="" and that the actual token is not in the DOM.

Result: Token not exposed in page source.

Test 2: Save without changing the token

  1. Load the Settings page.
  2. Click Save Changes without entering anything in the token field.
  3. Verify the token still works.

Result: Existing token is preserved.

Test 3: Update the token

  1. Enter a new value in the token field.
  2. Save Changes.
  3. Verify the new token is stored.

Result: New token is saved correctly.

Screenshots

Before:
image

After:
image

- Change token input from type=text to type=password
- Remove token value from HTML, use masked placeholder instead
- Preserve existing token in DB when field submitted empty
- Update description text to reflect new behavior

Fixes 10up#4305

@burhandodhy burhandodhy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Please add tests to cover these changes.

- Guard credentials update when EP_CREDENTIALS defined (prevent crafted POST leaking wp-config token to wp_options)
- Reuse prev_ep_credentials instead of redundant get_epio_credentials read
- Remove dead ternary branch
- Add tests for token preserve-on-empty and new-token save
- Add CHANGELOG Security entry

Refs 10up#4324

@faisalahammad faisalahammad left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up to address feedback before review. Pushed in 4e0092a:

  • Leak guard: when EP_CREDENTIALS is defined, a crafted POST could persist the wp-config token into wp_options in plaintext. The credentials update block now short-circuits when the constant is set, consistent with the field's existing disabled attribute.
  • Redundant read removed: reuse $this->prev_ep_credentials (already fetched at the top of action_admin_init) instead of calling get_epio_credentials() again.
  • Dead ternary branch removed inside the isset guard.
  • Tests added (TestSettings): token preserved on empty POST, new token saved. Both skip when EP_CREDENTIALS is defined.
  • CHANGELOG: Security entry under Unreleased.

composer run lint clean, composer run test-single-site -- --filter TestSettings passes (9 tests).

Ready for review.

@faisalahammad

Copy link
Copy Markdown
Author

Pushed follow-up addressing feedback before review (commit 4e0092a). Leak guard for EP_CREDENTIALS, redundant read removed, dead branch removed, tests + CHANGELOG added. Lint clean, 9/9 TestSettings pass. Ready for review @felipeelia.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hide Subscription Token value

2 participants