Security audit fixes: fn() whitelist, escaping, and performance (v0.1.4)
All checks were successful
Create Release Package / PHP Lint (push) Successful in 1m41s
Create Release Package / Build Release (push) Successful in 1m47s

- WooCommerceExtension: ALLOWED_FUNCTIONS whitelist for fn() Twig function
- Notice templates: data attributes use wp_kses_post instead of raw
- Search form: esc_attr on search query value attribute
- Per-request ContextBuilder caching via static variable
- Shared wc_bootstrap_render_in_page_shell() helper (DRY)
- Removed unused WC_BOOTSTRAP_VERSION and WC_BOOTSTRAP_URL constants

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 01:02:43 +01:00
parent e72b4ba3c1
commit 98359d4cfb
9 changed files with 118 additions and 65 deletions

View File

@@ -235,18 +235,40 @@ class WooCommerceExtension extends AbstractExtension {
}
/**
* Call a PHP function by name and return its result.
* Allowlist of PHP functions that can be called via fn() in Twig templates.
*
* Prevents arbitrary function execution (e.g., exec, system) if template
* context were ever compromised. Only functions actually used in templates
* are permitted.
*/
private const ALLOWED_FUNCTIONS = [
'WC',
'_n',
'get_pagenum_link',
'wc_review_ratings_enabled',
'wc_get_product_category_list',
'wc_get_product_tag_list',
];
/**
* Call a whitelisted PHP function by name and return its result.
*
* Enables `fn('WC')` in templates to access the WooCommerce singleton
* and chain method calls via Twig's property accessor.
*
* Only functions in the ALLOWED_FUNCTIONS list can be called. This prevents
* arbitrary code execution if template context were ever compromised.
*
* @param string $name Function name.
* @param mixed ...$args Arguments.
* @return mixed Function return value.
*
* @throws \RuntimeException If function does not exist.
* @throws \RuntimeException If function is not allowed or does not exist.
*/
public function callFunction( string $name, ...$args ): mixed {
if ( ! in_array( $name, self::ALLOWED_FUNCTIONS, true ) ) {
throw new \RuntimeException( "Function {$name} is not allowed. Add it to ALLOWED_FUNCTIONS." );
}
if ( ! function_exists( $name ) ) {
throw new \RuntimeException( "Function {$name} does not exist." );
}