Aller au contenu principal

Sandboxing et limitations de sécurité

Sandboxing et limitations de securite

Code Interpreter execute du code dans un environnement isole et ephemere. Comprendre ses limites de securite est essentiel pour concevoir des applications fiables et eviter les surprises en production.

Architecture du sandbox

Chaque execution de Code Interpreter se fait dans un container isole avec les proprietes suivantes :

  • Isolation reseau : aucun acces internet, aucune requete sortante
  • Systeme de fichiers ephemere : tout est efface apres l’appel
  • Timeout d’execution : le code est interrompu apres un delai limite
  • Ressources controlees : CPU et memoire plafonnes
from openai import OpenAI

client = OpenAI()

# Cette requete echouera : pas d'acces reseau
response = client.responses.create(
    model="gpt-5.3",
    input="Telecharge le contenu de https://example.com avec requests",
    tools=[{"type": "code_interpreter"}]
)

# Le modele expliquera que l'acces reseau n'est pas disponible
print(response.output_text)

Ce qui est disponible

Bibliotheques pre-installees

Le sandbox inclut un ensemble de bibliotheques Python courantes :

# Analyse de donnees
# pandas, numpy, scipy, statsmodels

# Visualisation
# matplotlib, seaborn, plotly

# Traitement d'images
# Pillow (PIL)

# Mathematiques
# sympy, math, statistics

# Formats de fichiers
# openpyxl (Excel), csv, json, xml

# Utilitaires
# datetime, collections, itertools, re, os

Systeme de fichiers

Le code peut lire et ecrire des fichiers dans le container :

# Le modele peut creer des fichiers temporaires
response = client.responses.create(
    model="gpt-5.3",
    input="Cree un fichier CSV avec 100 lignes de donnees de test "
          "(nom, age, ville, salaire) et retourne-le.",
    tools=[{"type": "code_interpreter"}]
)

Ce qui n’est pas disponible

Acces reseau

Aucune connexion entrante ou sortante :

# Impossible :
# - requests.get(), urllib.request
# - socket, http.client
# - pip install (pas de telechargement)
# - Acces a des API externes
# - Envoi d'emails

Persistence entre appels

Chaque appel API cree un nouveau container. Rien ne persiste :

# Premier appel : cree un fichier
response1 = client.responses.create(
    model="gpt-5.3",
    input="Cree une variable x = 42 et sauvegarde-la dans un fichier",
    tools=[{"type": "code_interpreter"}]
)

# Deuxieme appel : le fichier n'existe plus
response2 = client.responses.create(
    model="gpt-5.3",
    input="Lis le fichier cree precedemment",
    tools=[{"type": "code_interpreter"}]
)
# -> Erreur : fichier introuvable

Pour conserver des resultats entre appels, recuperez les fichiers generes et renvoyez-les :

def pipeline_avec_persistence(etapes: list[str]) -> list:
    """Execute des etapes sequentielles en passant les fichiers."""
    fichiers_context = []
    resultats = []

    for etape in etapes:
        content = [{"type": "text", "text": etape}]
        for fid in fichiers_context:
            content.append({"type": "input_file", "file_id": fid})

        response = client.responses.create(
            model="gpt-5.3",
            input=[{"role": "user", "content": content}],
            tools=[{"type": "code_interpreter"}]
        )

        # Recuperer les fichiers generes pour l'etape suivante
        for item in response.output:
            if item.type == "code_interpreter_call":
                for result in item.results:
                    if hasattr(result, "files"):
                        for f in result.files:
                            fichiers_context.append(f.file_id)

        resultats.append(response.output_text)

    return resultats

Execution longue

Le code est interrompu apres environ 5 minutes d’execution :

# Pattern pour les traitements lourds : decouper en etapes
response = client.responses.create(
    model="gpt-5.3",
    input="Traite ce fichier CSV de 500 000 lignes en lots de 50 000. "
          "Pour chaque lot, calcule les statistiques et accumule les resultats.",
    tools=[{"type": "code_interpreter"}],
    instructions="Si le traitement risque d'etre long, decoupe-le en etapes "
                "et affiche la progression."
)

Securite des donnees

Donnees sensibles

Les fichiers que vous envoyez au Code Interpreter sont traites dans le sandbox puis supprimes. Neanmoins, en production :

def analyser_donnees_sensibles(fichier_path: str, colonnes_a_masquer: list[str]):
    """Anonymise les donnees avant envoi au Code Interpreter."""
    import pandas as pd

    # Charger et anonymiser localement
    df = pd.read_csv(fichier_path)
    for col in colonnes_a_masquer:
        if col in df.columns:
            df[col] = df[col].apply(lambda x: hash(str(x)) % 1000000)

    # Sauvegarder la version anonymisee
    fichier_anonyme = "/tmp/donnees_anonymes.csv"
    df.to_csv(fichier_anonyme, index=False)

    # Envoyer la version anonymisee
    with open(fichier_anonyme, "rb") as f:
        fichier = client.files.create(file=f, purpose="assistants")

    response = client.responses.create(
        model="gpt-5.3",
        input=[{
            "role": "user",
            "content": [
                {"type": "text", "text": "Analyse les tendances dans ces donnees"},
                {"type": "input_file", "file_id": fichier.id}
            ]
        }],
        tools=[{"type": "code_interpreter"}]
    )
    return response.output_text

Code malveillant

Le sandbox protege contre les tentatives d’evasion, mais ne validez jamais du code genere cote client sans verification :

# Le sandbox empeche :
# - os.system("rm -rf /")  -> pas de permissions
# - subprocess.call(...)    -> pas de sous-processus dangereux
# - Acces aux variables d'environnement sensibles
# - Escalade de privileges

Gerer les erreurs d’execution

Le code peut echouer dans le sandbox. Le modele tente generalement de corriger :

response = client.responses.create(
    model="gpt-5.3",
    input="Calcule la matrice inverse d'une matrice singuliere [[1,2],[2,4]]",
    tools=[{"type": "code_interpreter"}],
    instructions="Si le code produit une erreur, explique pourquoi "
                "et propose une alternative."
)

# Le modele execute le code, detecte l'erreur LinAlgError,
# puis explique que la matrice est singuliere et propose
# la pseudo-inverse de Moore-Penrose

Bonnes pratiques

# 1. Soyez specifique dans vos instructions
# Mauvais :
input_vague = "Analyse ces donnees"

# Bon :
input_precis = ("Charge ce CSV avec pandas. "
               "Calcule la moyenne, mediane et ecart-type de la colonne 'montant'. "
               "Identifie les valeurs superieures a 3 ecarts-types. "
               "Genere un boxplot.")

# 2. Demandez du code commente
instructions = "Commente chaque etape du code. Affiche les resultats intermediaires."

# 3. Gerez les fichiers volumineux
instructions_lot = ("Si le fichier depasse 100 000 lignes, "
                   "travaille sur un echantillon representatif de 10 000 lignes "
                   "et indique-le dans ta reponse.")

Points cles a retenir

  • Le sandbox est isole : pas de reseau, pas de persistence, timeout limite
  • Les bibliotheques d’analyse et de visualisation sont pre-installees
  • Anonymisez les donnees sensibles avant envoi
  • Passez les fichiers entre appels via l’API files pour simuler la persistence
  • Le modele gere les erreurs d’execution et tente de s’auto-corriger