Is it safe to fix Access-Control-Allow-Origin (CORS origin) errors with a php header directive?

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.

Leave a Comment