Home > Net >  Content Security Policy inline scripts has been blocked html form js php
Content Security Policy inline scripts has been blocked html form js php

Time:01-11

I am having trouble implementing CSP with nonce and I'm not understanding what I am doing wrong. I am able to execute local scripts which I'm assuming is allowed the the 'self' parameter. However when I try to submit a contact form which onsubmit execute a return on a js function that sends a post request to a php file to send a email it apparently qualifies as an inline script execution and get blocked by CSP. I have tried to implement nonce in various ways but I'm just not understanding how to enable its execution without using 'unsafe-inline'. Any help would be appreciated. I'm using the following code:

I am specifically getting an error for inline executing from the 'script-src' policy

.htaccess

Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'strict-dynamic' 'nonce-12345678' https://example.com; style-src 'self' 'unsafe-inline'; base-uri 'self'; script-src-elem 'self'; img-src 'self' data:; form-action 'self'; report-to csp-endpoints"

contact.html

<form id="contact_form" onsubmit="return submitForm()"  nonce="12345678>
<script src="/js/contact.js" nonce="12345678"></script>

contact.js

function submitForm(e) { 
    
    // do stuff
    
    const request = new XMLHttpRequest();
    request.open("POST", "php/email.php", true);
    request.setRequestHeader("Content-type", "application/json");
    request.onload = function () {
        if (request.status >= 200 && request.status < 400) {
            const resp = request.responseText;
            const data = JSON.parse(resp);
            alert(`Thank you ${data.name} for your message. We will get back to you at ${data.email} as soon as possible.`);
        } else {
            alert("Something went wrong. Please try again later.");
            console.log(request.responseText);
        }
    };
    request.onerror = function () {
        alert("An error occured. Please try again later.");
    };

    const data = JSON.stringify({
        name,
        email,
        goal,
        itsatrap,
        requirements,
        integrations,
        features,
        guidelines
    });
    request.send(data);
    return false;
  }
}

email.php

<?php
   // do stuff
   header('Content-Type: application/json');
   if (mail($recipient, $subject, $email_content, $email_headers)) {
     http_response_code(200);
     $json = array("success" => true, "message" => "Thank You! Your message has been sent.", "name" => $name, "email" => $email);
     echo json_encode($json, JSON_PRETTY_PRINT);
     exit;
   } else {
     http_response_code(500);
     $json = array("success" => false, "message" => "Oops! Something went wrong and we couldn't send your message.", "reason" => error_get_last());
     echo json_encode($json, JSON_PRETTY_PRINT);
     exit;
   }

CodePudding user response:

Thank you @Sebastian Simon. I am now able to use 'strict-dynamic' I realize now why I was getting the errors. I made the following changes to avoid inline execution.

.htaccess

Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'strict-dynamic' https://example.com; style-src 'self' 'unsafe-inline'; base-uri 'self'; script-src-elem 'self'; img-src 'self' data:; form-action 'self'; report-to csp-endpoints"

contact..html

<form id="contact_form" >
<script src="/js/contact.js"></script>

contact.js

async function submitForm() {
// do stuff 

  const response = await fetch("php/email.php", {
          method: "POST",
          headers: {
              "Content-Type": "application/json"
          },
          body: JSON.stringify(data)
      });
  if (response.ok) {
      const data = await response.json();
      alert(`Thank you ${data.name} for your message. We will get back to you at ${data.email} as soon as possible.`);
      return true;
  } else {
      alert("Something went wrong. Please try again later.");
      console.log(response);
      return false;
  }
}

document.getElementById('contact_form').addEventListener('submit', (e) => {
  e.preventDefault();
  const submitted = submitForm();
  if (submitted) {
      document.getElementById('contact_form').reset();
  }
});
  • Related