Php

Cross-Origin Request HeadersCORS with PHP headers

19 September 2026 · 10 min read

Cross-Origin Request HeadersCORS with PHP headers

In today’s web development landscape, security is paramount. One critical aspect of web security is handling Cross-Origin Resource Sharing (CORS). CORS is a browser security feature that restricts web pages from making requests to a different domain than the one which served the web page. Understanding and properly configuring Cross-Origin Request Headers (CORS) with PHP headers is vital for any web developer dealing with APIs, single-page applications (SPAs), or any scenario where resources are requested from different origins. Without proper CORS configuration, your web applications may face blocked requests, leading to functionality issues and a poor user experience. This article will delve deep into the intricacies of CORS and how to implement it effectively using PHP headers, ensuring your web applications are both secure and functional.

Understanding Cross-Origin Resource Sharing (CORS)

CORS is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin access to selected resources from a different origin. An origin is defined by the scheme (protocol), host (domain), and port of a URL. For example, https://www.example.com and https://api.example.com are considered different origins. When a web page makes a request to a different origin, it’s considered a cross-origin request. Browsers implement CORS to prevent malicious websites from accessing sensitive data from other websites without permission.

Without CORS, a malicious website could potentially make requests to your bank’s website on your behalf, accessing your account information. CORS acts as a gatekeeper, allowing the server to specify which origins are allowed to access its resources. This is achieved through HTTP headers that are sent back to the browser, instructing it on whether to allow or block the cross-origin request. This fine-grained control is crucial for maintaining the security and integrity of web applications.

The Same-Origin Policy, which precedes CORS, is a fundamental security concept in web browsers. It restricts scripts from one origin from accessing data from a different origin. CORS is essentially a relaxation of the Same-Origin Policy, but it’s a carefully controlled relaxation. The server explicitly allows certain origins to access its resources, rather than completely disabling security measures. According to OWASP, improper CORS configuration is a common vulnerability that can lead to data leakage and other security risks. Therefore, understanding and implementing CORS correctly is essential for modern web development practices. OWASP Top Ten is a great resource for understanding web security risks.

Implementing CORS with PHP Headers

PHP provides a straightforward way to implement CORS by setting specific HTTP headers in your server-side scripts. The most common header used for CORS is Access-Control-Allow-Origin. This header specifies which origins are allowed to access the resource. You can set it to a specific origin (e.g., https://www.example.com) or use a wildcard (``) to allow access from any origin. However, using a wildcard is generally discouraged for security reasons, especially when dealing with sensitive data, as it effectively disables CORS protection. The ideal approach is to explicitly list the origins that are permitted to access your resources.

Here’s a PHP code snippet demonstrating how to set the Access-Control-Allow-Origin header:

<?php header("Access-Control-Allow-Origin: https://www.example.com"); header("Content-Type: application/json"); // Your API logic here echo json_encode($data); ?> 

This code snippet allows requests only from https://www.example.com. The Content-Type header specifies that the response is in JSON format, which is common for APIs. In addition to Access-Control-Allow-Origin, other important CORS headers include Access-Control-Allow-Methods, which specifies the allowed HTTP methods (e.g., GET, POST, PUT, DELETE), and Access-Control-Allow-Headers, which specifies the allowed request headers (e.g., Content-Type, Authorization). These headers provide further control over cross-origin requests, ensuring that only authorized requests are processed. For example, to allow GET and POST requests, and the Content-Type and Authorization headers, you would use the following PHP code:

<?php header("Access-Control-Allow-Origin: https://www.example.com"); header("Access-Control-Allow-Methods: GET, POST"); header("Access-Control-Allow-Headers: Content-Type, Authorization"); header("Content-Type: application/json"); // Your API logic here echo json_encode($data); ?> 

Preflight Requests and CORS

For certain types of cross-origin requests, browsers will send a “preflight” request before the actual request is sent. A preflight request is an HTTP OPTIONS request that asks the server for permission to send the actual request. The server responds with headers indicating whether the request is allowed. Preflight requests are typically triggered when the cross-origin request uses HTTP methods other than GET, HEAD, or POST with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain.

To handle preflight requests in PHP, you need to check the HTTP method and respond accordingly. Here’s an example:

<?php if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { header("Access-Control-Allow-Origin: https://www.example.com"); header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type, Authorization"); header("Access-Control-Max-Age: 86400"); // Cache preflight response for 24 hours http_response_code(200); // OK exit; } header("Access-Control-Allow-Origin: https://www.example.com"); header("Content-Type: application/json"); // Your API logic here echo json_encode($data); ?> 

In this code, the Access-Control-Max-Age header specifies how long the preflight response can be cached by the browser, reducing the number of preflight requests. Setting an appropriate cache duration can improve performance. The featured snippet optimized paragraph is: Proper handling of preflight requests is essential for ensuring that complex cross-origin requests are processed correctly. By checking the HTTP method and responding with the appropriate CORS headers, you can allow the browser to proceed with the actual request. Failing to handle preflight requests can result in CORS errors and blocked requests.

Best Practices for CORS Configuration

Configuring CORS correctly is crucial for the security and functionality of your web applications. Here are some best practices to follow:

  • Avoid using the wildcard () for Access-Control-Allow-Origin: This allows any origin to access your resources, which can be a security risk. Instead, explicitly list the allowed origins.
  • Be specific with Access-Control-Allow-Methods and Access-Control-Allow-Headers: Only allow the HTTP methods and headers that are actually needed for your API.
  • Set an appropriate Access-Control-Max-Age: Caching the preflight response can improve performance, but be mindful of the cache duration.

Furthermore, it’s important to validate the origin of the request on the server-side, even if CORS is enabled in the browser. This provides an additional layer of security against malicious requests. You can check the Origin header in the request and compare it to a list of allowed origins. If the origin is not in the list, reject the request. Additionally, consider using a Content Security Policy (CSP) to further restrict the resources that the browser is allowed to load. Implementing robust security measures is essential for protecting your web applications from various threats.

Here’s an example of how to validate the origin in PHP:

<?php $allowed_origins = [ 'https://www.example.com', 'https://api.example.com' ]; $origin = $_SERVER['HTTP_ORIGIN'] ?? ''; if (in_array($origin, $allowed_origins)) { header("Access-Control-Allow-Origin: " . $origin); header("Content-Type: application/json"); // Your API logic here echo json_encode($data); } else { http_response_code(403); // Forbidden echo json_encode(['error' => 'Origin not allowed']); } ?> 
Infographic here
Troubleshooting Common CORS Issues ----------------------------------

CORS errors can be frustrating to debug. Here are some common issues and how to resolve them:

  1. “No ‘Access-Control-Allow-Origin’ header is present on the requested resource”: This means the server is not sending the Access-Control-Allow-Origin header. Make sure you have correctly configured CORS headers in your PHP scripts.
  2. “Request header field Content-Type is not allowed by Access-Control-Allow-Headers”: This means the server is not allowing the Content-Type header in cross-origin requests. Add Content-Type to the Access-Control-Allow-Headers header.
  3. Preflight request fails: This could be due to various reasons, such as incorrect Access-Control-Allow-Methods or Access-Control-Allow-Headers. Check your server configuration and ensure that it correctly handles preflight requests.

When debugging CORS issues, use your browser’s developer tools to inspect the network requests and responses. The “Console” tab will often display CORS errors, and the “Network” tab will show the HTTP headers exchanged between the browser and the server. Pay close attention to the Origin, Access-Control-Request-Method, and Access-Control-Request-Headers headers in the request, and the Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers headers in the response. These headers provide valuable clues about the cause of the CORS error. You can also use online CORS checkers to validate your CORS configuration. Test CORS is an excellent resource for testing CORS configurations.

  • Double-check your server-side configuration for typos.
  • Ensure the client-side is sending the correct headers.

FAQ About CORS and PHP Headers

What is the purpose of CORS?
CORS is a security mechanism that allows web pages from one origin to access resources from a different origin, while preventing malicious websites from accessing sensitive data without permission.
Why is CORS important?
CORS is crucial for protecting web applications from cross-site scripting (XSS) attacks and other security vulnerabilities.
What are the key CORS headers?
The key CORS headers include `Access-Control-Allow-Origin`, `Access-Control-Allow-Methods`, and `Access-Control-Allow-Headers`.
How do I enable CORS in PHP?
You can enable CORS in PHP by setting the appropriate HTTP headers using the `header()` function.
What is a preflight request?
A preflight request is an HTTP OPTIONS request that is sent by the browser before the actual cross-origin request to determine if the server allows the request.
Configuring **Cross-Origin Request Headers (CORS) with PHP headers** is a critical skill for web developers. By understanding the principles of CORS, implementing the correct headers, and following best practices, you can ensure that your web applications are both secure and functional. Remember to avoid using wildcards, be specific with allowed methods and headers, and validate the origin of the request on the server-side. This detailed guide provides you with the knowledge and tools necessary to effectively manage CORS in your PHP projects. Now, armed with this understanding, go forth and create secure and seamless web experiences! For further reading on web security, check out the [PortSwigger Web Security Academy](https://portswigger.net/web-security). **Question & Answer :** I have a simple PHP script that I am attempting a cross-domain CORS request:
<?php header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Headers: *"); ... 

Yet I still get the error:

Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers

Anything I’m missing?

Handling CORS requests properly is a tad more involved. Here is a function that will respond more fully (and properly).

/** * An example CORS-compliant method. It will allow any GET, POST, or OPTIONS requests from any * origin. * * In a production environment, you probably want to be more restrictive, but this gives you * the general idea of what is involved. For the nitty-gritty low-down, read: * * - https://developer.mozilla.org/en/HTTP_access_control * - https://fetch.spec.whatwg.org/#http-cors-protocol * */ function cors() { // Allow from any origin if (isset($_SERVER['HTTP_ORIGIN'])) { // Decide if the origin in $_SERVER['HTTP_ORIGIN'] is one // you want to allow, and if so: header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}"); header('Access-Control-Allow-Credentials: true'); header('Access-Control-Max-Age: 86400'); // cache for 1 day } // Access-Control headers are received during OPTIONS requests if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) // may also be using PUT, PATCH, HEAD etc header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); exit(0); } echo "You have CORS!"; } 

Security Notes

Check the HTTP_ORIGIN header against a list of approved origins.

If the origin isn’t approved, then you should deny the request.

Please read the spec.

TL;DR

When a browser wants to execute a cross-site request it first confirms that this is okay with a “pre-flight” request to the URL. By allowing CORS you are telling the browser that responses from this URL can be shared with other domains.

CORS does not protect your server. CORS attempts to protect your users by telling browsers what the restrictions should be on sharing responses with other domains. Normally this kind of sharing is utterly forbidden, so CORS is a way to poke a hole in the browser’s normal security policy. These holes should be as small as possible, so always check the HTTP_ORIGIN against some kind of internal list.

There are some dangers here, especially if the data the URL serves up is normally protected. You are effectively allowing browser content that originated on some other server to read (and possibly manipulate) data on your server.

If you are going to use CORS, please read the protocol carefully (it is quite small) and try to understand what you’re doing. A reference URL is given in the code sample for that purpose.

Header security

It has been observed that the HTTP_ORIGIN header is insecure, and that is true. In fact, all HTTP headers are insecure to varying meanings of the term. Unless a header includes a verifiable signature/hmac, or the whole conversation is authenticated via TLS, headers are just “something the browser has told me”.

In this case, the browser is saying “an object from domain X wants to get a response from this URL. Is that okay?” The point of CORS is to be able to answer, “yes I’ll allow that”.