Εκτέλεση εντολής χωρίς σύνθεση κελύφους — DedSec Project
Συνταγή: κλήση υποδιεργασίας με πραγματικά ορίσματα και χρονικό όριο Σενάριο και κριτήρια επιτυχίας Ένα εργαλείο ανάπτυξης μπορεί να χρειάζεται να εκτελέσει άλλο εγκατεστημένο πρόγραμμα…
Συνταγή: κλήση υποδιεργασίας με πραγματικά ορίσματα και χρονικό όριο
Σενάριο και κριτήρια επιτυχίας
Ένα εργαλείο ανάπτυξης μπορεί να χρειάζεται να εκτελέσει άλλο εγκατεστημένο πρόγραμμα. Δήλωσε χωριστά το εκτελέσιμο και κάθε όρισμα σε λίστα, πέρασε κείμενο που μοιάζει με εντολή ως κυριολεκτικό όρισμα και όρισε χρονικό όριο. Η δοκιμή χρησιμοποιεί την ίδια έκδοση Python ως παιδική διεργασία και ελέγχει ότι ειδικοί χαρακτήρες του κελύφους εμφανίζονται αμετάβλητοι αντί να ερμηνεύονται ως εντολές.
Πλήρες εκτελέσιμο παράδειγμα
Αποθήκευσε ως 11_Subprocess.py και εκτέλεσε με Python 3 και την ενσωματωμένη βιβλιοθήκη. Δεν απαιτείται διαδίκτυο ή πρόσβαση σε πραγματικά αρχεία σου.
import subprocess, sys
argument="literal; $(echo NOT_EXECUTED) & α"
command=[sys.executable,"-c","import sys; print(sys.argv[1])",argument]
result=subprocess.run(command,check=True,text=True,capture_output=True,timeout=3)
assert result.stdout.strip()==argument
assert result.returncode==0
slow=[sys.executable,"-c","import time; time.sleep(5)"]
try:
subprocess.run(slow,check=True,capture_output=True,timeout=0.1)
except subprocess.TimeoutExpired:
pass
else:
raise AssertionError("timeout not enforced")
print("PASS literal argv and bounded child process")
Τεχνική εξήγηση
Με την προεπιλογή shell=False, η subprocess.run περνά λίστα ορισμάτων στο εκτελέσιμο αντί να συνθέτει εντολή κελύφους. Οι χαρακτήρες ;, $() και & μένουν μέρος του ίδιου ορίσματος. Η check=True προκαλεί CalledProcessError για μη μηδενικό κωδικό εξόδου, ενώ TimeoutExpired δείχνει ότι ξεπεράστηκε το επιτρεπτό χρονικό όριο. Η σωστή χρήση ορισμάτων δεν αποδεικνύει ότι το εκτελέσιμο είναι αξιόπιστο· έλεγξε πηγή, δικαιώματα και αναμενόμενες λειτουργίες.
Περιορισμένες ασκήσεις
Πρόσθεσε όρισμα με κενά, εισαγωγικά και emoji και δες τη λίστα argv του παιδιού. Όρισε σκόπιμο κωδικό εξόδου 7 και χειρίσου CalledProcessError. Πρόσθεσε όριο εξόδου αν καλείς μη έμπιστο πρόγραμμα, γιατί η capture_output μπορεί να δεσμεύσει μεγάλη μνήμη. Μην επιτρέπεις στον χρήστη να επιλέγει ανεξέλεγκτα τη διαδρομή του εκτελέσιμου.
Διάγνωση και ασφάλεια
Αν τα ορίσματα χωρίζονται λανθασμένα, έλεγξε μήπως προστέθηκε shell=True ή δημιουργήθηκε χειροκίνητα συμβολοσειρά εντολής. Σε TimeoutExpired αναφέρουμε καθαρή αποτυχία αντί για ατέρμονες επαναλήψεις. Τα Windows διαφέρουν από POSIX στη δημιουργία διεργασιών, γι' αυτό χρειάζεται δοκιμή σε κάθε στοχευμένη πλατφόρμα.