X-Permitted-Cross-Domain-Policies is a response header that sets a meta-policy controlling whether site resources can be accessed cross-origin by documents running in legacy web clients (for example, Adobe Acrobat or Microsoft Silverlight).
Usage is less common today because Flash/Silverlight have been deprecated, but many security testing tools still check for X-Permitted-Cross-Domain-Policies: none to reduce the risk of an overly-permissive cross-domain policy being present accidentally or maliciously.
This documentation format mirrors the style used in the existing header docs (e.g., Cache-Control).
from secure import Secure, XPermittedCrossDomainPolicies
secure_headers = Secure(
xpcdp=XPermittedCrossDomainPolicies().none()
)X-Permitted-Cross-Domain-Policies: noneMost modern apps do not need this header, but security scanners still look for it. Add it when you want an explicit deny policy for legacy cross-domain policy files.
If you create XPermittedCrossDomainPolicies() and do not set a policy, it returns the library default value:
- Default header value:
none
This is the least permissive option and is the most common secure setting when you do not need legacy cross-domain policy behavior.
If you don’t configure anything, the default value is emitted.
Preset.BASIC includes X-Permitted-Cross-Domain-Policies: none; Preset.BALANCED and Preset.STRICT leave it out unless you add it explicitly.
from secure import XPermittedCrossDomainPolicies
xpcdp = XPermittedCrossDomainPolicies() # default: none
print(xpcdp.header_name) # X-Permitted-Cross-Domain-Policies
print(xpcdp.header_value) # noneMDN notes this is the typical configuration when you don’t need legacy clients.
xpcdp = XPermittedCrossDomainPolicies().master_only()
print(xpcdp.header_value) # master-onlyThis allows cross-domain access to the master policy file defined on the same domain.
xpcdp = XPermittedCrossDomainPolicies().by_content_type()
print(xpcdp.header_value) # by-content-typeOnly policy files served with Content-Type: text/x-cross-domain-policy are allowed.
xpcdp = XPermittedCrossDomainPolicies().none_this_response()
print(xpcdp.header_value) # none-this-responseThis directive is unique to the HTTP header and indicates the current document should not be used as a policy file.
.none().master_only().by_content_type()(HTTP/HTTPS only).by_ftp_filename()(FTP only).all().none_this_response()(HTTP-header-only)
These map directly to the directive definitions described by MDN (and largely echoed by OWASP).
.policy("none" | "master-only" | "by-content-type" | "by-ftp-filename" | "all" | "none-this-response")
Raises ValueError for unsupported values (helps catch typos early).
Set an explicit header value (replaces any configured directive):
xpcdp = XPermittedCrossDomainPolicies().value("none")
print(xpcdp.header_value) # noneAlias for .value(...) (use when you intentionally want a raw string value):
xpcdp = XPermittedCrossDomainPolicies().custom("master-only")
print(xpcdp.header_value) # master-onlyReset to the default:
xpcdp = XPermittedCrossDomainPolicies().all().clear()
print(xpcdp.header_value) # none- The header value is rendered as a single directive token, so output is inherently deterministic.
- Raw setters (
.value(...)/.custom(...)) normalize obvious header-splitting primitives (CR/LF) before serialization; stricter validation can be enforced viaSecure.validate_and_normalize_headers(...).
This library implements security recommendations and behavior described by:
- MDN Web Docs (licensed under CC-BY-SA 2.5)
- OWASP Secure Headers Project (licensed under CC-BY-SA 4.0)