RoastMyOpsec

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.

ControlWho honors itPublic originTakeaway
CORS ACAO allowlistBrowsers on fetch/XHRNamed originsThe modern gate
/crossdomain.xml *Legacy plugin policyDeleteNot a scored roast path; remove anyway
JSONP callback=Any script tagRetireSee JSONP vs CORS
clientaccesspolicy.xmlSilverlight leftoverDeleteSame 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 now

FAQ

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