Vulnerabilities
crossdomain.xml vs CORS for Public Browser APIs
October 9, 2022
crossdomain.xml vs CORS for public browser APIs is two generations of cross-origin policy. CORS (Access-Control-Allow-Origin and friends) is what browsers enforce on fetch and XHR. /crossdomain.xml is an Adobe Flash (and some PDF/plugin) policy file that listed which origins could talk to the host. A file that still says allow-access-from domain="*" is a leftover allow-all, not a substitute for a named CORS allowlist. Modern Chrome does not run Flash. The file is still an inventory gift and a signal that nobody audited the origin. clientaccesspolicy.xml is the Silverlight cousin. RoastMyOpsec app mode sends a bounded untrusted Origin and reads ACAO. It does not currently score /crossdomain.xml, does not parse policy XML, and does not load plugins.
The practical difference
CORS is response headers on the API. crossdomain.xml is a well-known XML document at the site root (and sometimes in subpaths). JSONP is a third costume: a script callback with no origin list. Replace JSONP with CORS. Delete Flash policy files.
robots.txt Disallow: /crossdomain.xml advertises the name. Deny or 404 the object at the CDN. See JSONP vs CORS and CORS wildcard vs allowlist.
How to choose a policy
Public marketing APIs for browsers: CORS with named origins, no credentials unless you mean it. No crossdomain.xml in the artifact. If a legacy PDF or kiosk still required the file, it does not belong on the brand CDN next to index.html — isolate that host. Staging copies of * policies must not ship to production.
| Control | Who honors it | Public origin | Takeaway |
|---|---|---|---|
| CORS ACAO allowlist | Browsers on fetch/XHR | Named origins | The modern gate |
| /crossdomain.xml * | Legacy plugin policy | Delete | Not a scored roast path; remove anyway |
| JSONP callback= | Any script tag | Retire | See JSONP vs CORS |
| clientaccesspolicy.xml | Silverlight leftover | Delete | Same class |
When CORS wins
CORS always wins for browser APIs in 2026. crossdomain.xml never wins as a security control on a marketing site. A missing file is healthy. Pair with credentials vs wildcard if ACAO is * with cookies.
What the roast can prove
ACAO on a bounded untrusted Origin can surface. crossdomain.xml is not a scored path. Confirm a 404 yourself. Pair with public JS keys if the old policy sat beside a publishable key.
Common mistakes
The first mistake is copying allow-access-from * from a 2012 CMS into the static bucket.
The second mistake is treating a 200 on /crossdomain.xml as 'required for CORS.'
The third mistake is Disallow: /crossdomain.xml and calling it access control.
Free audit the URL you own
RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.
Free audit nowFAQ
- Do I need crossdomain.xml for CORS?
- No. CORS is headers. The XML file is a Flash-era leftover. Delete it from the public origin.
- Is a missing crossdomain.xml a roast F?
- No. Missing the file is the healthy state. A world-readable * policy is the miss.
- Does RoastMyOpsec fetch crossdomain.xml?
- Not as a scored path today. It does read CORS headers. Deny or delete the XML anyway.
Sources
Related guides
Vulnerabilities
CORS Wildcard vs Allowlist for Public APIsVulnerabilities
JSONP vs CORS for Public Browser APIsVulnerabilities
CORS Credentials vs Wildcard Origins