Η έξοδος του μοντέλου σας είναι μη έμπιστη είσοδος. Βρείτε πού το ξεχνά ο κώδικάς σας.
Στατική ανάλυση του κώδικα γύρω από το LLM σας — του κώδικα που χτίζει το prompt, καλεί το μοντέλο και κάνει κάτι με την απάντηση. Όχι του μοντέλου. Όχι της αντοχής του prompt σε ένα jailbreak. Του κώδικα.
Το δωρεάν πρόγραμμα καλύπτει 3 έργα και 30 αναλύσεις τον μήνα, χωρίς όριο στον αριθμό χρηστών και χωρίς πιστωτική κάρτα. Αυτή η ανάλυση χωράει μέσα του.
Το πρόβλημα
Ένα μοντέλο δεν είναι βιβλιοθήκη. Είναι ένας μη έμπιστος διερμηνέας: του δίνετε μια συμβολοσειρά και σας επιστρέφει μία. Ό,τι επηρέασε εκείνη τη συμβολοσειρά — το ίδιο το prompt του χρήστη, μια σελίδα που του δείχτηκε, ένα έγγραφο που του δόθηκε, το αποτέλεσμα ενός άλλου εργαλείου — επηρέασε και την απάντηση.
Η απάντηση είναι αβλαβής μέχρι ο κώδικας να της δώσει δυνατότητα να δράσει. Ο κίνδυνος δεν είναι ότι ένα μοντέλο είπε κάτι· είναι ότι ένα πρόγραμμα το πίστεψε. Κάθε σημείο όπου ένα πρόγραμμα μεταχειρίζεται το παραγόμενο κείμενο ως κώδικα, ως εντολή, ως ερώτημα, ως διαδρομή ή ως URL είναι μια ένεση ένα άλμα πιο πέρα — και, σε αντίθεση με το ερώτημα αν ένα prompt μπορεί να παρακαμφθεί με jailbreak, αυτό το άλμα φαίνεται στον πηγαίο κώδικα.
Τι αναζητά το Cybseco
Εκεί όπου η έξοδος του μοντέλου φτάνει σε κάτι που δρα. Αυτές είναι οι κατηγορίες, οι σοβαρότητες και τα αναγνωριστικά CWE της ίδιας της μηχανής.
eval, exec, compile, new Function, pickle.loads, yaml.load — η απάντηση γίνεται πρόγραμμα.os.system, subprocess, child_process.exec, execSync — η απάντηση γίνεται εντολή.execute, raw, createQuery — το text-to-SQL είναι ακριβώς αυτό το μοτίβο, και το DROP TABLE είναι εύλογη συμπλήρωση.open, readFile, shutil.rmtree, unlink — το ../../etc/passwd είναι εξίσου εύλογη συμπλήρωση.requests, httpx, fetch, axios, urlopen — πλαστογράφηση αιτήματος από την πλευρά του διακομιστή, επιλεγμένη από το μοντέλο.Ένα συγκεκριμένο παράδειγμα
Εννέα γραμμές, και ολόκληρο το σχήμα του κινδύνου.
from openai import OpenAI
client = OpenAI()
def run_plan(task: str):
answer = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": task}],
)
exec(answer.choices[0].message.content)client.chat.completions.create(…) — μια κλήση που επιστρέφει έξοδο του μοντέλου. Ο αναλυτής δεσμεύει τη μεταβλητή στην οποία ανατέθηκε, και ακριβώς αυτό του επιτρέπει να ακολουθήσει την τιμή μέσα στη συνάρτηση χωρίς διαδιαδικαστική ανάλυση.answer περιέχει κείμενο που έχει επηρεαστεί από επιτιθέμενο. Ανάμεσα στην κλήση και στον αποδέκτη τίποτα δεν το ελέγχει, δεν το περιορίζει και δεν το αντιστοιχίζει σε ένα σταθερό σύνολο λειτουργιών.exec(…) — το κείμενο γίνεται πρόγραμμα μέσα στην ίδια τη διεργασία της εφαρμογής, με τα διαπιστευτήριά της, το δίκτυό της και το σύστημα αρχείων της.task — άμεσα ή μέσω ενός εγγράφου που δείχτηκε στο μοντέλο — επιλέγει τι θα εκτελεστεί. Αυτό είναι απομακρυσμένη εκτέλεση κώδικα ένα άλμα πιο πέρα.Εκτελεσμένο στην τρέχουσα μηχανή, αυτό το απόσπασμα παράγει ένα εύρημα: llm-output-to-code-execution, CWE-94, σοβαρότητα κρίσιμη, βεβαιότητα υψηλή, στη γραμμή exec. Η βεβαιότητα είναι υψηλή επειδή η μεταβλητή είναι δεσμευμένη σε πραγματική κλήση completion. Ένα όνομα που απλώς μοιάζει με απάντηση μοντέλου — llm_response, reply — αναφέρεται αντ' αυτού με μέτρια βεβαιότητα, επειδή αυτό είναι εικασία και το να ισχυριστούμε το αντίθετο θα ήταν ψέμα για τα στοιχεία.
Τι δεν είναι αυτό
Άλλοι κίνδυνοι ειδικοί για LLM μέσα στον κώδικα
Καθένας τους ενεργοποιήθηκε σε δείγμα πάνω στην τρέχουσα μηχανή πριν γραφτεί εδώ.
api_key, ένας κωδικός, ένα IBAN ή ένας ιατρικός φάκελος τοποθετημένα στο κείμενο που στέλνετε. Αναφέρεται εκεί όπου χτίζεται πραγματικό περιβάλλον prompt, όχι σε κάθε f-string που τυχαίνει να περιέχει κλειδί.PythonREPLTool, ShellTool, διερμηνέας κώδικα, τερματικό. Η παραχώρηση ενός από αυτά μετατρέπει κάθε ερώτημα για ένεση prompt σε ερώτημα για απομακρυσμένη εκτέλεση κώδικα.allow_dangerous_deserialization=True, trust_remote_code=True, dangerouslyAllow… — ένα framework την είχε απενεργοποιήσει επειδή ήταν επισφαλής.BLOCK_NONE, safety_settings=None, moderation=false.hub.pull(…), πρότυπο prompt που φορτώνεται μέσω HTTP. Όποιος ελέγχει εκείνο το άκρο ελέγχει τις οδηγίες.sk-…, sk-ant-…, AIza…, hf_… καταχωρημένα στο αποθετήριο.text-davinci-*, gpt-4-0314, claude-instant — ασθενέστερη ιεραρχία οδηγιών, χωρίς διαχωρισμό του prompt συστήματος.Γιατί να πιστέψετε κάτι από όλα αυτά
Ανεξάρτητο από πάροχο εκ κατασκευής. Ο αναλυτής αναγνωρίζει τη μορφή — κάτι παράγει κείμενο, κάτι το καταναλώνει — και όχι τη γραφή ενός συγκεκριμένου SDK. Κατονομάζει το framework που είδε όταν μπορεί (OpenAI, Anthropic, Google, Azure OpenAI, Mistral, Bedrock, Ollama, LiteLLM, LangChain, LangGraph, LlamaIndex, Semantic Kernel, AutoGen, CrewAI, Hugging Face), ώστε ένα εύρημα να μπορεί να πει από πού προήλθε. Αυτό είναι ετικέτα πάνω στο εύρημα, όχι ενσωμάτωση ανά SDK, και ένα framework που λείπει από τη λίστα αναλύεται ακριβώς με τον ίδιο τρόπο.
Δείτε το Cybseco να συλλογίζεται για ένα πραγματικό σύστημα
Παρακολουθήστε την διαδραστική επίδειξη και έπειτα ζητήστε μια καθοδηγούμενη δοκιμή για την ομάδα σας.