EntwicklerMitarbeiter-Handbuch

Security-Richtlinien

Der sellx Hub führt Plugin-Queries gegen die echte JTL-Wawi-Datenbank aus. Sicherheit ist deshalb nicht optional — ein Plugin kann potenziell Daten exfiltrieren oder Schaden anrichten, wenn es nicht durch den Validator geprüft wird.

Entwickler-Handbuch · Plugin-Authoring

SqlSecurityValidator

Datei: sellx-sidecar/SellxSidecar/Services/SqlSecurityValidator.cs

Der Validator läuft vor jeder Query-Ausführung und prüft statisch:

PrüfungRegelFehlercode
Single-StatementGenau ein ;-freies Top-Level-StatementMULTI_STATEMENT
Keine EXECEXEC/EXECUTE blockiertEXEC_NOT_ALLOWED
Keine sp_/xp_System-Prozeduren blockiertSYSTEM_PROC_NOT_ALLOWED
Keine OPENROWSET/OPENDATASOURCEExterner Datenbankzugriff blockiertEXTERNAL_ACCESS
Keine Kommentare-- und /* */ blockiertCOMMENTS_NOT_ALLOWED
Read-only by defaultINSERT/UPDATE/DELETE/MERGE nur in automation-PluginsWRITE_NOT_ALLOWED
Keine Temp-Tables#temp, @@ nur in automationTEMP_TABLE_NOT_ALLOWED

Was passiert bei Verletzung?

textvalidator-flow.txt
Plugin-Author: Schreibt INSERT in SQL
  ↓
Hub: SqlSecurityValidator lehnt ab mit WRITE_NOT_ALLOWED
  ↓
Frontend zeigt Fehler: "SQL_SECURITY_VIOLATION: Write-Operation not allowed in 'report'-Plugin"
  ↓
User kann nichts machen außer Plugin-Author kontaktieren

Erlaubte SQL-Patterns

Read-Only (category: "report")

sqlsql/read-only.sql
SELECT cName, fPreis FROM tArtikel WHERE kArtikel > 0
SELECT * FROM vBestellung WHERE dErstellt > '2026-01-01'
SELECT COUNT(*) FROM tKunde
SELECT TOP 100 * FROM tBestellung ORDER BY kBestellung DESC

Aggregationen, JOINs, Sub-Queries

sqlsql/aggregations.sql
SELECT kKunde, SUM(fGesamtsumme) AS Umsatz
FROM tBestellung
WHERE dErstellt > '2026-01-01'
GROUP BY kKunde
HAVING SUM(fGesamtsumme) > 1000

CTEs, Window Functions

sqlsql/cte.sql
WITH RankedArticles AS (
  SELECT cName, fVerkauft, ROW_NUMBER() OVER (ORDER BY fVerkauft DESC) AS rn
  FROM tArtikel
)
SELECT * FROM RankedArticles WHERE rn <= 10

Write-Operations (category: "automation", requiresDbRole: "write")

sqlsql/write.sql
UPDATE tArtikel SET fLagerbestand = fLagerbestand - 1 WHERE kArtikel = @articleId
INSERT INTO tLog (dZeit, cMessage) VALUES (GETDATE(), @msg)

Schema-Queries

sqlsql/schema.sql
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'
SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'tArtikel'

Verbotene Patterns

sqlsql/concat-bad.sql
SELECT * FROM tArtikel WHERE cName = '@{userInput}'

→ Verwende immer @{paramName} und vertraue auf Parameterisierung.

sqlsql/multi-bad.sql
SELECT 1; SELECT 2
SELECT 1; DROP TABLE tArtikel
sqlsql/comments-bad.sql
SELECT cName -- der Artikelname
FROM tArtikel

SELECT cName FROM tArtikel
sqlsql/sysproc-bad.sql
EXEC sp_who
EXEC xp_cmdshell 'dir'
EXEC master.dbo.xp_dirtree 'C:'
sqlsql/openrowset-bad.sql
SELECT * FROM OPENROWSET('SQLOLEDB', '...', 'SELECT 1')
SELECT * FROM OPENDATASOURCE('SQLNCLI', '...').master.dbo.sysobjects
sqlsql/dynamic-bad.sql
EXEC('SELECT * FROM tArtikel WHERE kArtikel = ' + @articleId)

Threat Model

AngreiferZielMitigation
Bösartiger Plugin-AuthorDaten exfiltrierenValidator + Signatur + Audit-Logs
Bösartiger EndkundePlugin missbrauchen, um mehr Daten zu sehenRBAC via DB-Rolle, kein direkter SQL-Zugriff
Kompromittiertes Plugin-Signing-KeySchadcode einschleusenKey-Rotation in Central, Hardware-Bindung
Sidecar-SchwachstelleRCE auf KundenrechnerHardened .NET-Config, Process-Isolation

Audit-Log

Jede Query-Ausführung wird geloggt mit:

textaudit-log.txt
[INFO] 2026-06-30 14:23:11 — plugin=sellx.artikel-kpi query=top-articles rows=27 duration_ms=143 userHash=a1b2c3

Diese Logs sind über get_log_entries("INFO") in den Einstellungen einsehbar.

Best Practices für Plugin-Autoren

  1. Schreibe Queries defensiv — prüfe NULL, prüfe Bereiche
  2. Verwende sprechende Aliasse — vermeide JTL-Spaltennamen im Output
  3. Dokumentiere Parameter — gute label und description sind UX
  4. Teste mit großen Datenmengen— JTL-Mandanten haben oft > 100k Artikel
  5. Halte das Manifest minimal — nur Felder, die du brauchst
  6. Signiere deine Plugins — verhindert Manipulation auf dem Weg zum Kunden