2026-08-16 12:00:00 +00:00
|
|
|
---
|
|
|
|
|
type: issue
|
|
|
|
|
id: "0055"
|
|
|
|
|
status: open
|
|
|
|
|
created: 2026-08-16
|
|
|
|
|
milestone: M2
|
|
|
|
|
priority: medium
|
|
|
|
|
area: security
|
|
|
|
|
related:
|
|
|
|
|
- "docs/issues/0054-ki-geraeuschunterdrueckung-element-call.md"
|
|
|
|
|
- "docs/adr/0018-ki-geraeuschunterdrueckung-clientseitig-opt-in.md"
|
|
|
|
|
- "docs/adr/0001-gitlab-kanonisch-push-mirror.md"
|
2026-08-18 12:00:00 +00:00
|
|
|
gitlab_iid: "39"
|
2026-08-16 12:00:00 +00:00
|
|
|
---
|
|
|
|
|
|
|
|
|
|
# Issue-0055: `@sorb`-Scope in ThreadNet-Web ist nirgends auf rohana festgelegt
|
|
|
|
|
|
|
|
|
|
## Problem / Motivation
|
|
|
|
|
|
|
|
|
|
`ThreadNet-Web` bezieht `@sorb/threadnet-call-embedded` aus der Gitea-npm-Registry auf rohana,
|
|
|
|
|
aber **im Repo steht nirgends, dass der Scope `@sorb` dorthin zeigt**. Es gibt weder eine
|
|
|
|
|
`.npmrc` im Wurzelverzeichnis noch in `apps/web`, und die CI setzt auch keine.
|
|
|
|
|
|
|
|
|
|
Dass es trotzdem funktioniert, liegt allein am Lockfile: `pnpm-lock.yaml` pinnt die vollständige
|
|
|
|
|
Tarball-URL
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
tarball: https://rohana.axion1337.de/api/packages/sorb/npm/%40sorb%2F…tgz
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
und die CI installiert mit `--frozen-lockfile`. Solange niemand die Version anhebt, wird der
|
|
|
|
|
Scope nie aufgelöst — und der fehlende Eintrag fällt nicht auf.
|
|
|
|
|
|
|
|
|
|
Aufgefallen beim Anheben auf `0.19.2-threadnet.8` (#0054): `pnpm install` griff nach
|
|
|
|
|
`registry.npmjs.org` und brach ab.
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
ERR_PNPM_FETCH_404 GET https://registry.npmjs.org/@sorb%2Fthreadnet-call-embedded: Not Found
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Die Anhebung ging nur durch, weil der Scope für diesen einen Aufruf von Hand gesetzt wurde:
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
env 'npm_config_@sorb:registry=https://rohana.axion1337.de/api/packages/sorb/npm/' pnpm install
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Das steht in keiner Doku. Der nächste, der die Abhängigkeit anhebt, läuft in dieselbe Wand.
|
|
|
|
|
|
|
|
|
|
## Warum das mehr ist als eine Unbequemlichkeit
|
|
|
|
|
|
|
|
|
|
Der heutige Fehlschlag ist **laut** — 404, Abbruch, niemand baut versehentlich etwas Falsches.
|
|
|
|
|
Laut ist gut. Der Punkt ist, dass die Lautstärke von einer Bedingung abhängt, die uns nicht
|
|
|
|
|
gehört: `@sorb/threadnet-call-embedded` existiert auf `registry.npmjs.org` **derzeit nicht**.
|
|
|
|
|
|
|
|
|
|
Registriert dort jemand diesen Namen, löst genau derselbe Befehl nicht mehr mit 404 auf, sondern
|
|
|
|
|
**erfolgreich — gegen ein fremdes Paket**. Das ist das Muster, das als *dependency confusion*
|
|
|
|
|
bekannt ist, und die Bedingung dafür ist nicht „ein Angriff auf uns", sondern „jemand legt einen
|
|
|
|
|
Scope-Namen an". Der Schutz besteht heute ausschließlich darin, dass ein Name auf einer fremden
|
|
|
|
|
Registry noch frei ist.
|
|
|
|
|
|
|
|
|
|
Verschärfend: Der Fehler träfe genau den Moment, in dem jemand eine Version anhebt — also den
|
|
|
|
|
Moment, in dem eine neue Abhängigkeit ohnehin erwartet wird und ein Download nicht auffällt.
|
|
|
|
|
|
|
|
|
|
Das ist dieselbe Klasse wie die Befunde aus #0054 und der Backup-Reihe: **die Absicherung besteht
|
|
|
|
|
nicht, sie ergibt sich nur zufällig aus dem aktuellen Zustand.** Sie „meldet" auch nichts — sie
|
|
|
|
|
funktioniert stillschweigend, bis sie es nicht mehr tut.
|
|
|
|
|
|
|
|
|
|
## Acceptance
|
|
|
|
|
|
|
|
|
|
- Eine **eingecheckte** `.npmrc` in `ThreadNet-Web` bindet den Scope fest:
|
|
|
|
|
`@sorb:registry=https://rohana.axion1337.de/api/packages/sorb/npm/`
|
|
|
|
|
- Ein Anheben der Version funktioniert im **frischen Klon ohne Zusatzschritte** — das ist der
|
|
|
|
|
eigentliche Nachweis, nicht das Vorhandensein der Datei.
|
|
|
|
|
- Gegenprobe: Ein Lauf mit absichtlich unerreichbarer rohana **scheitert**, statt auf
|
|
|
|
|
`registry.npmjs.org` auszuweichen.
|
|
|
|
|
- Die anderen Repos der Gruppe sind auf denselben Befund geprüft: Wer sonst noch `@sorb`-Pakete
|
|
|
|
|
zieht, hat dieselbe Lücke (`threadnet-call` selbst publisht nur, konsumiert aber ggf. auch).
|
|
|
|
|
- Der Auslieferungsweg in `ThreadNet-Web:docs/axion1337-fork.md` nennt den Befehl zum Anheben.
|
|
|
|
|
|
|
|
|
|
## Notes
|
|
|
|
|
|
|
|
|
|
**Kein Token nötig.** Der Lesezugriff auf die Registry ist anonym möglich (nachgeprüft: der
|
|
|
|
|
Paket-Index antwortet ohne Authentifizierung). Die `.npmrc` enthält damit **nur eine URL und kein
|
|
|
|
|
Geheimnis** und kann bedenkenlos eingecheckt werden — das ist der Grund, warum hier kein
|
|
|
|
|
Secrets-Handling dranhängt.
|
|
|
|
|
|
|
|
|
|
**Warum nicht einfach dokumentieren:** Ein Satz in der Fork-Doku würde den 404 erklären, aber die
|
|
|
|
|
`registry.npmjs.org`-Auflösung nicht verhindern. Nach der Lehre aus #0053 und dem Bindmount-Fall
|
|
|
|
|
ist Aufschreiben hier ausdrücklich **nicht** die Maßnahme: die Regel war beide Male vorhanden und
|
|
|
|
|
hat den Fehler nicht verhindert. Wirksam ist die eingecheckte Datei, weil sie den falschen Weg
|
|
|
|
|
gar nicht erst offen lässt.
|
|
|
|
|
|
|
|
|
|
**Verwandt, aber getrennt:** Bei der Gelegenheit ist aufgefallen, dass der Job `publish_npm` in
|
|
|
|
|
`threadnet-call` `allow_failure: true` trägt — ein *scheiternder* Publish färbt die Pipeline
|
|
|
|
|
nicht rot. Das ist ein eigener Befund und gehört nicht in dieses Issue; hier nur notiert, damit
|
|
|
|
|
er nicht verloren geht.
|