[sec-check] SVG remote-reference gate misses src attributes, link hrefs and bare-string @import
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 88/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- javascript
- Ambito
- security
Direzione di ricerca
Inizia in scripts/lib/svg-active-content.mjs, in findRemoteReferences(), RESOURCE_ELEMENTS, CSS_URL_PATTERN e cssTargets(); esegui i tre snippet di riproduzione dell’issue. Il lavoro è completato quando vengono segnalati gli attributi src remoti, gli href dei link e i target @import di stringhe nude tra virgolette, mentre la normale navigazione delle ancore rimane consentita.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Security Finding
Severity: medium
Type: unsafe-pattern (incomplete input validation / detection bypass)
findRemoteReferences() in scripts/lib/svg-active-content.mjs is the control
that stops an imported SVG from making a visitor's browser fetch a subresource
from a third-party host. scripts/validate-architecture-assets.mjs:188-190
records every one of its findings as a hard error, so it blocks CI on every
pull request and every scheduled import.
It only ever inspects two things: an href attribute on an element in
RESOURCE_ELEMENTS, and a url(...) token in CSS. Three reference shapes that
load a remote subresource carry neither, and walk past the gate silently.
1. src is never inspected
src is not an SVG attribute, so it reaches the scanner only through the HTML
a <foreignObject> may carry — and foreignObject is deliberately allowed
("editors such as draw.io emit it for ordinary text", svg-active-content.mjs:19-20;
static/img/architectures/swisscom-cloud-native-telco/swisscom-cloud-native-telco-automation-layers.svg
already contains one). The src attribute on img, video, source and friends
is all permitted today.
2. <link> is not in RESOURCE_ELEMENTS
<link rel="stylesheet" href="https://evil.example/x.css"> inside a
foreignObject fetches a third-party stylesheet on load. link is absent from
the set at svg-active-content.mjs:83-89, so its href is never tested.
3. CSS @import with a bare string target
@import "https://evil.example/x.css"; is valid CSS and fetches the stylesheet
exactly as @import url(...) does, but carries no url( token for
CSS_URL_PATTERN to match. STYLE_BLOCK_PATTERN finds the block; the scan
inside it finds nothing.
Reproduction
Against scripts/lib/svg-active-content.mjs at 7772dcf:
import { findRemoteReferences } from './scripts/lib/svg-active-content.mjs';
const svg = (b) => `<svg xmlns="http://www.w3.org/2000/svg">${b}</svg>`;
findRemoteReferences(svg('<foreignObject><img src="https://evil.example/beacon.png"/></foreignObject>'));
// [] <- not flagged
findRemoteReferences(svg('<foreignObject><link rel="stylesheet" href="https://evil.example/x.css"/></foreignObject>'));
// [] <- not flagged
findRemoteReferences(svg('<style>@import "https://evil.example/x.css";</style>'));
// [] <- not flagged
findRemoteReferences(svg('<image href="https://evil.example/x.png"/>'));
// ['references a remote resource in <image> href: ...'] <- control, flagged
Impact
static/img/architectures/** is published verbatim at the site origin, and the
module's own threat model is that a visitor may open an SVG directly rather
than through an <img> (svg-active-content.mjs:4-7). When they do, every
subresource in the three shapes above is fetched from a host the diagram's
author chose, disclosing the visitor's IP address, User-Agent and Referer to
that third party — exactly the outcome findRemoteReferences() exists to
prevent and that the artwork-mirroring in scripts/lib/project-assets.mjs
exists to prevent elsewhere.
The author is third-party in both paths that write these files: the daily
import-architectures job from the upstream cncf/architecture checkout, and
import-architecture-issue.mjs from a community submission issue. Neither is
reviewed byte-by-byte; the CI error is the review. A remote stylesheet
additionally lets the third party restyle the document it is loaded into.
The current corpus is clean (50 SVGs under static/, no src=, <link href> or @import), so this is a gap in the gate rather than an exposure that
has already landed.
Recommendation
Extend the detection in scripts/lib/svg-active-content.mjs to cover all
three. Exact replacement text:
-
Add
'link'toRESOURCE_ELEMENTS(svg-active-content.mjs:83-89). -
Check
srcon any element — unlikehrefthere is no element on which it
reads as visitor-chosen navigation, so it needs no allow-list. In
findRemoteReferences(), replaceif (name === 'href' && RESOURCE_ELEMENTS.has(element)) {with
if ( (name === 'href' && RESOURCE_ELEMENTS.has(element)) || name === 'src' ) { -
Add a bare-string
@importpattern besideCSS_URL_PATTERNand scan for
both incssTargets():const CSS_IMPORT_PATTERN = /@import\s+(?:"([^"]*)"|'([^']*)')/gi;function cssTargets(css) { const targets = []; for (const pattern of [CSS_URL_PATTERN, CSS_IMPORT_PATTERN]) { for (const match of String(css).matchAll(pattern)) { const value = match[1] ?? match[2] ?? match[3] ?? ''; const target = remoteTarget(value); if (target) targets.push(target); } } return targets; }
a must stay out of RESOURCE_ELEMENTS: a hyperlink is navigation the visitor
chooses, and the existing draw.io corpus carries one.
Scope
One deliverable, one file, one function — a single pull request closes this.
-
srcon any element is reported as a remote reference - a
linkelement href is reported as a remote reference - bare-string
@importin a<style>block is reported as a remote reference
This does not overlap #818, which adds branch-coverage tests to
tests/svg-active-content.test.mjs and does not change
scripts/lib/svg-active-content.mjs.
Filed by sec-check agent (ACMM L4/L5 - hold-gated mode)
🐝 Hive Agent: security | Instance: hosted-available-lke648397-260827-5n31 | SHA: 7772dcf
— hive: agent=sec-check backend=copilot model=claude-opus-5 copilot=1.0.88
- Lingua principale
- JavaScript
- Stelle
- 0
- Fork
- 3
- Merge medio
- 7h 15m
- PR unite (30g)
- 565
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di cncf/endusers
-
agent/quality bug ci stage/010-actionable
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
I maintainer di solito rispondono entro 1 giorno
-
[quality] /resources/metrics publishes a commit count as "Reference architecture submissions" (28 on the chart, 8 on the card)Forse già presa @hivecommons-hive l’ha presa oggi. Apertaagent/quality hive/claimed-by-scanner stage/040-covered-by-pr testing
Difficoltà 2/5 1-3 ore Idoneità per principianti 35/100
cncf/endusers#1977 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
a11y: search button accessible name does not contain its visible label (WCAG 2.5.3)Forse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Apertablocked bug hive/claimed-by-scanner needs-human
Difficoltà 4/5 3-5 giorni Idoneità per principianti 39/100
cncf/endusers#1618 · 8 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
🐝 Hive Advisory ReportForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Apertahive/advisory
Difficoltà 5/5 Più di una settimana Idoneità per principianti 15/100
cncf/endusers#23 · 8 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di cncf/endusers
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
Graphify-Labs/graphify#4860 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
CommandCodeAI/command-code#1088 ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
CanadaHonk/porffor#426 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
RIT-Software-Engineering/RIT-SE-Senior-Project#546 ·
I maintainer di solito rispondono entro 1 giorno