@@ -251,3 +251,48 @@ function jq_image_posted_on() {
251251
252252 return $ classes ;
253253} );
254+
255+ /**
256+ * Content Security Policy
257+ */
258+ function jq_content_security_policy () {
259+ if ( !JQUERY_STAGING ) {
260+ return ;
261+ }
262+ $ nonce = bin2hex ( random_bytes ( 8 ) );
263+ $ report_url = 'https://csp-report-api.openjs-foundation.workers.dev/ ' ;
264+ $ policy = array (
265+ 'default-src ' => "'self' " ,
266+ 'script-src ' => "'self' 'nonce- $ nonce' code.jquery.com " ,
267+ // The nonce is here so inline scripts can be used in the theme
268+ 'style-src ' => "'self' 'nonce- $ nonce' " ,
269+ // data: SVG images are used in typesense
270+ 'img-src ' => "'self' data: " ,
271+ 'connect-src ' => "'self' typesense.jquery.com " ,
272+ 'font-src ' => "'self' " ,
273+ 'object-src ' => "'none' " ,
274+ 'media-src ' => "'self' " ,
275+ 'frame-src ' => "'self' " ,
276+ 'child-src ' => "'self' " ,
277+ 'form-action ' => "'self' " ,
278+ 'frame-ancestors ' => "'none' " ,
279+ 'base-uri ' => "'self' " ,
280+ 'block-all-mixed-content ' => '' ,
281+ 'report-to ' => 'csp-endpoint ' ,
282+ // Add report-uri for Firefox, which
283+ // does not yet support report-to
284+ 'report-uri ' => $ report_url ,
285+ );
286+
287+ $ policy = apply_filters ( 'jq_content_security_policy ' , $ policy );
288+
289+ $ policy_string = '' ;
290+ foreach ( $ policy as $ key => $ value ) {
291+ $ policy_string .= $ key . ' ' . $ value . '; ' ;
292+ }
293+
294+ header ( 'Reporting-Endpoints: csp-endpoint=" ' . $ report_url . '" ' );
295+ header ( 'Content-Security-Policy-Report-Only: ' . $ policy_string );
296+ }
297+
298+ add_action ( 'send_headers ' , 'jq_content_security_policy ' );
0 commit comments