5

I am trying to show a Formidable Pro Form from a WordPress site to the other. I followed the developer's API and the REST API, but faced a CORS problem.

Then I found a suggestion on a forum thread suggesting to add this line of code the functions.php of the site where the original form is:

header("Access-Control-Allow-Origin: *");

I tried this code and it worked perfectly fine.

My question is: does this code opens security risks or other vulnerabilities?

The solution seems too simple for a problem that faces many people.

Your input is highly appreciated.

2
  • @markratledge. Thanks for editing the question. It now makes more sense and certainly helped me to write better questions.
    – Atef Wagih
    Commented Oct 12, 2016 at 4:29
  • I wonder if this answer helps: wordpress.stackexchange.com/a/226494/51462
    – Ryan
    Commented Aug 13, 2017 at 2:02

2 Answers 2

6

Yes, you open your site to being requested via AJAX to any other script in the whole web.

It would be better if you limit the origin to one specific remote domain from which you are consuming the API, like this example:

header("Access-Control-Allow-Origin: http://mozilla.com");

However as the mozilla documentation states, a client can fork the origin, nevertheless limiting the sites a casual user can connect is a deterrent for some attacks.

Even better, you can limit your request to only the methods you really need to allow, the gist is this snippet, and it works for several domains, if you have the $_SERVER['HTTP_ORIGIN'] variable populated:

add_action('rest_api_init', function() {

     /* unhook default function */
     remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');

     /* then add your own filter */
     add_filter('rest_pre_serve_request', function( $value ) {
          $origin = get_http_origin();
          $my_sites = array( 'http://site1.org/', 'http://site2.net', );
          if ( in_array( $origin, $my_sites ) ) {
              header( 'Access-Control-Allow-Origin: ' . esc_url_raw( $origin ) );
          } else {
              header( 'Access-Control-Allow-Origin: ' . esc_url_raw( site_url() ) );
          }
          header( 'Access-Control-Allow-Methods: GET' );

          return $value;
     });
}, 15);

As you can see, this snippet uses the function get_http_origin provided by WordPress, but it will return null or empty, if the key HTTP_ORIGIN is not populated in the $_SERVER array, therefore it's not available to the PHP script, maybe because it is blocked by the cloudflare proxy you are using. I'd check quickly, with a script with the <?php phpinfo(); ?>, if you have this variable populated.

Maybe the origin site it's populated in another header by cloudflare, and you could use it in a function hooked to the http_origin filter. If you are lost to this point, edit your original question posting the contents of the _SERVER variable, except your filesystem paths or passwords.

I'd be glad to help.

6
  • Thanks. The first solution worked for me. But since I have 4 sites that I want to allow them to access the main site, do I repeat the line 4 times and change the site url, or it can be combined into a single command? thanks
    – Atef Wagih
    Commented Oct 12, 2016 at 8:14
  • Of course you can, I use to allow just a to a few sites access to the API, I've updated my answer with the check for this, if it works, would you mind to upvote the answer? Commented Oct 12, 2016 at 17:25
  • first solution 2orked for 1 domain only. if i repeated the line, it doesn't work. I tried the method in this thread link, but doesn't work too. When I apply solution 2, this is what I get: XMLHttpRequest cannot load https://coptic-treasures.com/wp-json/frm/v2/forms/6?return=html. The 'Access-Control-Allow-Origin' header has a value 'https://coptic-treasures.com' that is not equal to the supplied origin. Origin 'https://audio.coptic-treasures.com' is therefore not allowed access.
    – Atef Wagih
    Commented Oct 14, 2016 at 8:39
  • You can't use the Allow Origin header most than once. I've updated my answer with further instructions to help you debug the issue because always returning the same site shouldn't happen and it should recognize the list of your domains you pass to the array. Please update your question with the data of the $_SERVER variable, returned by phpinfo(), excluding passwords and filesystem paths. I'd be glad to help. Commented Oct 14, 2016 at 18:24
  • 1
    It's taken me about 2 days to find out how to remove CORS access from the WP-JSON API. Thanks for this. Remove the rest_send_cors_headers function call!
    – dewd
    Commented Nov 22, 2019 at 17:19
1

background - browsers are restricting remote access from scripts to only the site from which it was loaded. If this kind of check wasn't done, while visiting a site X it would have been possible for it to submit data to your gmail account (if you are logged in) without even needing to guess your user and password, because the browser would have sent the proper authentication cookies to gmail.

The CORS "protocol" is there to help you relax this restriction when needed.

So the question that you should ask yourself, is do I need it? On the one hand, I can't see why would 99% of wordpress sites need it, on the other hand, wordpress cookies are relatively short lived and 99% of wordpress sites are not going to be a target to such a random attack.

I would say, that since the rest API is a mutating one, and have access to private information, you should not use rest api in your solution if you need to enable cors, you better write your own "read only" API.

16
  • The OP is not talking about the 99% of WP sites out there, but their own sites, and according to the question its needed to make available resources from other site. Commented Oct 13, 2016 at 14:23
  • @JesúsFranco, and your point is? Commented Oct 13, 2016 at 14:58
  • 1
    That the point is answer the question, it is the goal of this site. Commented Oct 13, 2016 at 16:41
  • @JesúsFranco, I think my rep shows that I know how to answer questions and don't need your advice? Commented Oct 13, 2016 at 16:50
  • So, you have an specific idea of how the OP can resolve this problem? Commented Oct 14, 2016 at 18:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.