Importanța unui PHP framework bine scris

Spuneam la GeekMeet-ul din octombrie (damn it, iarăși fac referință la el) în timpul prezentării mele, pentru cei absenți, o abordare de la OS până la coder în privința Web Security, despre importanța folosirii unui framework ce să facă în mod implicit filtrare XSS și SQL Injection (SQLi) a input-ului, în biblioteca ce se ocupă de baza de date. Iar pentru chestii riscante, chiar o filtrare XSS cu HTML Purifier, o bibliotecă a cărui filtru XSS a fost creat să treacă de XSS (Cross Site Scripting) Cheat Sheet.

Știu, nu vreau să fac “carieră” din astfel de post-uri pe blog și nu prea cred că o să mă vedeți vreodată să trimit chestii către http://hackersblog.org/. Sunt preocupat de a proteja, de a-i învăța pe alții cum să se protejeze, și mai puțin de a demonstra vulernabilități. Sunt orientat către ce nu ar trebui să facă aplicația și mai puțin înspre a demonstra cum ajungi acolo. De altel aș prefera ca lumea să nu se ia de ‘junk’-ul de WordPress ce rulează pe blog, sunt prea ocupat pentru a scrie un engine sigur cu un număr echivalent de facilități. Mă rog, va urma un contra-exemplu pentru a susține cele din paragraful anterior.

Povestea începe de la faptul că am avut o mică discuție cu necenzurat despre importanța folosirii unui framework, dar el o susținea pe a lui cu alea 10 kile de cod. Doar pentru ce îți trebuie un framework de 1.25 megi (dimensiunea minimă, maxim 1.49) pentru o aplicație banală? Pai în primul rând bune sunt cele de PHP5 folosind OOP și clase cu auto-load. Poți face multiple instalări folosind aceleași surse ale framework-ului exceptând aplicația în sine. Folosești ce încarci. A da, și ai filtrare implicită. De ce? Pentru că nimeni nu este perfect. Greșeli apar și în codul programatorilor ce au trecut de fazele tatonării. Vorbesc din experiența lucrului și mai mult din experiența lucrului în echipă. Dacă tu ca programator nu o dai de gard, se prea poate să dea altul.

Acu recunosc, am trișat puțin. M-am uitat puțin prin cele 10 kile de cod astfel încât buba a fost oarecum imediată. Dar nu imposibil de descoperit cu puțină răbdare și stil având în vedere regulile simple de URL rewrite, destul de evidente, și faptul că era vorba de un singur parametru vulnerabil. De fapt am reușit 3 in 1: XSS, blind SQLi și disclosure în același input.

A da, a folosi mysql_error() în producție este una dintre cele mai proaste idei. XSS-ul și disclosure-ul au fost posibile prin intermediul acestei funcții magice ce ar trebui folosite doar pentru dezvoltare, nu și pentru producție.

Momentan nu dăm poze, așteptăm să aplice patch-ul trimis :).

6 thoughts on “Importanța unui PHP framework bine scris

  1. Adrian Andreias

    De curiziotate, ai incercat Django. Noi ne-am mutat din PHP in Python/Django si ne e bine :).

    Cat despre ditamai frameworkul pentru o aplicatie mica. Care aplicatie mica? 🙂

  2. SaltwaterC Post author

    Era vorba despre giveabeer.com ca aplicație mică din câteva fișiere PHP și ditamai bubua în parametrul nesecurizat. Nu am menționat-o pentru că la ora scrierii articolului site-ul încă nu era securizat.

    Printre altele, piața de Python e destul de mică pe aici pe la Sibiu, dar cel mai probabil va fi următorul limbaj pe care îl voi învăța, implicit voi cocheta cu Django despre care am auzit o târla de chestii. Sunt MVC/HMVC junkie de vreun an. Mă cam atrage și Ruby/RoR/Mongrel+frontend.

    Should I try a fortune cookie?

  3. Adrian Andreias

    Piata de Python e in general mica in Romania si in lume. In Cluj mai stiu o singur firma ce lucreaza pe Django, probabil ca sunt vreo 3-4 in total :).

    Nu cunosc suficient RoR ca sa imi dau cu parerea, e clar ca hype-ul e RoR, ceea ce are parti bune si rele.

    Din filozofie nu mi-a placut Ruby, care am inteles ca vrea sa se apropie de limbajul natural si astfel sunt (prea) multe feluri de a “spune” acelasi lucru, pe cand Python: “There should be one– and preferably only one –obvious way to do it.”
    http://www.python.org/dev/peps/pep-0020/

    Zend probabil e un framework bun din ce am auzit. Dar de ex. comparand Simphony cu Django, Django e cu cateva secole in fata la design/arhitectura.

    Iar dupa ce m-a prins Django, n-am mai insistat pe RoR.

  4. SaltwaterC Post author

    Din acest punct de vedere îți dau dreptate 100%. Sunt orientat spre DRY pentru că am văzut pe propria piele ce înseamnă proiect scris cu picioarele având mult cod redundant sau apropiat ca funcționalitate, dar replicat. Am lucrat din postura de “legacy code maintainer” unde dezvoltarea unui feature îmi lua practic ~20% din timp pe când restul era să lucrez pe lângă cod redundant sau prost scris. Sau chestii ce se dezvoltau redundant deși am repetat în mod absolut stresant chestia asta către echipa de dezvoltare. Chiar am scris un articol despre refactor vs Ctr+C/Ctrl+V în programare.

    În schimb ce m-a atras la RoR și Ruby în general a fost ideea de a scrie “production code at prototyping speed” și faptul că e modelat pe/spre metodologii Agile, chiar dacă la nivel de țară, în echipele de dezvoltatori chestia cu Agile cam pute (sau mi se pare mie). Cel puțin în teorie Agile e bun, în practică oamenii au nevoie de un coach decent pentru a da bâte pe drumul descris anterior. Altfel din încercarea de a “face” spre exemplu SCRUM se alege ce spune numele în limba română neaoșă.

    Nu am încercat Zend Framework, deși am citit destule despre el și e parte a stivei Zend Server Community Edition pe care o folosesc. Ce nu mi-a plăcut la Zend, cel puțin privind din exterior este mai mult aspect de colecție de biblioteci PEAR și mai puțin aspect de framework. Oricum, părți din Zend se integrează bine cu framework-ul ce îl folosesc momentan și anume Kohana. Pornit inițial ca fork de CodeIgniter, a ajuns doar să îi împrumute anumite concepte, în rest s-a orientat spre PHP 5 și alte “design goals”. Buba e că e genul de framework “from coders for coders”. Nu e problemă faptul că e proiect comunitar ci faptul că documentația de cele mai multe ori e codul având în vedere că wiki-ul acoperă doar aspecte de bază, sau e inexistentă, API-ul e consistent doar pe branch-uri minore. Exemplu: de la v2.3 la v2.4 s-a schimbat Database Builder-ul, pe când v3.0 și v3.1 sunt proiecte oarecum separate, diferite din punct de vedere conceptual. Aproximativ diferența dintre Python 2.x și 3.x.

    M-a atras poate și faptul că e destul de elitist, precum este și comunitatea, ceea ce în lumea PHP e destul de dificil având în vedere că orice arici ce știe pune dolarul în fața la variabilă și știe apela 3 funcții se crede și se recomandă programator PHP. În cel mai bun caz e ridicol, în cel mai prost caz iese Joomla sau WordPress. Exagerez puțin, dar nu sunt departe de adevăr având în vedere că extensibilitatea le-a făcut populare și tot extensiile le duc pe râpă.

    Symfony n-a reușit să mă atragă de nici o culoare. Instalat, testat, rm -rf *. În plus, la fel ca și Cake, cel puțin din benchmark-uri este destul de lent.

  5. Adrian Andreias

    Eu sunt fan WordPress, am vazut in articolele tale ca are diverse probleme de securitate. Nu am intrat asa de adanc, incerc doar sa tin la zi versiunile ce le avem instalate. Mi se pare totusi bine scris daca e sa il compar cu phpbb, joomla si alte monstruozitati. Dar nu am mai intrat in codul WordPress din anii timpurii de PHP :).

    Joomla e intr-adevar o chestie in care probabil autorul a invatat sa scrie cod PHP. E oribil gandit.

    Iar despre frameworkuri, vorba aia: orice programator la un moment dat incep sa si-l scrie pe-al lui. E important in schimb sa iti dai seama din timp ca sunt pe planeta oameni mai destepti decat tine si sa mergi cu un framework bun la care dezvolta oameni inteligenti :D. Inca am prieteni pe care incerc sa ii conving s-o lase dracului cu frameworkul lor ca reinveteaza roata. E o tendinta la programatori sa exagereze cu “ce fac eu cu mana mea…”. Eu ma bucur ca am depasit faza aia :D.
    Din nefericire tot ei sunt oamenii carora la un moment dat a trebuit sa le explic ce inseamna SQLi sau mail form injection.
    Binenteles, pentru programatori “maturi” si cu resurse poate fi cea mai buna optiune sa isi faca framework.

    La un framework eu caut sa:
    – sa foloseasca feateruri moderne ale limbajelor cum ar fi reflection, salvand astfel timp (si nefiind necesara chestia de mai jos)
    – sa nu trebuiasca sa scriu xml sau yaml
    (pana aici a picat deja cam tot ce e Java, Simphony sau chestii gen Drupal. Drupal desi nu e framework, e un CMS decent dar din nefericire arhitectura se bazeaza pe WIN32-API-alike in loc de mosteniri etc.)
    – sa pot face hello world in 2-3 minute
    – sa fie modular si flexibil. Adica sa il dau peste cap cand vreu sa customizez x si y din core features, adica sa nu ma forteze la chestii (multe) implicite
    – sa nu exagereze cu OOP si unde nu e cazul
    – sa aiba comunitate decenta
    – sa aiba o separare gen MVC (asta acum exista cam in toate, in Django i-au zis MTV)

    Si Django a iesit castigator :).

    Python mai are avantajul ca e un limbaj serios si vechi care a fost gandit ca limbaj de scop general nu pentru web neaparat si nu duce lipsa de biblioteci in comunitate.
    Daca ne gandim la istoria PHP lucrurile sunt incomparabile :). Dar starea de fata a PHP-ului nu e rea, trecand peste mici incosistente, e un limbaj serios in momentul asta.

    Senzatia ce mi-o da lumea Django e asta: o data ce lucrurile basic sunt rezolvate ai timp tu ca developer (si comunitatea merge in directia asta) sa te ocupi de lucruri serioase gen: unit testing (care e integrat frumos in Django usurandu-ti munca) si testare automata in general, scripturi automate de deployment (vezi fabric), DB schema evolution automatizat (vezi South – in Django e 3rd party, in RoR mi se pare ca e nativ – probabil o sa fie integrat la un moment dat in Django), impachetare si deployment automat cu dependente (vezi pip), izolare mediu/biblioteci pentru fiecare aplicatie instalata pe acelasi server (vezi virtualenv).
    http://clemesha.org/blog/2009/jul/05/modern-python-hacker-tools-virtualenv-fabric-pip/

    Pe scurt tot arsenalul de tool-uri ne permite sa rulam o comanda pe workstation care iti face unit testing si daca nu esueaza se face deployment de Hypanel pe toate serverele ocupandu-se de: modificari pe DB schema (eventual refactor la date in DB daca e cazul, pre-populari etc.), instalat biblioteci/dependinte, restartat apache si ready to go :).

    Cu PHP trebuia sa ne ocupam de tot felul de mizerii, neavand timp de astfel de lucruri “serioase”. Probabil ca astea se fac si sunt posibile si in PHP, e vorba in primul rand de piesa dintre tastatura si scaun.
    Adevarul e ca am evoluat si noi intre timp si Django ne-a oferit cadrul sa o facem.

    Programatori PHP, normal ca sunt 90% moloz pentru ca e foarte jos bariera de intrare. Dar e totusi cel mai folosit limbaj din lume si ai de unde sa gasesti si oameni buni.
    Si cu Python se pot face prostii am vazut pe juniori, pana la urma si Python trebuie tratat serios si cu studiu aprofundat nu doar copy/paste daca vrei sa produci calitate.

  6. SaltwaterC Post author

    Am fost și eu pe acolo cu tentative firave de a-mi face CMS/framework, dar le-am lăsat baltă … nu era prea productiv să reinventez gaura la macaroană. Mi-am scris în schimb propriul “framework” de configurare nginx. Nu sunt prea mare fan de Apache. Cred că o să-l public cândva, trebuie să-l mai periez pentru că este exclusiv în shell scripting și sunt tentat să-l rescriu în Perl.

    În rest, ai descris în bună parte Kohana ca framework, deși nu are încă unit testing integrat (e în curs de rezolvare), schema evolution sau deploy automat. RoR și Django au servit ca inspirație, de fapt a fost apreciat de unii ce l-au folosit după ce au interacționat cu Django. Având în vedere că știu vreo doi Python junkies, cred că o să îi mai stresez cu întrebări – pentru început.

    Cât despre PHP, este ușor ca sintaxă, pentru început, dar în rest pentru a face treabă bună, este nevoie de multă atenție și disciplină, capitol la care mulți dezvoltatori sunt deficitari. De fapt este un limbaj chiar dificil de stăpânit. O spun și statisticile despre web security unde PHP este rege la capitolul probleme. Vorba ‘ceea: with great power comes great responsibility. Iar aici sunt de vină și uneltele folosite în mod implicit pentur că toți încep cu mysql_connect(), $_REQUEST și alte aberații în loc să pornească de la principii, după care să se dea prin cod. De fapt seamănă cu Windows, bariera de început e joasă, pentru securizare trebuie să se depună eforturi substanțiale. De fapt eu n-am știut utiliza Windows decât după vreo 3 ani de Linux de unde am priceput cum stă treaba cu sistemu multi-user, filesystem ACL, etc din moment ce erau servite forțat ca implicite, nu sub formă de utilizator de XP trântit cu furca în S-1-5-32-544 (în limbaj de lemn de Windows aka BUILTIN\ADMINISTRATORS). Iar UAC a fost o încercare faină de a drege busuiocul, eșuată în Vista.

Leave a Reply

Your email address will not be published. Required fields are marked *