What Is X-Permitted-Cross-Domain-Policies and Why Should You Care?
When users visit your website, they trust you with their data. This trust extends beyond just the information they deliberately provide--it includes the implicit assumption that their interaction with your site won't expose them to security risks from third parties. The X-Permitted-Cross-Domain-Policies header is one of several HTTP security headers that help maintain this trust by controlling how external resources can interact with your site's content.
The X-Permitted-Cross-Domain-Policies header is an HTTP response header that defines a meta-policy controlling whether site resources can be accessed cross-origin by documents running in web clients like Adobe Acrobat or Microsoft Silverlight. Originally developed to address security concerns with Adobe Flash and PDF documents, this header has evolved to serve as a defense-in-depth measure against various cross-domain attack vectors.
The User Security Perspective
From a user-centered design perspective, the X-Permitted-Cross-Domain-Policies header protects users from several types of attacks:
- Prevents Unauthorized Data Access - By restricting cross-domain access, you prevent malicious third-party sites from reading user data that might be embedded in your pages. This is particularly important for applications that handle sensitive information, from e-commerce transactions to personal dashboards.
- Mitigates Cross-Site Scripting Risks - While not a direct replacement for Content Security Policy, properly configured cross-domain policies add a layer of defense against certain cross-site scripting attacks by limiting how external resources can interact with your content.
- Reduces Data Leakage - The header helps ensure that only authorized resources can interact with your site, protecting sensitive data from being exfiltrated through malicious embedded content.
- Enhances Browser Security - By using this header, you reduce the chances of your website being used as a vector for loading external resources that could compromise user browser security.
The Modern Relevance
While Adobe Flash is largely obsolete, PDF documents and some enterprise applications still use cross-domain mechanisms. Security testing tools continue to check for this header as part of comprehensive security assessments. The header serves as a defense-in-depth measure--even if your primary security comes from other headers like Content Security Policy, having proper cross-domain policies adds an extra layer of protection. As the OWASP Secure Headers Project notes, the header is categorized as "Active," meaning it's still recommended for production use.
Understanding the Header Values and Their Security Implications
The X-Permitted-Cross-Domain-Policies header accepts several values, each with different security implications. Understanding these values is crucial for making the right configuration decisions.
None
Setting the header to none is the most secure option. When you set X-Permitted-Cross-Domain-Policies: none, you're telling the browser that no cross-domain policy files are allowed anywhere on your server, including in the master policy file. This effectively blocks any cross-domain access to your site's resources through these legacy mechanisms.
When to use this value:
- For the vast majority of modern websites
- When you don't have specific requirements for cross-domain Flash or PDF access
- When security is a priority (which should be nearly always)
- As the default configuration for any new project
According to OWASP recommendations, none is the appropriate value for most web applications. This setting eliminates any possibility of cross-domain policy-based attacks while having minimal impact on modern web applications that don't rely on these legacy mechanisms.
Master-Only
The master-only value allows cross-domain access but only through the master policy file defined on the same domain. This is more restrictive than all but less restrictive than none. With this setting, only a crossdomain.xml file in the root of your domain can grant cross-domain access.
When to use this value:
- When you need to support cross-domain access for legacy applications
- When you want granular control through a central policy file
- When you need to explicitly authorize specific domains while blocking ad-hoc policy files
This option provides a middle ground--you can still use cross-domain policies if needed, but you maintain control through a single, auditable policy file rather than allowing policy files in arbitrary directories.
By-Content-Type
The by-content-type value (HTTP/HTTPS only) allows cross-domain access only for policy files served with the Content-Type header value of text/x-cross-domain-policy. This provides some protection against policy files being accidentally served through misconfiguration.
When to use this value:
- When you have specific cross-domain policy requirements
- When you can ensure proper Content-Type headers for policy files
- In controlled environments where you need fine-grained control
This option is less commonly used but can be appropriate in specific enterprise or legacy application scenarios.
By-FTP-Filename
The by-ftp-filename value (FTP only) allows cross-domain access only for policy files whose file names are crossdomain.xml--essentially URLs ending in /crossdomain.xml. This option is specific to FTP servers and not applicable for standard web hosting.
When to use this value:
- Only when serving content via FTP servers
- For legacy FTP-based content delivery systems
Most modern web applications will never need to use this value.
All
The all value allows all policy files on the target domain to grant cross-domain access. This is the least restrictive option and should be avoided in most circumstances.
When to use this value:
- Almost never in production environments
- Only in very specific legacy scenarios where you cannot control the policy file locations
- When explicitly required by a third-party service that needs to load content from your domain
As OWASP notes, permissive cross-domain policies have historically been a significant source of security vulnerabilities. Using all essentially means any subdirectory on your domain could have a policy file granting broad cross-domain access, which is a security risk you should avoid.
None-This-Response
The none-this-response value is unique to the HTTP header and indicates that the current document should not be used as a policy file despite other headers or its content. This value doesn't have a direct equivalent in crossdomain.xml files.
When to use this value:
- When you want to explicitly override any inherited policy
- In specific scenarios where you need to ensure a response is never interpreted as a policy file
This is a specialized option that most developers won't need to use regularly.
How Cross-Domain Policies Work in Practice
The Cross-Domain Policy File
A cross-domain policy file is an XML document that grants a web client, such as Adobe Flash Player or Adobe Acrobat, permission to handle data across domains. When a client requests content hosted on a particular source domain and that content makes requests directed towards a domain other than its own, the remote domain needs to host a cross-domain policy file that grants access to the source domain.
The master cross-domain policy file is typically named crossdomain.xml and resides in the root directory of a domain--for example, http://example.com/crossdomain.xml. This master file defines the meta-policy for the entire site using the permitted-cross-domain-policies attribute of the <site-control> tag.
Here's an example of a basic crossdomain.xml file that doesn't permit any cross-domain access:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="none"/>
</cross-domain-policy>
This XML structure is the foundation of the cross-domain policy system. The <site-control> element with permitted-cross-domain-policies="none" indicates that no policy files are allowed anywhere on this domain.
The HTTP Header Alternative
The X-Permitted-Cross-Domain-Policies HTTP header can specify a meta-policy for the HTTP response it's included in, or override a meta-policy defined in the master cross-domain policy file, if present. It takes the same values as the file's permitted-cross-domain-policies attribute, with the addition of none-this-response.
There are several reasons you might use the HTTP header instead of or in addition to an XML file:
- No Root Access: If you don't have access to write files to the root directory of your domain (common in shared hosting or certain CMS configurations), the HTTP header provides an alternative way to set the policy.
- Per-Response Control: The header allows you to set policies on specific responses rather than globally for the entire domain. This can be useful for APIs or specific resources that need different policies.
- Defense in Depth: Using both the header and the XML file provides layered protection. If one is compromised or misconfigured, the other still provides protection.
- Explicit Override: The header can override the XML file's policy, giving you more granular control over how different resources are accessed.
Relationship with Modern Security Headers
While the X-Permitted-Cross-Domain-Policies header addresses a specific type of cross-domain access, it's important to understand how it relates to modern security mechanisms:
- Content Security Policy (CSP): CSP is the modern successor to many of the security concerns addressed by cross-domain policies. CSP provides more comprehensive control over resource loading and is the recommended approach for most resource access controls. However, X-Permitted-Cross-Domain-Policies still has value as a defense-in-depth measure. Learn more about implementing CSP in our Content Security Policy guide.
- Cross-Origin Resource Sharing (CORS): CORS is the modern mechanism for controlling cross-origin requests in browsers. Unlike the legacy cross-domain policy system, CORS is actively maintained and widely supported. If you're building new web applications, CORS is likely the mechanism you should be using for cross-origin access control.
- Cross-Origin Resource Policy (CORP): This header allows you to define which origins can include your resources, providing another layer of cross-origin protection.
The key insight is that X-Permitted-Cross-Domain-Policies is part of a layered security approach. While it may not be as critical as CSP or CORS for modern applications, it still plays a role in comprehensive web security.
Apache Configuration
For Apache servers, you can set the X-Permitted-Cross-Domain-Policies header using either your server configuration file or an .htaccess file. The most common approach for shared hosting or simple configurations is using .htaccess:
# In your .htaccess file
Header set X-Permitted-Cross-Domain-Policies "none"
For more controlled environments, you might add this to your virtual host configuration:
# In your virtual host configuration
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
# Set X-Permitted-Cross-Domain-Policies header
Header always set X-Permitted-Cross-Domain-Policies "none"
</VirtualHost>
When using Apache, ensure that the mod_headers module is enabled. You can verify this with:
a2enmod headers
systemctl restart apache2
For sites that specifically need cross-domain policy support, you might use:
# For sites that need cross-domain policies
Header always set X-Permitted-Cross-Domain-Policies "master-only"
Best Practices for X-Permitted-Cross-Domain-Policies
Default to None
For the vast majority of websites, the recommended configuration is X-Permitted-Cross-Domain-Policies: none. This should be your default starting point unless you have a specific, documented requirement for cross-domain access. Starting with the most restrictive setting and only relaxing it when necessary follows the principle of least privilege and reduces your attack surface.
Document Your Decisions
Any deviation from the default none value should be documented. Document:
- Why the cross-domain access is needed - Business or technical justification
- Which domains are being granted access - Specific, authorized domains only
- When the policy was implemented and by whom - Accountability for security decisions
- When the policy should be reviewed - Regular security reassessment schedule
This documentation is essential for security audits, incident response, and maintenance. Without it, future team members may not understand why a policy exists or whether it's still needed.
Use with Other Security Headers
The X-Permitted-Cross-Domain-Policies header is most effective when used as part of a comprehensive security header strategy:
- Content-Security-Policy - Provides comprehensive control over resource loading
- X-Frame-Options - Prevents clickjacking by controlling iframe embedding
- X-Content-Type-Options - Prevents MIME type sniffing
- Referrer-Policy - Controls referrer information sent with requests
- Permissions-Policy - Controls browser features and APIs
These headers work together to provide defense in depth. Even if one header is misconfigured or bypassed, others may still provide protection.
Regular Security Audits
Security headers should be reviewed regularly as part of your security audit process:
- Include X-Permitted-Cross-Domain-Policies in your security header scanning
- Review the value during quarterly security assessments
- Verify that any cross-domain policies are still necessary when you do change management
- Test after server migrations or configuration changes
Consider Edge Cases
Certain scenarios require additional consideration:
- Third-Party Embeds: If you embed content from third parties that may use cross-domain mechanisms, ensure your policy doesn't inadvertently allow excessive access.
- CDN Configurations: If you use a CDN, ensure the header is properly configured at the CDN level, not just at your origin server.
- API Endpoints: Consider whether different policies are needed for your main site versus API endpoints. APIs often have different security requirements.
- Error Pages: Ensure your security headers, including X-Permitted-Cross-Domain-Policies, are set on error pages (404, 500, etc.) as well as normal content.
The User-Centered Case for Cross-Domain Security
Protecting User Data
Users share data with websites based on the assumption that this data will be protected. Cross-domain vulnerabilities can allow unauthorized parties to access this data, potentially leading to privacy violations, identity theft, or financial loss. By properly configuring X-Permitted-Cross-Domain-Policies and other security headers, you help ensure that user data remains protected.
Maintaining Trust
Security incidents can severely damage user trust and brand reputation. Even a perceived security issue can cause users to lose confidence in your platform. When users see that your site is secure--through indicators like security headers, HTTPS, and privacy practices--they're more likely to engage confidently with your product.
Contributing to Web Safety
Proper cross-domain security doesn't just protect your users--it contributes to the overall safety of the web ecosystem. Vulnerable websites can be used as attack vectors against other sites or against the users who visit them. By implementing proper security headers, you're doing your part to maintain a safer web for everyone.
The UX of Security Headers
Security and user experience are often discussed as competing concerns, but properly implemented security enhances UX rather than detracts from it. Users shouldn't have to worry about security when using your application. By handling security concerns server-side through headers like X-Permitted-Cross-Domain-Policies, you provide seamless protection without imposing additional friction on users. When your web development services include proper security headers, you're building trust with every visitor.
Frequently Asked Questions
Is X-Permitted-Cross-Domain-Policies still relevant since Flash is deprecated?
Yes. While Flash is obsolete, the header remains relevant for defense-in-depth, PDF security, and compliance with security audits. Security scanners still check for this header, and OWASP categorizes it as an 'Active' security header that should be implemented in production environments.
What's the difference between X-Permitted-Cross-Domain-Policies and CORS?
X-Permitted-Cross-Domain-Policies addresses legacy mechanisms (Flash, PDF, Silverlight). CORS is the modern browser mechanism for cross-origin requests. They address different security concerns and should be used together as part of layered security.
Should I use 'none' or 'master-only' for my website?
For most websites, 'none' is recommended. Use 'master-only' only if you have specific legacy requirements that need a crossdomain.xml policy file. Default to 'none' and only relax if you have documented requirements.
How do I test if my X-Permitted-Cross-Domain-Policies header is set correctly?
Use curl (curl -I https://yourdomain.com), browser DevTools Network tab, or online security header scanners like SecurityHeader.io or observatory.mozilla.org. Include verification in your deployment checklist.
Does setting this header affect my site's functionality?
For most modern websites, setting 'none' has no impact on functionality since Flash and PDF cross-domain mechanisms are rarely used. Test your site after implementation to verify all features work as expected.
Sources
-
MDN Web Docs - X-Permitted-Cross-Domain-Policies - Primary technical reference for header specifications, directives, and examples.
-
OWASP Secure Headers Project - Security best practices and recommendations from the leading web security organization.
-
InspiredMonks - X Permitted Cross Domain Policies Guide - Comprehensive practical implementation guide with server configuration examples.
-
Adobe Cross Domain Policy File Specification - Original specification from Adobe that defined the cross-domain policy mechanism.