Secure programarea Perl

Cum se evită transferul variabilelor utilizator în shell-ul OS atunci când se apelează exec () și system ()?

În Perl, puteți rula programe externe în moduri diferite. Puteți intercepta rezultatele programelor externe folosind cotații înapoi:







Puteți deschide o "țeavă" la program:

deschideți (SORT, "| / usr / bin / sort | / usr / bin / uniq");

Puteți rula programe externe și puteți aștepta finalizarea executării acestora prin intermediul sistemului ():

sistem "/ usr / bin / sortare

sau puteți rula programe externe fără a reveni la control cu ​​exec ():

exec "/ usr / bin / sortare

Toate aceste expresii sunt periculoase dacă folosesc datele introduse de utilizator, care pot conține metacaractere. Pentru sistemele () și exec (), există o caracteristică sintactică care vă permite să executați direct programe externe fără a accesa shell-ul sistemului de operare. Dacă trimiteți argumente la programul extern care nu sunt un șir, ci o listă, atunci Perl nu va utiliza shell-ul, iar metacaractele nu vor provoca efecte secundare nedorite. De exemplu:

Puteți utiliza această funcție pentru a deschide un tunel fără a accesa shell-ul sistemului de operare. Apelarea deschisă în secvența magică a caracterelor | -, executați o copie a Perl și deschideți o țeavă pentru această copie. Copia copilului Perl începe apoi imediat programul extern utilizând lista de argumente pentru exec ().

deschis (SORT, "| -") || exec "/ usr / bin / sortare", $ uservariable;

în timp ce linia $ (@lines)

print SORT $ line, "\ n";

Pentru a citi din tunel fără a accesa shell-ul, puteți folosi o metodă similară, cu secventa - |:

deschis (GREP, "- |") || execuție "/ usr / bin / grep", $ userpattern, $ filename;

tipăriți "potrivire: $ _";

Acestea sunt acele formulare open () pe care ar trebui să le utilizați întotdeauna în cazurile în care într-o altă situație ați folosi redirecționarea deschisă (deschisă).

O caracteristică și mai dificilă vă permite să rulați programe externe și să le înșelați în nume propriu. Acest lucru este util atunci când folosiți programe ale căror acțiuni depind de numele pe care îl execută.

sistem $ real_name "false_name", "argument1", "argument2"

sistemul $ shell "-sh", "- norc"

Acest exemplu pornește shell-ul shell al sistemului de operare cu numele "-sh", care îi obligă să acționeze interactiv. Rețineți că numele real al programului trebuie să fie stocat ca variabilă și că nu există nici o virgulă între numele variabilei și începutul listei de argumente.

Puteți scrie această comandă mai compact:

Ce este "controlul de tentă" în Perl? Cum le pot activa?

După cum am văzut, una dintre cele mai frecvente probleme de securitate cu programarea CGI este transferul variabilelor utilizator în shell-ul OS fără a le verifica. Perl oferă un mecanism de verificare a "infecțiozității", ceea ce nu permite acest lucru. Orice variabilă care este generată de date în afara programului (inclusiv datele din mediu, intrarea standard și linia de comandă) este considerată "contagioasă" și nu poate fi utilizată în afara programului. Infecția se poate răspândi. Dacă utilizați o variabilă infectată pentru a atribui o valoare unei alte variabile, a doua variabilă este, de asemenea, infectată. Variabilele infectate nu pot fi folosite pentru a apela eval (), system (), exec (), sau piped open (). Dacă încercați să faceți acest lucru, Perl nu mai funcționează și afișează un avertisment. De asemenea, Perl refuză să lucreze dacă încercați să apelați un program extern fără a seta explicit variabila PATH.







În versiunea 4 a limbajului Perl, verificarea este activată atunci când se utilizează o versiune specială a interpretului numită "taintperl":

În versiunea 5, folosiți pavilionul -T atunci când rulați interpretul:

Mai jos este descrisă o variabilă "dezinstalați".

Ok, am apelat la cec pentru infecție, așa cum ți-ai recomandat. Acum, scriptul meu nu mai funcționează cu mesajul "Insecure $ ENV la linia XX" de fiecare dată când începe!

Chiar dacă nu aveți încredere în variabila PATH când rulați programe externe, există posibilitatea ca programul extern să facă acest lucru. Prin urmare, ar trebui să includeți întotdeauna o astfel de linie la începutul scriptului dvs., dacă utilizați verificări de tentă:

Editați-l pentru a afișa directoarele în care doriți să căutați. Ideea de a include directorul curent (".") În variabila PATH este o idee proastă.

Cum să "dezinstalați" o variabilă?

Șterg meta-caracterele din variabilă, dar Perl continuă să creadă că este infectat!

Priviți mai sus răspunsul la această întrebare. Singura modalitate de decontaminare a variabilei este folosirea căutării de mască.

Este $ foo =

Deseori sarcina scriptului CGI pe Perl este de a obține o listă de cuvinte cheie de la utilizator și de a le utiliza în operațiile de căutare a mascilor pentru a găsi nume de fișiere potrivite (sau ceva de genul asta). Acest lucru nu este periculos în sine. Optimizare optimă, pe care unele programe Perl le utilizează pentru a accelera căutarea. Când utilizați o variabilă într-o operație de căutare, expresia este compilată de fiecare dată când operația este efectuată. Pentru a evita recompilarea luând timp, puteți utiliza steagul special - o, ceea ce va face ca expresia să fie compilată o singură dată:

Acum, cu toate acestea, Perl va ignora orice modificare a variabilei, ceea ce va duce la funcționarea defectuoasă a acestor bucle:

pentru $ user_pattern (@user_patterns)

tipăriți dacă m / $ user_pattern / o;

Pentru a rezolva această problemă, programatorii care scriu în Perl folosesc adesea acest truc:

pentru $ user_pattern (@user_patterns)

tipăriți dacă m / \ Q $ user_pattern \ E / o;

Scenariul meu CGI necesită privilegii mari decât primește ca utilizator nimeni. Cum pot schimba codul de utilizator?

Puteți forța scriptul să ruleze cu drepturile proprietarului său prin setarea bitului s:

Îți poți acorda drepturile grupului căruia îi aparține proprietarul prin setarea biților în câmpul de grup:

Cu toate acestea, multe sisteme Unix conțin o portiță care permite hacking astfel de scripturi. Acest lucru este valabil numai pentru scripturi, nu pentru programe compilate. În astfel de sisteme, încercarea de a rula un script pe Perl pentru care s-au setat biți s va duce la un mesaj de eroare de la Perl în sine.

La astfel de sisteme, aveți două opțiuni:

Puteți remedia kernelul pentru a împiedica instalarea acestor biți pentru fișierele de script. Cu toate acestea, Perl va identifica corect acești biți și va stabili codul de utilizator. Informații detaliate despre acest lucru pot fi găsite în întrebarea Perl:

Puteți pune scenariul într-un shell încărcat cu C. De obicei, acesta arată astfel:

După compilarea programului, ieșiți biți. Programul va rula cu drepturile proprietarului, va rula interpretul Perl și va executa scriptul conținut în fișierul "foo.pl".

În plus, puteți rula serverul în sine cu drepturi de utilizator care sunt suficiente pentru a efectua acțiunile necesare. Dacă utilizați un server CERN, aveți opțiunea de a rula un server cu drepturi diferite pentru diferite scripturi. Consultați documentația CERN pentru informații suplimentare.







Articole similare

Trimiteți-le prietenilor: