tincanny_content_security_policy
Filters the Content Security Policy string, allowing modification of allowed script sources.
add_filter( 'tincanny_content_security_policy', $callback, 10, 1 );
Description
Allows developers to modify the Content Security Policy header. This hook is applied before headers are sent, enabling fine-grained control over allowed script sources, inline scripts, and eval. Use with caution to avoid security vulnerabilities.
Usage
add_filter( 'tincanny_content_security_policy', 'your_function_name', 10, 1 );
Return Value
The filtered value.
Examples
add_filter( 'tincanny_content_security_policy', 'my_custom_csp_policy', 10, 1 );
/**
* Adds custom CSP directives for Wistia and YouTube, and removes 'unsafe-inline'.
*
* This function modifies the default Content-Security-Policy header generated by
* the Uncanny Tincan plugin to enhance security by removing potentially risky
* directives like 'unsafe-inline' and explicitly allowing scripts from Wistia
* and YouTube domains.
*
* @param string $policy The default CSP policy string.
* @return string The modified CSP policy string.
*/
function my_custom_csp_policy( $policy ) {
// Remove 'unsafe-inline' for better security
$policy = str_replace( "'unsafe-inline'", '', $policy );
// Ensure Wistia and YouTube are explicitly allowed (they might already be there, but this is explicit)
// We'll append them in case they are missing or to ensure they are present.
// We also want to ensure that the * for script-src is not overly permissive if we are being more specific.
// For this example, let's assume we want to keep 'unsafe-eval' for development but remove the general '*'
// and be more specific with allowed sources.
// Let's parse the existing policy to modify specific parts.
$policy_parts = explode( ';', $policy );
$new_policy_parts = array();
$script_src_found = false;
foreach ( $policy_parts as $part ) {
$part = trim( $part );
if ( strpos( $part, 'script-src' ) === 0 ) {
$script_src_found = true;
// Split script-src directives and clean them up
$script_directives = explode( ' ', $part );
$cleaned_script_directives = array();
foreach ( $script_directives as $directive ) {
$directive = trim( $directive );
if ( ! empty( $directive ) && $directive !== "'unsafe-inline'" && $directive !== '*' ) {
$cleaned_script_directives[] = $directive;
}
}
// Add our specific allowed sources
$cleaned_script_directives[] = "'unsafe-eval'"; // Keep unsafe-eval if needed
$cleaned_script_directives[] = "wistia.com";
$cleaned_script_directives[] = "youtube.com";
$cleaned_script_directives[] = "blob:"; // Keep blob if needed
// Reconstruct the script-src directive
$new_policy_parts[] = 'script-src ' . implode( ' ', array_unique( $cleaned_script_directives ) );
} else {
$new_policy_parts[] = $part;
}
}
// If script-src directive was not present, add it with our desired settings.
if ( ! $script_src_found ) {
$new_policy_parts[] = "script-src 'unsafe-eval' wistia.com youtube.com blob:";
}
// Join the parts back together, ensuring no empty parts.
$final_policy = implode( '; ', array_filter( $new_policy_parts ) );
// Add a semicolon at the end if the policy is not empty and doesn't already end with one.
if ( ! empty( $final_policy ) && substr( $final_policy, -1 ) !== ';' ) {
$final_policy .= ';';
}
return $final_policy;
}
Placement
This code should be placed in the functions.php file of your active theme, a custom plugin, or using a code snippets plugin.
Source Code
src/uncanny-tincan/classes/Init.php:216
private function set_objects() {
new Server();
new Services();
// For Edge
if ( ! headers_sent() ) {
$header = apply_filters( 'tincanny_content_security_policy', "Content-Security-Policy: script-src * 'self' 'unsafe-inline' 'unsafe-eval' wistia.com youtube.com blob:" );
@header( $header ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
}
if ( is_admin() ) {
// moved to init action for dynamic post types
new AdminWP_UserProfile();
}
}