Filter tin-canny-learndash-reporting

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();
		}
	}

Scroll to Top