Skip to content

Sicherheitshinweise ​

Was Sie nach diesem Lernabschnitt können werden ​

  • Verstehen, wie das Plugin Ihr System vor Sicherheitsbedrohungen schützt
  • Wissen, welchen Sicherheitsstandards Skill-Dateien entsprechen müssen
  • Die Best Practices für die sichere Verwendung des Plugins beherrschen

Grundlegende Überlegungen ​

Das OpenCode Agent Skills Plugin läuft in Ihrer lokalen Umgebung, führt Skripte aus, liest Dateien und parst Konfigurationen. Obwohl es leistungsfähig ist, können Skill-Dateien aus nicht vertrauenswürdigen Quellen auch Sicherheitsrisiken mit sich bringen.

Das Plugin wurde mit mehreren Sicherheitsebenen entwickelt, die wie Schutzschichten funktionieren – von Pfadzugriff, Dateiparsing bis zur Skriptausführung. Das Verständnis dieser Mechanismen hilft Ihnen, das Plugin sicherer zu nutzen.

Detaillierte Sicherheitsmechanismen ​

1. Pfadsicherheitsprüfung: Verhinderung von Directory Traversal ​

Problem: Wenn Skill-Dateien böswillige Pfade enthalten (z.B. ../../etc/passwd), könnte auf sensible Systemdateien zugegriffen werden.

Schutzmaßnahmen:

Das Plugin verwendet die Funktion isPathSafe() (src/utils.ts:130-133), um sicherzustellen, dass alle Dateizugriffe auf das Skill-Verzeichnis beschränkt sind:

typescript
export function isPathSafe(basePath: string, requestedPath: string): boolean {
  const resolved = path.resolve(basePath, requestedPath);
  return resolved.startsWith(basePath + path.sep) || resolved === basePath;
}

Funktionsweise:

  1. Der angeforderte Pfad wird in einen absoluten Pfad aufgelöst
  2. Es wird geprüft, ob der aufgelöste Pfad mit dem Skill-Verzeichnis beginnt
  3. Wenn der Pfad versucht, das Skill-Verzeichnis zu verlassen (mit ..), wird er direkt abgelehnt

Praktisches Beispiel:

Wenn das Tool read_skill_file eine Datei liest (src/tools.ts:101-103), wird zuerst isPathSafe aufgerufen:

typescript
// Security: ensure path doesn't escape skill directory
if (!isPathSafe(skill.path, args.filename)) {
  return `Invalid path: cannot access files outside skill directory.`;
}

Das bedeutet:

  • ✅ docs/guide.md → Erlaubt (innerhalb des Skill-Verzeichnisses)
  • ❌ ../../../etc/passwd → Abgelehnt (versucht auf Systemdateien zuzugreifen)
  • ❌ /etc/passwd → Abgelehnt (absoluter Pfad)

Warum ist das wichtig

Directory Traversal-Angriffe sind häufige Schwachstellen in Web-Anwendungen. Auch wenn das Plugin lokal läuft, könnten nicht vertrauenswürdige Skills versuchen, auf Ihre SSH-Schlüssel, Projektkonfigurationen und andere sensible Dateien zuzugreifen.

2. Sichere YAML-Analyse: Verhinderung von Codeausführung ​

Problem: YAML unterstützt benutzerdefinierte Tags und komplexe Objekte. Böswilliges YAML könnte durch Tags Code ausführen (z.B. !!js/function).

Schutzmaßnahmen:

Das Plugin verwendet die Funktion parseYamlFrontmatter() (src/utils.ts:41-49) mit einer strengen YAML-Parsing-Strategie:

typescript
export function parseYamlFrontmatter(text: string): Record<string, unknown> {
  try {
    const result = YAML.parse(text, {
      // Use core schema which only supports basic JSON-compatible types
      // This prevents custom tags that could execute code
      schema: "core",
      // Limit recursion depth to prevent DoS attacks
      maxAliasCount: 100,
    });
    return typeof result === "object" && result !== null
      ? (result as Record<string, unknown>)
      : {};
  } catch {
    return {};
  }
}

Wichtige Sicherheitseinstellungen:

EinstellungWirkung
schema: "core"Unterstützt nur grundlegende JSON-Typen (String, Zahl, Boolean, Array, Objekte), deaktiviert benutzerdefinierte Tags
maxAliasCount: 100Begrenzt die Rekursionstiefe von YAML-Aliassen, um DoS-Angriffe zu verhindern

Praktisches Beispiel:

yaml
# Böswilliges YAML-Beispiel (wird vom Core-Schema abgelehnt)
---
!!js/function >
function () { return "malicious code" }
---

# Korrektes sicheres Format
---
name: my-skill
description: A safe skill description
---

Wenn das YAML-Parsing fehlschlägt, ignoriert das Plugin den Skill stillschweigend und fährt mit der Erkennung anderer Skills fort (src/skills.ts:142-145):

typescript
let frontmatterObj: unknown;
try {
  frontmatterObj = parseYamlFrontmatter(frontmatterText);
} catch {
  return null;  // Parsing fehlgeschlagen, überspringe diesen Skill
}

3. Eingabevalidierung: Strenge Zod-Schema-Prüfung ​

Problem: Die Frontmatter-Felder eines Skills könnten nicht der Spezifikation entsprechen, was zu abnormalem Plugin-Verhalten führen könnte.

Schutzmaßnahmen:

Das Plugin verwendet ein Zod-Schema (src/skills.ts:105-114) zur strengen Validierung des Frontmatters:

typescript
const SkillFrontmatterSchema = z.object({
  name: z.string()
    .regex(/^[\p{Ll}\p{N}-]+$/u, { message: "Name must be lowercase alphanumeric with hyphens" })
    .min(1, { message: "Name cannot be empty" }),
  description: z.string()
    .min(1, { message: "Description cannot be empty" }),
  license: z.string().optional(),
  "allowed-tools": z.array(z.string()).optional(),
  metadata: z.record(z.string(), z.string()).optional()
});

Validierungsregeln:

FeldRegelAbgelehntes Beispiel
nameKleinbuchstaben, Zahlen, Bindestrich, darf nicht leer seinMySkill (Großbuchstaben), my skill (Leerzeichen)
descriptionDarf nicht leer sein"" (leerer String)
licenseOptionaler String-
allowed-toolsOptionaler String-Array[123] (kein String)
metadataOptionaler Key-Value-Objekt (Werte sind Strings){key: 123} (Wert ist kein String)

Praktisches Beispiel:

yaml
# ❌ Fehler: name enthält Großbuchstaben
---
name: GitHelper
description: Git operations helper
---

# ✅ Korrekt: entspricht der Spezifikation
---
name: git-helper
description: Git operations helper
---

Wenn die Validierung fehlschlägt, überspringt das Plugin den Skill (src/skills.ts:147-152):

typescript
let frontmatter: SkillFrontmatter;
try {
  frontmatter = SkillFrontmatterSchema.parse(frontmatterObj);
} catch (error) {
  return null;  // Validierung fehlgeschlagen, überspringe diesen Skill
}

4. Skriptausführungssicherheit: Nur ausführbare Dateien werden ausgeführt ​

Problem: Wenn das Plugin beliebige Dateien ausführt (z.B. Konfigurationsdateien, Dokumente), könnte dies zu unerwarteten Konsequenzen führen.

Schutzmaßnahmen:

Bei der Skripterkennung (src/skills.ts:59-99) sammelt das Plugin nur Dateien mit Ausführungsberechtigung:

typescript
async function findScripts(skillPath: string, maxDepth: number = 10): Promise<Script[]> {
  const scripts: Script[] = [];
  const skipDirs = new Set(['node_modules', '__pycache__', '.git', '.venv', 'venv', '.tox', '.nox']);

  // ... Rekursive Traversierungslogik ...

  if (stats.isFile()) {
    // Wichtig: Nur Dateien mit Ausführungsbit sammeln
    if (stats.mode & 0o111) {
      scripts.push({
        relativePath: newRelPath,
        absolutePath: fullPath
      });
    }
  }
  // ...
}

Sicherheitsmerkmale:

PrüfungsmechanismusWirkung
Ausführungsbit-Prüfung (stats.mode & 0o111)Führt nur Dateien aus, die vom Benutzer explizit als ausführbar markiert wurden, verhindert versehentliche Ausführung von Dokumenten
Überspringen versteckter Verzeichnisse (entry.name.startsWith('.'))Scannt keine .git-, .vscode-Verzeichnisse usw., vermeidet das Scannen zu vieler Dateien
Überspringen von Abhängigkeitsverzeichnissen (skipDirs.has(entry.name))Überspringt node_modules, __pycache__ usw., vermeidet das Scannen von Drittanbieter-Abhängigkeiten
Rekursionstiefenbegrenzung (maxDepth: 10)Begrenzt die Rekursionstiefe auf 10 Ebenen, verhindert Leistungsprobleme durch tief verschachtelte Verzeichnisse

Praktisches Beispiel:

Im Skill-Verzeichnis:

bash
my-skill/
├── SKILL.md
├── deploy.sh          # ✓ Ausführbar (als Skript erkannt)
├── build.sh           # ✓ Ausführbar (als Skript erkannt)
├── README.md          # ✗ Nicht ausführbar (wird nicht als Skript erkannt)
├── config.json        # ✗ Nicht ausführbar (wird nicht als Skript erkannt)
└── node_modules/      # ✗ Übersprungen (Abhängigkeitsverzeichnis)
    └── ...           # ✗ Übersprungen

Wenn run_skill_script("my-skill", "README.md") aufgerufen wird, wird README.md aufgrund fehlender Ausführungsberechtigung nicht als Skript erkannt (src/skills.ts:86), sodass ein "Nicht gefunden"-Fehler zurückgegeben wird (src/tools.ts:165-177).

Best Practices für Sicherheit ​

1. Skills aus vertrauenswürdigen Quellen beziehen ​

  • ✓ Verwenden Sie offizielle Skill-Repositories oder vertrauenswürdige Entwickler
  • ✓ Überprüfen Sie die GitHub-Sterne-Anzahl und die Aktivität der Contributors eines Skills
  • ✗ Laden Sie keine Skills aus unbekannten Quellen herunter und führen Sie diese nicht aus

2. Skill-Inhalte überprüfen ​

Bevor Sie einen neuen Skill laden, überprüfen Sie schnell die SKILL.md und die Skriptdateien:

bash
# Skill-Beschreibung und Metadaten anzeigen
cat .opencode/skills/skill-name/SKILL.md

# Skriptinhalte überprüfen
cat .opencode/skills/skill-name/scripts/*.sh

Besonders beachten:

  • Ob Skripte auf sensible Systempfade zugreifen (/etc, ~/.ssh)
  • Ob Skripte externe Abhängigkeiten installieren
  • Ob Skripte Systemkonfigurationen ändern

3. Skriptberechtigungen korrekt setzen ​

Nur Dateien, die explizit ausgeführt werden müssen, sollten Ausführungsberechtigungen erhalten:

bash
# Korrekt: Ausführungsberechtigung für Skript hinzufügen
chmod +x .opencode/skills/my-skill/tools/deploy.sh

# Korrekt: Dokumente behalten Standardberechtigungen (nicht ausführbar)
# README.md, config.json usw. müssen nicht ausgeführt werden

4. Sensible Dateien verbergen ​

Skill-Verzeichnisse sollten keine sensiblen Informationen enthalten:

  • ✗ .env-Dateien (API-Schlüssel)
  • ✗ .pem-Dateien (private Schlüssel)
  • ✗ credentials.json (Anmeldeinformationen)
  • ✓ Verwenden Sie Umgebungsvariablen oder externe Konfigurationen für sensible Daten

5. Projekt-Level-Skills überschreiben Benutzer-Level-Skills ​

Skill-Erkennungspriorität (src/skills.ts:241-246):

  1. .opencode/skills/ (Projekt-Level)
  2. .claude/skills/ (Projekt-Level, Claude)
  3. ~/.config/opencode/skills/ (Benutzer-Level)
  4. ~/.claude/skills/ (Benutzer-Level, Claude)
  5. ~/.claude/plugins/cache/ (Plugin-Cache)
  6. ~/.claude/plugins/marketplaces/ (Plugin-Marktplatz)

Best Practices:

  • Projektspezifische Skills in .opencode/skills/ ablegen, überschreiben automatisch gleichnamige Benutzer-Level-Skills
  • Generische Skills in ~/.config/opencode/skills/ ablegen, für alle Projekte verfügbar
  • Globale Installation von Skills aus nicht vertrauenswürdigen Quellen wird nicht empfohlen

Zusammenfassung dieser Lektion ​

Das OpenCode Agent Skills Plugin verfügt über mehrere Sicherheitsebenen:

SicherheitsmechanismusSchutzzielCode-Position
PfadsicherheitsprüfungDirectory Traversal verhindern, Dateizugriffsbereich einschränkenutils.ts:130-133
Sichere YAML-AnalyseBöswilliges YAML an der Codeausführung hindernutils.ts:41-49
Zod-Schema-ValidierungSicherstellen, dass Skill-Frontmatter der Spezifikation entsprichtskills.ts:105-114
Skript-AusführbarkeitsprüfungNur Dateien ausführen, die vom Benutzer explizit als ausführbar markiert wurdenskills.ts:86
Verzeichnis-ÜberspringlogikVermeiden des Scannens versteckter Verzeichnisse und Abhängigkeitsverzeichnisseskills.ts:61, 70

Denken Sie daran: Sicherheit ist eine gemeinsame Verantwortung. Das Plugin bietet Schutzmechanismen, aber die endgültige Entscheidung liegt bei Ihnen – verwenden Sie nur Skills aus vertrauenswürdigen Quellen und gewöhnen Sie sich an, Code zu überprüfen.

Vorschau auf die nächste Lektion ​

In der nächsten Lektion lernen wir Best Practices für die Skill-Entwicklung.

Sie werden sehen:

  • Namenskonventionen und Beschreibungsschreibtechniken
  • Verzeichnisorganisation und Skriptverwendung
  • Frontmatter-Best Practices
  • Methoden zur Vermeidung häufiger Fehler

Anhang: Quellcode-Referenz ​

Klicken zum Aufklappen der Quellcode-Positionen

Letzte Aktualisierung: 2026-01-24

SicherheitsmechanismusDateipfadZeilennummer
Pfadsicherheitsprüfungsrc/utils.ts130-133
Sichere YAML-Analysesrc/utils.ts41-56
Zod-Schema-Validierungsrc/skills.ts105-114
Skript-Ausführbarkeitsprüfungsrc/skills.ts86
Verzeichnis-Überspringlogiksrc/skills.ts61, 70
Pfadsicherheit in Toolssrc/tools.ts101-103

Wichtige Funktionen:

  • isPathSafe(basePath, requestedPath): Validiert, ob ein Pfad sicher ist, verhindert Directory Traversal
  • parseYamlFrontmatter(text): Parst YAML sicher, verwendet Core-Schema und Rekursionsbegrenzung
  • SkillFrontmatterSchema: Zod-Schema, validiert Skill-Frontmatter-Felder
  • findScripts(skillPath, maxDepth): Rekursiv nach ausführbaren Skripten suchen, überspringt versteckte und Abhängigkeitsverzeichnisse

Wichtige Konstanten:

  • maxAliasCount: 100: Maximale Anzahl von Aliasen beim YAML-Parsing, verhindert DoS-Angriffe
  • maxDepth: 10: Maximale Rekursionstiefe bei der Skripterkennung
  • 0o111: Ausführungsbit-Maske (prüft, ob eine Datei ausführbar ist)