ampproject / amp-wp

Enable AMP on your WordPress site, the WordPress way.
https://wordpress.org/plugins/amp/
GNU General Public License v2.0
1.79k stars 383 forks source link

Provide means to add CSP `nonce` attributes to AMP component script tags #7720

Closed westonruter closed 9 months ago

westonruter commented 9 months ago

Feature Description

See support topic: https://wordpress.org/support/topic/add-nonce-to-amp-scripts/

It seems like both the AMP plugin and the AMP Optimizer should have some way to be configured so that when they construct script tags that the provided nonce is included as an attribute.

Acceptance Criteria

No response

Implementation Brief

No response

QA Testing Instructions

No response

Demo

No response

Changelog Entry

No response

westonruter commented 9 months ago

This should actually be possible without modifying the AMP plugin or AMP Optimizer by registering a new Transformer for the AMP Optimizer which runs at the very end. It can add the nonce attributes. This could then be put into a mini plugin to extend the AMP plugin.

westonruter commented 9 months ago

Here's how it can be implemented with plugin code:

namespace AMP_CSP_Scripts;

add_filter(
    'amp_optimizer_config',
    static function ( $config ) {
        require_once __DIR__ . '/ScriptNonceTransformer.php';
        $config['transformers'][] = ScriptNonceTransformer::class;
        return $config;
    }
);

Then in the same directory another file called ScriptNonceTransformer.php:

namespace AMP_CSP_Scripts;

use AmpProject\Optimizer\Transformer;
use AmpProject\Dom\Document;
use AmpProject\Optimizer\ErrorCollection;
use DOMElement;

class ScriptNonceTransformer implements Transformer {
    public function transform( Document $document, ErrorCollection $errors ) {
        $scripts = $document->xpath->query( '//script[ not( @type ) or @type = "module" ]' );
        foreach ( $scripts as $script ) {
            /** @type DOMElement $script */
            $script->setAttribute( 'nonce', 'fooo' );
        }
    }
}

Naturally replace 'foo' with whatever your nonce is for the current response.

westonruter commented 9 months ago

Actually, since it is quite straightforward to implement with a custom transformer, I'm going to close this since it probably doesn't warrant any change to the plugin itself.

jcvignoli commented 9 months ago

I confirm this approach works. Would be great however not to have it in the future fully integrated in the plugin :)