Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSP: Refactor accessibility scripts to use Object.assign for style attributes #67988

Open
wants to merge 1 commit into
base: trunk
Choose a base branch
from

Conversation

huubl
Copy link
Contributor

@huubl huubl commented Dec 14, 2024

What?

Refactor: Use Object.assign to set inline style

Why?

This change will not be blocked by a CSP without unsafe-inline.

How?

The implementation replaces the existing setAttribute call with Object.assign, applying individual style properties to the element's style object.

Testing Instructions

  1. Install Wordpress and activate the Twenty Nineteen theme
  2. Add the following code to the functions.php file of the Twenty Nineteen theme:
// Enqueue the wp-a11y script plus internal script that uses a wp-a11y function that sets inline styles
function enqueue_wp_a11y_script() {

	wp_enqueue_script('wp-a11y');

	$internal_script = "
        document.addEventListener('DOMContentLoaded', function() {
            if (typeof wp !== 'undefined' && wp.a11y && wp.a11y.speak) {
                wp.a11y.speak( 'The message you want to send to the ARIA live region', 'assertive' );
            }
        });
    ";
	wp_add_inline_script('wp-a11y', $internal_script);
}
add_action('wp_enqueue_scripts', 'enqueue_wp_a11y_script');

// Add CSP without unsafe-inline
// To reduce CSP violations/noise: Added nonces to internal script and style tags/directives, allow data: in font-src and https://secure.gravatar.com as img-src
function add_csp_without_unsafe_inline() {
	ob_start( function ( $output ) {
		static $nonce = null;

		if ( $nonce === null ) {
			$nonce = bin2hex( openssl_random_pseudo_bytes( 32 ) );
		}

		$output = preg_replace_callback( '#<script.*?\>#', function ( $matches ) use ( $nonce ) {
			return str_replace( '<script', "<script nonce='{$nonce}'", $matches[0] );
		}, $output );

		$output = preg_replace_callback( '#<style.*?\>#', function ( $matches ) use ( $nonce ) {
			return str_replace( '<style', "<style nonce='{$nonce}'", $matches[0] );
		}, $output );

		header( "Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{$nonce}'; style-src 'self' 'nonce-{$nonce}'; font-src 'self' data:; img-src https://secure.gravatar.com" );

		return $output;
	} );
}
add_action( 'template_redirect', 'add_csp_without_unsafe_inline');
  1. Open the website in a browser and check the console for CSP violations in wp-a11y script
  2. Activate the Gutenberg plugin with this commit and confirm that the wp-a11y script is still enqueued but no longer triggers CSP violations

Testing Instructions for Keyboard

Screenshots or screencast

The Object.assign() method modifies individual CSS properties through the JavaScript API, which is not blocked by Content Security Policy (CSP) without the 'unsafe-inline' directive. In contrast, setAttribute('style', '...') is considered an inline style and would be blocked by CSP without 'unsafe-inline'.
Copy link

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: huubl <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

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.

1 participant