Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. Web Development
  3. JavaScript
  4. Javascript CSP and CORS problem? How can I send Cookies with AJAX in CORS?

Javascript CSP and CORS problem? How can I send Cookies with AJAX in CORS?

Scheduled Pinned Locked Moved JavaScript
helpquestionjavascriptphpsysadmin
7 Posts 2 Posters 15 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Member_15100276
    wrote on last edited by
    #1

    Hi all, first post here... I am playing with Content Security Policies and some other stuff trying to figure out how to add a bit if security for users. Ive created about a dozen pages, all nicely and neatly working together so far. All garbage test stuff, but its not working as I have hoped. One of the functions I need to work is to use AJAX to load data from a PHP script including a cookie with an HttpOnly flag set, so Javascript cant read it. Trouble is that no matter what I try short of turning off ALL security (which aint gonna happen), I can not get my AJAX call to not violate Cross Origin Request Policy. What is throwing me off is that I dont believe it should be Cross Origin at all! I know one way to do it is to process the "Origin" header when sending the request but its never actually sent! Typically it is not, except for when "withCredentials" flag is also set, which it is. If thats what I gotta do, fine, but I cant get it to work. Better solution is make sure it is NOT treated as Cross Origin, and I believe that would also resolve it. Both my solutions are evading me! The script is in "iframe.php" So here is my test page on my test server: https://www.webucate.me/cors\_csp/ Full source is here: https://www.webucate.me/cors\_csp/ajax.php This is where it fails on me. This AJAX call wont send the cookie. I am not sure if this is where I need to fix it however...

    const loadLocalXMLCookie = function(){
    // This isnt working, I get a CORS Violation
    let url = "jsondata.php";
    var xhttp = new XMLHttpRequest();
    // Third Argument of "true" allows XLMHttpRequest2 which allows sending Cookies via AJAX
    xhttp.open("GET", url, true);
    // withCredentials should send Cookies via the request, and should not be needed on SameSite
    xhttp.withCredentials = true;
    xhttp.onreadystatechange = function() {
    console.log(this);
    if (this.readyState == 4 && this.status == 200){
    outputElement.innerHTML = this.responseText;
    }
    };
    xhttp.onerror = function(){ outputElement.innerHTML = "XML Cookie Error " + url; };
    xhttp.send();
    }

    What can I do so that this XMLHttpRequest object is not treating the request as Cross Origin, thus, use PHP to read and set the cookie? If I have to use Cross Origin, what am I missing in my setup?

    Richard DeemingR 1 Reply Last reply
    0
    • M Member_15100276

      Hi all, first post here... I am playing with Content Security Policies and some other stuff trying to figure out how to add a bit if security for users. Ive created about a dozen pages, all nicely and neatly working together so far. All garbage test stuff, but its not working as I have hoped. One of the functions I need to work is to use AJAX to load data from a PHP script including a cookie with an HttpOnly flag set, so Javascript cant read it. Trouble is that no matter what I try short of turning off ALL security (which aint gonna happen), I can not get my AJAX call to not violate Cross Origin Request Policy. What is throwing me off is that I dont believe it should be Cross Origin at all! I know one way to do it is to process the "Origin" header when sending the request but its never actually sent! Typically it is not, except for when "withCredentials" flag is also set, which it is. If thats what I gotta do, fine, but I cant get it to work. Better solution is make sure it is NOT treated as Cross Origin, and I believe that would also resolve it. Both my solutions are evading me! The script is in "iframe.php" So here is my test page on my test server: https://www.webucate.me/cors\_csp/ Full source is here: https://www.webucate.me/cors\_csp/ajax.php This is where it fails on me. This AJAX call wont send the cookie. I am not sure if this is where I need to fix it however...

      const loadLocalXMLCookie = function(){
      // This isnt working, I get a CORS Violation
      let url = "jsondata.php";
      var xhttp = new XMLHttpRequest();
      // Third Argument of "true" allows XLMHttpRequest2 which allows sending Cookies via AJAX
      xhttp.open("GET", url, true);
      // withCredentials should send Cookies via the request, and should not be needed on SameSite
      xhttp.withCredentials = true;
      xhttp.onreadystatechange = function() {
      console.log(this);
      if (this.readyState == 4 && this.status == 200){
      outputElement.innerHTML = this.responseText;
      }
      };
      xhttp.onerror = function(){ outputElement.innerHTML = "XML Cookie Error " + url; };
      xhttp.send();
      }

      What can I do so that this XMLHttpRequest object is not treating the request as Cross Origin, thus, use PHP to read and set the cookie? If I have to use Cross Origin, what am I missing in my setup?

      Richard DeemingR Offline
      Richard DeemingR Offline
      Richard Deeming
      wrote on last edited by
      #2

      Your comment for the xhttp.open line is inaccurate and misleading. The third parameter has nothing to do with cookies; it simply controls whether the request is asynchronous or not: XMLHttpRequest.open() - Web APIs | MDN[^] The withCredentials property has no effect on same-site requests: XMLHttpRequest.withCredentials - Web APIs | MDN[^] You're not actually logging any details of the error. Have you checked the network request to see what the actual error is, or are you just assuming it's a CORS issue? I'd recommend switching to the Fetch API instead: Fetch API - Web APIs | MDN[^] Using Fetch - Web APIs | MDN[^] It's supported pretty much everywhere except Internet Explorer. If you need to support IE, there's a polyfill available[^]. In modern browsers, cookies for same-origin requests should be included by default. If you're using an older browser (prior to April 2018), you may need to supply the credentials:'same-origin' init option[^].

      const loadLocalXMLCookie = async function(){
      const url = "jsondata.php";

      const response = await fetch(url, {
          method: 'GET',
          cache: 'no-cache',
          credentials: 'same-origin'
      });
      
      if (!response.ok) {
          const errorMessage = await response.text();
          console.error(
      

      "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

      M 1 Reply Last reply
      0
      • Richard DeemingR Richard Deeming

        Your comment for the xhttp.open line is inaccurate and misleading. The third parameter has nothing to do with cookies; it simply controls whether the request is asynchronous or not: XMLHttpRequest.open() - Web APIs | MDN[^] The withCredentials property has no effect on same-site requests: XMLHttpRequest.withCredentials - Web APIs | MDN[^] You're not actually logging any details of the error. Have you checked the network request to see what the actual error is, or are you just assuming it's a CORS issue? I'd recommend switching to the Fetch API instead: Fetch API - Web APIs | MDN[^] Using Fetch - Web APIs | MDN[^] It's supported pretty much everywhere except Internet Explorer. If you need to support IE, there's a polyfill available[^]. In modern browsers, cookies for same-origin requests should be included by default. If you're using an older browser (prior to April 2018), you may need to supply the credentials:'same-origin' init option[^].

        const loadLocalXMLCookie = async function(){
        const url = "jsondata.php";

        const response = await fetch(url, {
            method: 'GET',
            cache: 'no-cache',
            credentials: 'same-origin'
        });
        
        if (!response.ok) {
            const errorMessage = await response.text();
            console.error(
        
        M Offline
        M Offline
        Member_15100276
        wrote on last edited by
        #3

        This is the error message I get:

        Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.webucate.me/cors\_csp/jsondata.php. (Reason: CORS header ‘Access-Control-Allow-Origin’ does not match ‘https://www.webucate.me’).

        I looked at the Origin header, its never sent. So much for Stack Overflow answers on other questions when youre tired, tend to miss stuff, like misleading comments. I will take a look further into fetch and maybe the polyfill, but I dont really have any intention of trying to support IE. Thank you.

        Richard DeemingR 1 Reply Last reply
        0
        • M Member_15100276

          This is the error message I get:

          Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.webucate.me/cors\_csp/jsondata.php. (Reason: CORS header ‘Access-Control-Allow-Origin’ does not match ‘https://www.webucate.me’).

          I looked at the Origin header, its never sent. So much for Stack Overflow answers on other questions when youre tired, tend to miss stuff, like misleading comments. I will take a look further into fetch and maybe the polyfill, but I dont really have any intention of trying to support IE. Thank you.

          Richard DeemingR Offline
          Richard DeemingR Offline
          Richard Deeming
          wrote on last edited by
          #4

          Well, based on the information provided, there's no way you should be violating the same-origin policy. The protocol, domain, and port all match; the only difference is the path. Same-origin policy - Web security | MDN[^] Have you tried a different browser, in case there's a problem with the one you're using or one of its plugins?


          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

          "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

          M 1 Reply Last reply
          0
          • Richard DeemingR Richard Deeming

            Well, based on the information provided, there's no way you should be violating the same-origin policy. The protocol, domain, and port all match; the only difference is the path. Same-origin policy - Web security | MDN[^] Have you tried a different browser, in case there's a problem with the one you're using or one of its plugins?


            "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

            M Offline
            M Offline
            Member_15100276
            wrote on last edited by
            #5

            Agreed, I do not believe it should be a CORS request... with one exception to that thought... But yes, different browsers and computers. I even tried accessing it with a Super Nintendo from WAY back in the day and that turned out exactly as you'd expect! I went so far as to try VM Kubuntu also running firefox and same thing. So this is probably affecting it, but the iframe is in Sandbox mode, with scripts allowed, so I think its *possible* I may need to use CORS anyway due to the IFrame being Sandboxed. CSP appears to work perfectly as expected. I am trying something from an inverse approach. Put it on "full lockdown", then open up for things that are needed. And I cant quite figure out how to "open it back up" without completely unlocking it. My concept is to do something "super" stupid as far as security pros will say. Users get to upload their own scripts to interact with a Canvas Object that other users can view and interact with. Everything else needs to be in full on lockdown mode. So I know I am asking for things that conflict. Most things work so far. Browsers shouldnt have access to Http Only cookies, this particular IFrame should. This is the only thing I want to work differently that doesnt work. CSP did a great job of only allowing open data connections to scripts and sources specified in the CSP headers from PHP / Apache. Perhaps a safer idea would be to figure out how to make this a CORS request and do that properly? --- Edit: Yay! I have a NEW error! It is different than the OLD error so the fact that I have a NEW error is wonderful news to me! Firefox Error: (Ambiguous) Error: TypeError: NetworkError when attempting to fetch resource. Chrome Error: POST https://www.webucate.me/cors\_csp/jsondata.php net::ERR_BLOCKED_BY_RESPONSE fetchData @ iframe.php:76 So now it is between my fetch call and probably PHP headers:

            const fetchData = async function(data = {}) {
            let url = 'https://www.webucate.me:443/cors\_csp/jsondata.php';
            const response = await fetch(url, {
            method: 'POST',
            mode: 'no-cors',
            cache: 'no-cache',
            credentials: 'include',
            headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            },
            redirect: 'follow',
            referrerPolicy: 'same-origin',
            body: JSON.stringify(data)
            })
            .then(response => response.json())
            .then(result => {
            console.log('Success:', result);
            })
            .catch(error => {
            console.warn('Error:', error);
            return;
            });
            return response

            Richard DeemingR 1 Reply Last reply
            0
            • M Member_15100276

              Agreed, I do not believe it should be a CORS request... with one exception to that thought... But yes, different browsers and computers. I even tried accessing it with a Super Nintendo from WAY back in the day and that turned out exactly as you'd expect! I went so far as to try VM Kubuntu also running firefox and same thing. So this is probably affecting it, but the iframe is in Sandbox mode, with scripts allowed, so I think its *possible* I may need to use CORS anyway due to the IFrame being Sandboxed. CSP appears to work perfectly as expected. I am trying something from an inverse approach. Put it on "full lockdown", then open up for things that are needed. And I cant quite figure out how to "open it back up" without completely unlocking it. My concept is to do something "super" stupid as far as security pros will say. Users get to upload their own scripts to interact with a Canvas Object that other users can view and interact with. Everything else needs to be in full on lockdown mode. So I know I am asking for things that conflict. Most things work so far. Browsers shouldnt have access to Http Only cookies, this particular IFrame should. This is the only thing I want to work differently that doesnt work. CSP did a great job of only allowing open data connections to scripts and sources specified in the CSP headers from PHP / Apache. Perhaps a safer idea would be to figure out how to make this a CORS request and do that properly? --- Edit: Yay! I have a NEW error! It is different than the OLD error so the fact that I have a NEW error is wonderful news to me! Firefox Error: (Ambiguous) Error: TypeError: NetworkError when attempting to fetch resource. Chrome Error: POST https://www.webucate.me/cors\_csp/jsondata.php net::ERR_BLOCKED_BY_RESPONSE fetchData @ iframe.php:76 So now it is between my fetch call and probably PHP headers:

              const fetchData = async function(data = {}) {
              let url = 'https://www.webucate.me:443/cors\_csp/jsondata.php';
              const response = await fetch(url, {
              method: 'POST',
              mode: 'no-cors',
              cache: 'no-cache',
              credentials: 'include',
              headers: {
              'Content-Type': 'application/x-www-form-urlencoded',
              },
              redirect: 'follow',
              referrerPolicy: 'same-origin',
              body: JSON.stringify(data)
              })
              .then(response => response.json())
              .then(result => {
              console.log('Success:', result);
              })
              .catch(error => {
              console.warn('Error:', error);
              return;
              });
              return response

              Richard DeemingR Offline
              Richard DeemingR Offline
              Richard Deeming
              wrote on last edited by
              #6

              I assume you've tried adding allow-same-origin to the sandbox attribute? <iframe>: The Inline Frame element - HTML: HyperText Markup Language | MDN[^] Without it, the content is "treated as being from a special origin that always fails the same-origin policy". The ERR_BLOCKED_BY_RESPONSE seems to be related to the X-Frame-Options header. The value needs to be SAMEORIGIN, not same-origin: X-Frame-Options - HTTP | MDN[^]


              "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

              "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

              M 1 Reply Last reply
              0
              • Richard DeemingR Richard Deeming

                I assume you've tried adding allow-same-origin to the sandbox attribute? <iframe>: The Inline Frame element - HTML: HyperText Markup Language | MDN[^] Without it, the content is "treated as being from a special origin that always fails the same-origin policy". The ERR_BLOCKED_BY_RESPONSE seems to be related to the X-Frame-Options header. The value needs to be SAMEORIGIN, not same-origin: X-Frame-Options - HTTP | MDN[^]


                "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                M Offline
                M Offline
                Member_15100276
                wrote on last edited by
                #7

                I looked at that allow-same-origin iframe attribute and I believe it wont work for what I have it intended for, as the IFrame would be an include on other peoples sites, not my own, I believe it would not be appropriate for that header. ... (?) Well, I got it "sort of" talking. Im now getting back Opaque responses but no data! Im so confuzzled, and kind of frustrated. I feel like all I am doing is throwing headers at it and hoping something sticks and each header fixes something some other header does! Hour of reading, 2 minutes of code, go back to reading, and very little success... I did take your advice and used fetch instead of XMLHttpRequest, which seems more flexibler! Is that a word? What do I need to do for me to get data back from the cookie in php and not just an Opaque response?

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups