0Pricing
AI Agents · Lektion

Sicherheitsrichtlinien für die Codeausführung

Einschränkung von Berechtigungen, Netzwerkisolierung, Dateisystemlimits und Zeitüberschreitungen.

Sicherheitsrichtlinien für die Codeausführung ist eine kostenlose AI Agents-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Agents-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.

Warum Richtlinien allein nicht ausreichen

Dem LLM zu sagen „greife nicht auf das Netzwerk zu“ ist keine Sicherheitsmaßnahme, sondern nur ein Hinweis. Das LLM könnte die Vorgabe ignorieren, durch einen Jailbreak manipuliert werden oder der generierte Code könnte indirekt gegen die Regel verstoßen.

Reale Sicherheitsrichtlinien müssen auf der Ausführungsebene durchgesetzt werden und nicht nur im Prompt.

Überblick über Capability-Einschränkungen

Capability-Einschränkungen begrenzen auf Betriebssystemebene, was ein in einer Sandbox ausgeführter Prozess tun kann. Linux-Capabilities teilen Root-Berechtigungen in fein abgestufte Berechtigungen auf, die einzeln entfernt werden können.

Alle Capabilities bis auf die unbedingt benötigten zu entfernen, wird als Prinzip der geringsten Berechtigung bezeichnet.

import docker
client = docker.from_env()

# Drop all Linux capabilities
output = client.containers.run(
    'python:3.12-slim',
    'python -c "print(\"safe run\")"',
    cap_drop=['ALL'],
    network_disabled=True,
    mem_limit='256m',
    auto_remove=True
)
print(output.decode())

Schreibzugriffe außerhalb von /tmp blockieren

Verwenden Sie ein schreibgeschütztes Root-Dateisystem und binden Sie nur /tmp mit Schreibzugriff ein. Dadurch wird verhindert, dass der Code Systemdateien verändert oder Daten außerhalb des vorgesehenen temporären Arbeitsbereichs dauerhaft speichert.

import tempfile, docker
client = docker.from_env()

with tempfile.TemporaryDirectory() as tmpdir:
    output = client.containers.run(
        'python:3.12-slim',
        'python -c "open(\"/tmp/ok.txt\",\"w\").write(\"ok\"); print(open(\"/tmp/ok.txt\").read())"',
        read_only=True,
        tmpfs={'/tmp': 'size=64m,mode=1777'},
        network_disabled=True,
        mem_limit='128m',
        auto_remove=True
    )
    print(output.decode())  # 'ok' — /tmp write allowed
    # Writing anywhere else raises ReadOnlyFileSystem

seccomp-Profile: Systemaufrufe filtern

seccomp (Secure Computing Mode) ermöglicht es Ihnen, eine Allowlist zulässiger Systemaufrufe festzulegen. Jeder Systemaufruf, der nicht auf der Liste steht, führt dazu, dass der Prozess mit SIGSYS beendet wird.

Docker liefert ein standardmäßiges seccomp-Profil mit. Sie können ein benutzerdefiniertes JSON-Profil bereitstellen, um die Regeln weiter zu verschärfen.

import json, docker
client = docker.from_env()

# Minimal seccomp profile: only allow read, write, open, close, exit
seccomp_profile = json.dumps({
    'defaultAction': 'SCMP_ACT_ERRNO',
    'architectures': ['SCMP_ARCH_X86_64'],
    'syscalls': [
        {'names': ['read', 'write', 'open', 'openat', 'close',
                   'fstat', 'mmap', 'mprotect', 'munmap', 'brk',
                   'exit', 'exit_group', 'rt_sigaction',
                   'rt_sigprocmask', 'futex'],
         'action': 'SCMP_ACT_ALLOW'}
    ]
})

output = client.containers.run(
    'python:3.12-slim',
    'python -c "print(1+1)"',
    security_opt=[f'seccomp={seccomp_profile}'],
    auto_remove=True
)
print(output.decode())

Ressourcenlimits: CPU, Speicher, Zeit

Drei Ressourcenlimits, die jede Sandbox durchsetzen sollte:

  • Speicher: mem_limit – OOM-Angriffe verhindern
  • CPU: nano_cpus oder cpu_quota – CPU-Erschöpfung verhindern
  • Zeit: Ausführungs-Timeout – Endlosschleifen verhindern
output = client.containers.run(
    'python:3.12-slim',
    'python -c "import time; time.sleep(100)"',
    mem_limit='128m',
    nano_cpus=500_000_000,   # 0.5 CPU
    network_disabled=True,
    auto_remove=True,
    timeout=10               # kill after 10 seconds
)
# Raises ReadTimeout after 10 seconds

Python-Importe auf eine Allowlist setzen

Untersuchen Sie vor der Codeausführung den AST auf Import-Anweisungen. Lehnen Sie jeden Import ab, der nicht auf der Allowlist steht. Dies ist eine zusätzliche Verteidigungsschicht und kein Ersatz für Kontrollen auf Betriebssystemebene, hilft aber dabei, offensichtliche Richtlinienverstöße frühzeitig zu erkennen.

import ast

ALLOWED_IMPORTS = {'math', 'statistics', 'json', 'csv', 'datetime', 'collections', 're'}

def check_imports(code: str) -> list[str]:
    tree = ast.parse(code)
    blocked = []
    for node in ast.walk(tree):
        if isinstance(node, ast.Import):
            for alias in node.names:
                if alias.name.split('.')[0] not in ALLOWED_IMPORTS:
                    blocked.append(alias.name)
        elif isinstance(node, ast.ImportFrom):
            if node.module and node.module.split('.')[0] not in ALLOWED_IMPORTS:
                blocked.append(node.module)
    return blocked

print(check_imports('import socket; print(1)'))   # ['socket']
print(check_imports('import math; print(math.pi)'))  # []

Erkennen gefährlicher Codemuster

Prüfen Sie neben Importen auch auf Muster, die Importbeschränkungen umgehen: __import__, exec(), eval(), compile() sowie open() mit Pfaden außerhalb von /tmp.

import ast

DANGEROUS_CALLS = {'exec', 'eval', 'compile', '__import__', 'breakpoint'}

def check_dangerous_calls(code: str) -> list[str]:
    tree = ast.parse(code)
    found = []
    for node in ast.walk(tree):
        if isinstance(node, ast.Call):
            if isinstance(node.func, ast.Name):
                if node.func.id in DANGEROUS_CALLS:
                    found.append(node.func.id)
            elif isinstance(node.func, ast.Attribute):
                if node.func.attr in DANGEROUS_CALLS:
                    found.append(node.func.attr)
    return found

print(check_dangerous_calls('exec("import os")'))  # ['exec']

Größenlimits für die Ausgabe

Eine außer Kontrolle geratene print-Schleife kann Gigabytes an Ausgabe erzeugen. Begrenzen Sie stdout/stderr auf eine angemessene Größe (z. B. 1 MB) und kürzen Sie die Ausgabe oder beenden Sie den Container, wenn das Limit überschritten wird.

MAX_OUTPUT_BYTES = 1 * 1024 * 1024  # 1 MB

def run_with_output_limit(client, code: str) -> dict:
    container = client.containers.run(
        'python:3.12-slim',
        f'python -c "{code}"',
        mem_limit='256m',
        network_disabled=True,
        detach=True
    )
    try:
        container.wait(timeout=30)
        logs = container.logs(stdout=True, stderr=True)
        if len(logs) > MAX_OUTPUT_BYTES:
            return {'success': False, 'error': 'Output too large'}
        return {'success': True, 'output': logs.decode(errors='replace')}
    finally:
        container.remove(force=True)

if __name__ == '__main__':
    class FakeContainer:
        def wait(self, timeout=30): pass
        def logs(self, stdout=True, stderr=True): return b'Analysis complete: 42 rows processed.'
        def remove(self, force=True): pass
    class FakeContainers:
        def run(self, *args, **kwargs): return FakeContainer()
    class FakeClient:
        containers = FakeContainers()

    result = run_with_output_limit(FakeClient(), 'print(42)')
    print('Success:', result['success'])
    print('Output :', result['output'])

Flag no-new-privileges

Die Sicherheitsoption no-new-privileges verhindert, dass der Prozess über setuid-Binärdateien oder sudo zusätzliche Berechtigungen erlangt. Selbst wenn der Code eine Shell startet, kann er seine Berechtigungen nicht erweitern.

output = client.containers.run(
    'python:3.12-slim',
    'python -c "import os; print(os.getuid())"',
    user='nobody',                              # run as non-root
    security_opt=['no-new-privileges:true'],    # no privilege escalation
    cap_drop=['ALL'],                           # no capabilities
    network_disabled=True,
    mem_limit='128m',
    auto_remove=True
)
print(output.decode())  # numeric UID of 'nobody'

Alle Richtlinien kombinieren

Eine produktionsreife Sandbox kombiniert alle Ebenen: verworfene Betriebssystemfähigkeiten, ein seccomp-Profil, ein schreibgeschütztes Dateisystem, no-new-privileges, deaktiviertes Netzwerk, Ressourcenlimits und eine Zeitüberschreitung. Defense-in-Depth stellt sicher, dass ein Umgehen einer Ebene durch eine andere verhindert wird.

import tempfile, json, docker
client = docker.from_env()

def maximum_security_run(code: str) -> dict:
    with tempfile.TemporaryDirectory() as tmpdir:
        try:
            out = client.containers.run(
                'python:3.12-slim',
                f'python -c "{code}"',
                user='nobody',
                security_opt=['no-new-privileges:true'],
                cap_drop=['ALL'],
                network_disabled=True,
                read_only=True,
                tmpfs={'/tmp': 'size=32m,mode=1777'},
                mem_limit='128m',
                nano_cpus=500_000_000,
                auto_remove=True,
                timeout=15
            )
            return {'success': True, 'output': out.decode()}
        except Exception as e:
            return {'success': False, 'error': str(e)}

Protokollierung von Richtlinienverstößen

Wenn ein Richtlinienverstoß erkannt wird (blockierter Import, gefährlicher Aufruf, Zeitüberschreitung), protokollieren Sie das Ereignis mit der Sitzungs-ID des Agenten, dem Hash des Codeausschnitts und der Art des Verstoßes. Diese Daten fließen in ein Sicherheits-Dashboard ein und helfen dabei, Richtlinien im Laufe der Zeit zu optimieren.

import hashlib, logging, time

logging.basicConfig(level=logging.INFO)
security_logger = logging.getLogger('sandbox.security')

def policy_check_and_run(code: str, session_id: str) -> dict:
    violations = check_imports(code) + check_dangerous_calls(code)
    code_hash = hashlib.sha256(code.encode()).hexdigest()[:16]

    if violations:
        security_logger.warning(
            'POLICY_VIOLATION session=%s hash=%s violations=%s',
            session_id, code_hash, violations
        )
        return {'success': False, 'error': f'Blocked: {violations}'}

    result = maximum_security_run(code)
    security_logger.info(
        'EXEC session=%s hash=%s success=%s',
        session_id, code_hash, result['success']
    )
    return result

Was bewirkt die Einstellung 'defaultAction: SCMP_ACT_ERRNO' im seccomp-Profil?

seccomp-Profile legen fest, welche Systemaufrufe ein Prozess ausführen darf. Das Feld defaultAction bestimmt, was mit Systemaufrufen geschieht, die im Profil nicht ausdrücklich aufgeführt sind.

Zusammenfassung der Sicherheitsrichtlinien

Eine wirksame Absicherung der Codeausführung erfordert mehrere Ebenen: verworfene Linux-Fähigkeiten, seccomp-Filterung von Systemaufrufen, ein schreibgeschütztes Dateisystem mit temporärem Speicherplatz per tmpfs, no-new-privileges, deaktiviertes Netzwerk, Speicher-, CPU- und Zeitlimits sowie eine Importprüfung auf AST-Ebene.

Keine einzelne Ebene ist ausreichend — Defense-in-Depth bedeutet, dass jede Ebene Schwachstellen in den anderen ausgleicht.

Häufig gestellte Fragen

Ist die Lektion „Sicherheitsrichtlinien für die Codeausführung“ kostenlos?

Ja — der vollständige Text von „Sicherheitsrichtlinien für die Codeausführung“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Agents-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Sicherheitsrichtlinien für die Codeausführung“?

Einschränkung von Berechtigungen, Netzwerkisolierung, Dateisystemlimits und Zeitüberschreitungen. Du übst AI Agents mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um AI Agents zu starten?

Keine Vorkenntnisse erforderlich. AI Agents auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Sicherheitsrichtlinien für die Codeausführung“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser AI Agents-Lektion Code schreiben und ausführen?

Ja. Jede AI Agents-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Docker-basierte Agent-Sandboxes
  2. VM-Isolierung für hochsichere Code-Agenten
  3. E2B- und Cloud-Sandbox-Dienste
  4. Sicherheitsrichtlinien für die Codeausführung
← Zurück zu AI Agents