Skip to content

Commit 727447f

Browse files
committed
Fix: Escape output in Settings API - use wp_kses, replace script template with HTML template element
- Replace unescaped echo with wp_kses_post() in Settings_API::show_navigation() - Switch repeater template from <script type="text/template"> to <template> element - Update JS to use .get(0).innerHTML for <template> content retrieval - Use wp_kses() with get_allowed_html() for repeater output - Use wp_kses_post() for WYSIWYG field description - Inline aria-current attribute in wizard step navigation - Add <template> to allowed HTML tags in get_allowed_html()
1 parent 98eb85e commit 727447f

5 files changed

Lines changed: 18 additions & 15 deletions

File tree

includes/admin/settings/class-settings-api.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Functions to register, read, write and update settings.
66
* Portions of this code have been inspired by Easy Digital Downloads, WordPress Settings Sandbox, WordPress Settings API class, etc.
77
*
8-
* @package WebberZone\Contextual_Related_Posts
8+
* @package WebberZone\Contextual_Related_Posts
99
*/
1010

1111
namespace WebberZone\Contextual_Related_Posts\Admin\Settings;
@@ -997,7 +997,7 @@ public function show_navigation() {
997997

998998
$html .= '</ul>';
999999

1000-
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1000+
echo wp_kses_post( $html );
10011001
}
10021002

10031003
/**

includes/admin/settings/class-settings-form.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* @link https://webberzone.com
66
*
7-
* @package WebberZone\Contextual_Related_Posts
7+
* @package WebberZone\Contextual_Related_Posts
88
*/
99

1010
namespace WebberZone\Contextual_Related_Posts\Admin\Settings;
@@ -219,9 +219,9 @@ protected function get_allowed_html(): array {
219219
'style' => true,
220220
'disabled' => true,
221221
),
222-
'em' => array(
223-
'style' => true,
224-
'class' => true,
222+
'template' => array(
223+
'class' => true,
224+
'data-id' => true,
225225
),
226226
);
227227

@@ -867,7 +867,7 @@ public function callback_wysiwyg( $args ) {
867867

868868
printf( '</div>' );
869869

870-
echo $this->get_field_description( $args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
870+
echo wp_kses_post( $this->get_field_description( $args ) );
871871
}
872872

873873
/**
@@ -961,16 +961,16 @@ public function callback_repeater( $args ) {
961961
<?php echo esc_html( ! empty( $args['add_button_text'] ) ? $args['add_button_text'] : 'Add Item' ); ?>
962962
</button>
963963

964-
<script type="text/template" class="repeater-template" data-id="<?php echo esc_attr( $args['id'] ); ?>">
964+
<template class="repeater-template" data-id="<?php echo esc_attr( $args['id'] ); ?>">
965965
<?php $this->render_repeater_item( $args, '{{INDEX}}' ); ?>
966-
</script>
966+
</template>
967967
</div>
968968
<?php
969969
$html = ob_get_clean();
970970
$html .= $this->get_field_description( $args );
971971

972972
/** This filter has been defined in class-settings-api.php */
973-
echo apply_filters( $this->prefix . '_after_setting_output', $html, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound,WordPress.Security.EscapeOutput.OutputNotEscaped -- Contains <script type="text/template"> which wp_kses would strip.
973+
echo wp_kses( apply_filters( $this->prefix . '_after_setting_output', $html, $args ), $this->get_allowed_html() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound
974974
}
975975

976976
/**

includes/admin/settings/class-settings-wizard-api.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* A reusable API class for creating multi-step settings wizards.
66
* This class provides the framework for creating guided setup experiences.
77
*
8-
* @package WebberZone\Contextual_Related_Posts
8+
* @package WebberZone\Contextual_Related_Posts
99
*/
1010

1111
namespace WebberZone\Contextual_Related_Posts\Admin\Settings;
@@ -837,7 +837,6 @@ protected function render_wizard_steps_navigation() {
837837
$step_config = $this->steps[ $step_key ];
838838
$is_current = $step_number === $this->current_step;
839839
$is_completed = $step_number < $this->current_step;
840-
$aria_current = $is_current ? ' aria-current="step"' : '';
841840
$class_parts = array();
842841

843842
if ( $is_current ) {
@@ -848,7 +847,7 @@ protected function render_wizard_steps_navigation() {
848847

849848
$class = implode( ' ', $class_parts );
850849
?>
851-
<li class="<?php echo esc_attr( $class ); ?>"<?php echo $aria_current; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
850+
<li class="<?php echo esc_attr( $class ); ?>"<?php echo $is_current ? ' aria-current="step"' : ''; ?>>
852851
<?php if ( $is_completed ) : ?>
853852
<a href="<?php echo esc_url( $this->get_step_url( $step_number ) ); ?>" class="step-link">
854853
<span class="step-number"><?php echo esc_html( (string) $step_number ); ?></span>

includes/admin/settings/js/settings-admin-scripts.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@ jQuery(document).ready(function ($) {
7979

8080
// Add Item.
8181
wrapper.on('click', '.add-item', function () {
82-
var template = wrapper.find('.repeater-template').html();
82+
var templateEl = wrapper.find('.repeater-template').get(0);
83+
if (!templateEl) {
84+
return;
85+
}
86+
var template = templateEl.innerHTML;
8387
var uniqueId = 'row_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
8488
template = template.replace(/{{INDEX}}/g, index);
8589
template = template.replace(/{{ROW_ID}}/g, uniqueId);

includes/admin/settings/js/settings-admin-scripts.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)