skip to Main Content

I’ve tried to follow mozilla guide lines for setting up report-uri in CSP-Report-Only mode. My CSP:

function add_csp_header() {
    header("Content-Security-Policy-Report-Only: 
    report-uri ".get_bloginfo('url')."/csp-endpoint;
    script-src 'self'");
    //some more, since only one header is rejected
    }
add_action('send_headers', 'add_csp_header',10);

The csp-endpoint file at the root is:

Report-To: { "group": "csp-endpoint",
      "max_age": 10886400,
      "endpoints": [
        { "url": "http://localhost:8888/wordpress/csp-endpoint" }
      ] }

And finally i have, also in the root directory, csp-report (a simple text file).

The console reports:

...some csp violation... a report is being sent

POST > http://localhost:8888/wordpress/csp-endpoint
Status 200 OK
VersionHTTP/1.1
transmitted 762 B (194 B size)
//many headers and also
special request header
Content-Type: application/csp-report

This is the important part:

Request:
csp-report*** //the data that i want to retrieve

and finally the response:

Response:
Report-To: { "group": "csp-endpoint",
      "max_age": 10886400,
      "endpoints": [
        { "url": "http://localhost:8888/wordpress/csp-endpoint" }
      ] }

I tried to establish a rest_api custom endpoint, listening to posts from the browser, i therefore assume the method has to be ‘GET’:

function test_csp_route() {
   register_rest_route( 'csp/v2', '/csp-endpoint', array(
   'methods'  => 'GET',
   'callback' => 'load_request',
   'permission_callback' => '__return_true',
   ) );
 }
 add_action( 'rest_api_init', 'test_csp_route' );

I added this callback, but i retrieves the response body and i am aiming at the request body that contains the csp-report***:

function load_request() {
  $url = get_bloginfo('url').'/csp-endpoint';
  // Send remote request
  $request = wp_remote_get($url);
  // Retrieve information
  $response_code = wp_remote_retrieve_response_code($request);
  $response_message =   wp_remote_retrieve_response_message($request);
  $response_body = wp_remote_retrieve_body($request);


if (!is_wp_error($request) ) {
   return new WP_REST_Response(
    array(
    'status' => $response_code,
    'response' => $response_message,
    'body_response' => $response_body,
    )
  );
} else {
  return new WP_Error($response_code, $response_message,    $response_body);
 }
}

How can i retrieve the csp-report*** (see above) present in the request body and send the json to a file? Is the detour via rest_api really applying or is there a direct method to retrieve the request body?

This is rather complicated stuff. If you have the time and energy to provide an answer, that would be much appreciated. thanks for the patience.

2

Answers


  1. Chosen as BEST ANSWER

    Simple solution to catch csp resports and save them

    CSP-Header for testing purposes:

    $csp = "script-src 'self'; report-uri ".get_bloginfo('url')."/process-csp-reports.php";
    header("Content-Security-Policy-Report-Only: $csp");
    

    process-csp-reports.php at the root:

    <?php // Note: this script requires PHP ≥ 5.4.
    // Send `204 No Content` status code.
    http_response_code(204);
    // Get the raw POST data.
    $data = file_get_contents('php://input');
    // Only continue if it’s valid JSON that is not just `null`, `0`, `false` or an
    // empty string, i.e. if it could be a CSP violation report.
    if ($data = json_decode($data)) {
        // Prettify the JSON-formatted data.
        $data = json_encode(
            $data,
            JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
            );
            $log_filename = "csp-reports";
            file_put_contents($log_filename, $data. "n", FILE_APPEND);
    }
    ?>
    

    Source This may not be the wordpress way, but it works. The csp-reports are saved to csp-reports (text-file) at the root.


  2. Essentially there should be an endpoint listening to receive CSP error reports.
    In WordPress you can create a REST API endpoint using the rest_api_init hook to handle CSP reports. Docs are here https://developer.wordpress.org/reference/hooks/rest_api_init/.

    The report data that receive via the endpoint can be logged to a file in this case could be the file you created csp-reports

    This requires some minimal coding and understanding of the workings of web applications.

    Hope this will help you!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search