Web-Plugin-Markt
Die Web-App hat einen Plugin-Markt zum Installieren von SheetForge-Plugins in den Browser, plus einen separaten Pfad zum Sideloaden eines ungeprüften Plugins von einer GitHub-URL. Derselbe Markt, neu gebaut in UIToolkit, wird auch innerhalb von Unity ausgeliefert.
Die Registry — eine statische Datei, zwei Leser
Die Markt-Auflistung stammt aus einer einzigen statischen Registry-Datei (public/registry/plugins.json), die sowohl die Web-App als auch das Markt-Fenster in Unity lesen. Es gibt eine Liste, daher zeigen beide Oberflächen immer denselben Katalog.
SheetForge hostet die Plugin-Binärdateien nicht. Das übernimmt der eigene GitHub-Release jedes Autors. Der Registry-Eintrag ist Metadaten plus ein fixierter Hash — keine Kopie des Plugins.
Hash-Fixierung — Integrität, bevor der Core auch nur ein Byte sieht
Jeder Registry-Eintrag trägt den SHA-256-Wert, der bei der Freigabe des Plugins erfasst wurde. Beim Beziehen wird jedes empfangene Byte gegen diesen Hash geprüft, bevor es je den Core erreicht. Eine Abweichung um ein einziges Byte wird abgelehnt.
Das ist es, was „die Binärdatei lebt auf dem GitHub eines anderen" sicher macht: Der Release kann von überall erneut heruntergeladen werden, aber es werden immer nur die exakt freigegebenen Bytes geladen.
Ein-Klick-Installation über den Server-Proxy
Browser können GitHub-Release-Assets nicht direkt abrufen — Cross-Origin-Regeln (CORS) blockieren das. Der Bezug läuft daher über eine Server-Proxy-Route (api/market/artifact, verdrahtet über den ArtifactProxy in lib/market/install.ts), die den Release serverseitig abruft und zurückstreamt. Die Installation ist daher ein Klick.
Ein manueller Download-und-Upload-Pfad bleibt als sekundärer Fallback für den Fall, dass der Proxy einen Release nicht erreichen kann. Er durchläuft denselben Hash-Check — einer hochgeladenen Datei wird nicht mehr vertraut als einer per Proxy bezogenen.
Das Kompatibilitäts-Gate — nach der Integrität, vor der Registrierung
Das Bestehen des Hash-Checks beweist, dass die Bytes die freigegebenen sind. Es sagt nichts darüber, ob dieser Host das Format dieses Plugins lesen kann — das ist eine zweite, separate Frage.
Die Antwort kommt aus der verifizierten DLL selbst: einer Assembly-Level-Deklaration, die die Generation des Plugin-Formats benennt, für die sie gebaut wurde, sowie die niedrigste Host-Version, die sie voraussetzt.
- Die Auflistung wirbt, die Assembly entscheidet. Ein Registry-Eintrag trägt dieselben zwei Werte (
pluginFormat,minHost), sodass der Katalog sie vor dem Download zeigen kann. Das Gate selbst liest die Deklaration aus den Bytes, die gerade die Verifikation bestanden haben. Ein Eintrag kann veraltet sein; eine kompilierte Deklaration kann es nicht. - Ein Gate, drei Pfade. Markt-Installation, Sideload und eine einfache lokale Datei stellen alle dasselbe Prädikat, sodass kein Pfad still akzeptieren kann, was ein anderer ablehnt.
- Alles oder nichts pro Assembly. Eine abgelehnte Assembly registriert nichts — nie die Hälfte ihrer Verträge —, und die Ablehnung benennt, was die Assembly deklariert hat, gegen das, was dieser Host liest.
- Keine Deklaration ist unbedenklich. Ein Plugin, das gebaut wurde, bevor das Attribut existierte, wird als früheste Generation ohne Host-Anforderung gelesen, sodass es genau so lädt wie immer.
Caching und Entladen
Bytes, die den Hash-Check bestehen, werden im Browser zwischengespeichert (IndexedDB), sodass ein in der Liste aktiviertes Plugin bei späteren Besuchen automatisch lädt — Sie aktivieren es einmal.
Ein Plugin zu deaktivieren oder zu entfernen wirkt sofort: Die App weist den Kern an, diese Assembly aus der Plugin-Zusammenstellung zu nehmen und die Sitzung neu aufzubauen, sodass ihre Zelltypen, Enums, Vorlagen, Farbvoreinstellungen, Studio-Aktionen und Canvas-Überlagerungen ohne Neuladen verschwinden. (.NET selbst entlädt eine Assembly nie – die Bytes bleiben in der Seite resident, aber wirkungslos; aktivierst du dasselbe Plugin erneut, reaktiviert der Kern die residente Assembly, statt sie ein zweites Mal zu laden.)
Ein ungeprüftes Plugin von einer GitHub-URL sideloaden
Getrennt von der kuratierten Registry können Sie der App eine beliebige GitHub-URL übergeben, um ein ungeprüftes Plugin zu sideloaden (lib/market/sideload.ts, ausgeliefert von api/market/github). Das dient dem Ausprobieren eines Plugins, das nicht im Katalog steht.
Weil diese Achse eine vom Nutzer gelieferte URL statt eines geprüften Registry-Eintrags entgegennimmt, ist sie die eine Stelle, die SSRF-Abwehr direkt erzwingt:
- Die URL muss sich zu einem GitHub-Familien-Host auflösen —
github.com,raw.githubusercontent.com,release-assets.githubusercontent.comund ähnliche —, exakt abgeglichen, klein geschrieben. - Redirects, die in ein internes Netzwerk durchsickern würden, werden an dieser Grenze blockiert.
Sideload-Artefakte werden unter einem eigenen Besitzer-Tag (sideload:) zwischengespeichert. Ein ungeprüftes Plugin, das zufällig dieselben Bytes wie ein Registry-Eintrag trägt, bleibt so vom kuratierten getrennt — ein Sideload gibt sich nie als freigegebenes Plugin aus.
GitHub als Importquelle
Beide Pfade leiten Plugin-Bytes durch dieselbe Pipeline:
- Registry-Installation zieht das auf dem GitHub-Release des Autors gehostete Artefakt über den Server-Proxy und prüft es dann gegen den fixierten SHA-256.
- Sideload akzeptiert eine rohe GitHub-URL, abgesichert auf GitHub-Familien-Hosts, und prüft die Bytes auf dieselbe Weise.
In beiden Fällen wird die CORS-Beschränkung des Browsers bei GitHub-Release-Assets serverseitig gehandhabt, während die Integrität durch den Hash-Check auf dem Client bewahrt wird, bevor der Core irgendetwas lädt.
Der Markt innerhalb von Unity
Der Unity-Plugin-Markt wurde in UIToolkit neu gebaut, um wie der Web-Markt auszusehen — ein Karten-Grid neben einem Detail-Panel, das dieselbe statische Registry liest, mit derselben Ablehnung bei Hash-Abweichung und demselben Full-Trust-Installationshinweis.
Anmeldung sowie die im Browser gespeicherte Plugin-Liste und die Presets bleiben nur im Web; das Unity-Fenster ist die Katalog- und Installationsoberfläche.
Verwandte Seiten
- SheetForge Web — die Browser-App, in der der Markt lebt
- Plugin-Erstellung — das Plugin bauen, auf das ein Markt-Eintrag zeigt