Skip to content

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

Open
huubl wants to merge 1 commit intoWordPress:trunkfrom
huubl:convert-set-attribute-csp-unsafe-inline
Open

CSP: Refactor accessibility scripts to use Object.assign for style attributes#67988
huubl wants to merge 1 commit intoWordPress:trunkfrom
huubl:convert-set-attribute-csp-unsafe-inline

Conversation

@huubl
Copy link
Copy Markdown
Contributor

@huubl huubl commented Dec 14, 2024

What?

Refactor: Use Object.assign to set inline style

More info:
#68021

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 'self' 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'.
@github-actions
Copy link
Copy Markdown

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 <huubl@git.wordpress.org>

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

[Package] A11y /packages/a11y [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants