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.

up vote 5 down vote accepted

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.

  • 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 Oct 12 '16 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? – Jesús Franco Oct 12 '16 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 Oct 14 '16 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. – Jesús Franco Oct 14 '16 at 18:24

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.

  • 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. – Jesús Franco Oct 13 '16 at 14:23
  • @JesúsFranco, and your point is? – Mark Kaplun Oct 13 '16 at 14:58
  • That the point is answer the question, it is the goal of this site. – Jesús Franco Oct 13 '16 at 16:41
  • @JesúsFranco, I think my rep shows that I know how to answer questions and don't need your advice? – Mark Kaplun Oct 13 '16 at 16:50
  • So, you have an specific idea of how the OP can resolve this problem? – Jesús Franco Oct 14 '16 at 18:26

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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