Andrei Posted August 22, 2011 Report Posted August 22, 2011 SYDO este o jucarie la care am inceput sa lucrez de foarte putina vreme. Scopul acesteia este de a veni ca un layer deasupra interfetelor SQL prin niste clase special construite care sa administreze, sa extraga, sa stocheze si sa proceseze datele din bazele de date intr-o maniera sigura. Solutia propusa de mine ataca neincrederea ce o avem in providerii de hosting, precum si atacurile bazate pe SQLI. Vrem sa stocam datele noastre intr-un mod criptat? Sa le procesam si sa fie disponibile doar atunci cand avem nevoie? Nicio problema, SYDO ar fi solutia.Cum lucreaza?Exista un API ce comunica cu SYDO Hash Center, un server aflat la distanta ce stocheaza cheile de criptare a datelor alaturi de un hash. Clientul face request pentru hash-ul x si primeste cheia de decriptare a tabelului, bazei de date, a unei coloane sau chiar a unui singur row.Ce vreau sa fac la ea?- suport pentru diverse interfete SQL- suport pentru encriptarea tabelelor, bazelor de date (ajung chiar si la partea hardcore de encriptare a numelor si coloanelor tabelelor)- suport pentru statistici per client (requesturi facute, ce a cerut, cat a cerut, bla bla)- SYDO Hash Center va suporta mai multe website-uri - un cache bine pus la punct pentru a limita la maxim numarul de requesturi- comunicatii client-server encriptate- ma gandesc si la o varianta a serverului P2P - posibilitatea de autentificare/encriptie PGP- comunicarea folosind un RESTful API- ma gandesc sa lucrez la un sistem ce "intelege" interogarile facute (la inceput pentru MySQL) si care gaseste tot ce are nevoie pentru a cripta/decripta - Anti-DOS for SYDO Hash Center- intelegerea query-urilor va incerca sa faca sabloane de interogari astfel ca in momentul in care voi detecta anomalii ale query-urilor sa nu-ti permita sa decripteze datele (Anti-SQLI)Aplicatia se afla in versiunea 0.1 Alpha dar am ganduri mari cu ea. Urmaresc sa o simplific si sa o optimizez ca sa devina aproape nativ de folosit si de integrat in proiecte noi sau existente. Aplicatia va fi Open Source si poate fi gasita pe GitHub aici. 1 Quote
gigaevil Posted August 22, 2011 Report Posted August 22, 2011 - ma gandesc sa lucrez la un sistem ce "intelege" interogarile facute (la inceput pentru MySQL) si care gaseste tot ce are nevoie pentru a cripta/decripta Ai putea face usor ce permite recunoasterea blind sql injectionOricum iti doresc mult success! Quote
Andrei Posted August 22, 2011 Author Report Posted August 22, 2011 Pai nu ma intereseaza tipul de SQLI, cred ca nu am fost pe aceeasi lungime de unda.Ideea e in felul urmator.Avem urmatorul query : SELECT * FROM x WHERE y=1 (1 primit prin GET).El dupa cateva query-uri vede ca trebuie sa primeasca doar int-uri pe y iar cand observa ca vine ceva de genu in request : SELECT * FROM WHERE y=1 AND 1=1 deja se schimba treaba si nu-i mai decripteaza query-ul ci i-l da normal (adica encrypted). Quote
anon Posted August 22, 2011 Report Posted August 22, 2011 El dupa cateva query-uri vede ca trebuie sa primeasca doar int-uri pe y iar cand observa ca vine ceva de genu in request : SELECT * FROM WHERE y=1 AND 1=1 deja se schimba treaba si nu-i mai decripteaza query-ul ci i-l da normal (adica encrypted).Poate ca mi se pare mie, dar cred ca te complici prea mult, sigur trebuie sa fie o metoda mai simpla pentru asta. Bafta oricum:P Quote
Andrei Posted August 22, 2011 Author Report Posted August 22, 2011 (edited) @Anon, nu ma complic pentru ca eu privesc treaba asta pe mai multe niveluri la care poti interactiona cu datele :1. Pre-procesare (client side)2. Procesare low level (direct din firewall, din aplicatii si module integrate in serviciul in cauza)3. Procesare mediul level(aici interactiunea cu datele este controlata de server-side si se pot aduce "patch-uri" asupra unor functii, requesturi, query-uri, date)4. Procesare high level (aici interactiunea este facuta doar cu functiile aferente treburilor respective).Pe mine ma intereseaza sa ma interpun intre 3 si 4 cu ceva generalizat, controlabil pe cat mai multe aplicatii web facute in PHP fara a fi nevoie de prea multa bataie de cap. Pleci de la premiza ca oricat ai securiza input-urile, unele mai scapa si asa ai un alt strat, 3.5 care dupa ce le-ai procesat tu, interactioneaza cu ele, le intelege si apoi apeleaza level 4. LE: Problema nu-i dificila, devine dificila generalizarea ei. LE2: Mai mult, gandeste-te ca un shared hosting nu poate interactiona cu level 2 ca sa puna mai multe protectii suplimentare si poate nu stie sa-si satinizeze input-urile daca e un CMS public. Edited August 22, 2011 by Andrei Quote
redox Posted August 22, 2011 Report Posted August 22, 2011 Poate ar merge altfel (zic si eu) in sensul in care in sql ai select (campuri) from (tabels) where (conditie) group by (campuri) order by (campuri). Pt a preveni sqli ai putea "separa" comanda si analiza de ex (conditie) dupa "anomalii", sa nu permiti de ex decat a-z, 0-9 si '; daca ai alte cuvinte cheie intre where si group by sau order by eventual poti interpreta ca o incercare de sqliOricum, nice job Quote
Andrei Posted August 22, 2011 Author Report Posted August 22, 2011 Pai aia e ideea, toate datele ce le trimitem noi prin input-uri pastreaza predominant un anumit sablon : trimitem int-uri, trimitem dump text (comentarii), trimite-mi comentarii prin taguri.Eh, toate astea sunt sabloane care daca reuseste sa le inteleaga isi poate da seama cand intervine anomalia (suspiciunea de sqli).Legat de propunerea ta gandeste-te ca un SELECT poate fi muuult muuult mai complex de atat. Pentru inceput ma gandesc sa fac suportul pentru functiile clasice de SELECT, INSERT, UPDATE si DELETE si apoi pentru double queries etc. Mersi de comentariu. Quote
pyth0n3 Posted August 22, 2011 Report Posted August 22, 2011 Pai nu ma intereseaza tipul de SQLI, cred ca nu am fost pe aceeasi lungime de unda.Ideea e in felul urmator.Avem urmatorul query : SELECT * FROM x WHERE y=1 (1 primit prin GET).El dupa cateva query-uri vede ca trebuie sa primeasca doar int-uri pe y iar cand observa ca vine ceva de genu in request : SELECT * FROM WHERE y=1 AND 1=1 deja se schimba treaba si nu-i mai decripteaza query-ul ci i-l da normal (adica encrypted).Dar daca face cut la bucatile in plus si recreaza un nou query sanitized nu ar fi mai bine ?Ma refer la faptul ca are totusi rost sa faca un query in database daca sintaxa e criptata ? ar putea sa extraga doar o sintaxa curata din query sau sa o formuleze in baza sintaxei primite.O chestie interesanta pe care am vazut-o in Sqlalchemy SQLAlchemy Documentation — SQLAlchemy 0.7 Documentation care bineinteles e cu totul altceva si nu se refera la PHP dar ar putea fi o idee.Citez din documentation:"If you have any "special" characters (such as semicolons or apostrophes) in your data, they will be automatically quoted for you by the SQLEngine object, so you don't have to worry about quoting. This also means that unless you deliberately bypass SQLAlchemy's quoting mechanisms, SQL-injection attacks are basically impossible.""The ins object automatically generates the correct SQL to insert the values specified. It is to be noted that SQLAlchemy handles any type conversion of the values specified to insert() using its type system, thus removing any chance of SQL injection attacks." Quote
Andrei Posted August 22, 2011 Author Report Posted August 22, 2011 (edited) @pyth0n3 Corect, dar asta inseamna ca te confrunti cu un "client" ce stie programare. Mai rar norocul asta. Pai sintaxa nu e criptata, datele din baza de date sunt criptate.Legat de sugestia ta, am o clasa similara cu SQLAlchemy facuta pentru PHP. Se comporta destul de bine. Edited August 22, 2011 by Andrei Quote
kNigHt Posted August 23, 2011 Report Posted August 23, 2011 @Andrei ideea mi se pare foarte buna, dar nu sunt lamurit in privinta catorva aspecte:1. Viteza client-serverPresupunem ca la o executie script-ul meu are 10 selecturi. Asta inseamna 10 api request-uri catre serverul tau. Chiar si in cele mai bune conditii, aceste request-uri vor dura peste 100 de milisecunde, acestea adaugandu-se la timpul final de executie al script-ului, si niciun developer care intretine un site cu trafic mare nu si-ar permite aceasta intarziere.2. SecuritateaVorbeai mai sus de increderea in serviciul de hosting de a avea acces la datele pretioase ale bazei de date, dar in script-ul tau se gasesc toate informatiile necesare pentru a face un request catre serviciul tau pentru cheile de decriptare. Serviciul de host are acces la script-ul tau si poate trimite date de pe ip-ul setat de tine (am vazut ca te bazezi si pe asta). In cazul asta, hostul nu poate avea acces la date?Acum ca o sugestie... ai putea sa folosesti un object relational mapper. Cred ca ti-ar simplifica foarte mult munca odata ce l-ai stapani calumea si ai elimina problema sql injectionului. Mi-a atras atentia Doctrine, trage o privire:http://www.doctrine-project.org/projects/orm Quote
Andrei Posted August 23, 2011 Author Report Posted August 23, 2011 Salut knight si mersi de comentariu.1. Problema asta exista la orice comunica cu API-uri, aici depinde mult de latenta serverelor. Spre exemplu, Akismet pentru Wordpress, comunica permanent cu serverele lor cloud ca sa detecteze spamul. Eu am doua metode de cache, plus o reducere de request-uri in minte : toate actiunile de set, get, delete sunt tinute pe local si isi face flush o singura data pentur toate actualizarile. Asta inseamna ca 1000 de operatii noi de insert se vor face intr-un singur request la final. Apoi, cheile sunt stocate in cache pe partea de client. Pe partea de server vor fi stocate in RAM pentru viteza maxima la read/write (nu cred ca pot scoate cu altceva mai bine).2. Securitatea datelor sta in felul urmator : ai un auth name + un token cu care poti face "interogarile". Astea le poate face doar asupra datelor contului respectiv. Eh, fiecare query are o identitate ce ii permite sa construiasca statistici. Daca un "evil hoster" incearca sa afle niste date el va trebuie sa construiasca niste query-uri noi ce sa le actioneze pe acelasi server cu API-ul SYDO. In clipa respectiva SYDO inregistreaza o noua identitate in baza lui de date si face log-uri asupra lui. Astfel, eu ca user oficial al tokenului respectiv voi putea vedea in stats treaba asta -> s-a facut requestul cutare, de pe serverul cutare, fisierul cutare, linia cutare, bla bla. Mai mult de atat nu poti face. De aia, in fond, se numeste SYDO. Nu poti crea un "firewall" impotriva furtului de date, dar poti ingreuna furtul lor ca in fond asta fac toate uneltele de securitate actuale. (sau aproape). Daca as folosi ORM, ar insemna ca trebuie ca userul sa stie sa integreze ORM-ul. Eu vreau sa pastrez cat mai mult din query-urile lui originale si sa nu-l fortez sa faca modificari. Ideea "perfectionista" ar fi sa am functia SYDO::mysql_query ce sa faca toata treaba celei mysql_query, doar ca in varianta propusa de mine. Mersi de sugestii. Quote
kNigHt Posted August 23, 2011 Report Posted August 23, 2011 @Andrei nu am niciun dubiu ca vei reusi sa scoti un timp foarte mic server-side, si nici ca poti face un sistem foarte eficient de caching. Cu toate astea, request-urile vor fi totusi destul de multe. Ia ca exemplu un site in care zilnic se logheaza, sa spunem, 2000 de oameni. Nu ai cum sa prinzi asta in cache. Sau un magazin online cu foarte multe pagini, fiecare cautand un lucru diferit. Akismet foloseste api-ul doar la postarea unui comentariu, lucru care nu afecteaza prea mult performanta site-ului in sine.Functia mysql_query ar putea fi realizata, in cazul select-urilor, daca se stiu numele coloanelor si in fiecare select ar fi un Primary Key. In cazul insert-urilor, poti folosi un tabel temporar, salva datele plain in acel tabel, apoi sa le copiezi in tabelul cerut. Ma refer aici la query-uri kilometrice, aproape imposibil de implementat in api. Sunt sigur ca te-ai lovit de select-uri, update-uri, left si right joinuri, where in-uri samd toate intr-un singur query.Dupa parerea mea ideea e grozava, si daca poti minimiza cat mai mult timpul client-server ar putea iesi ceva big, keep on the good job Quote
Andrei Posted August 24, 2011 Author Report Posted August 24, 2011 Ai foarte mare dreptate - nu ai cum sa garantezi acea latenta mica la nspe mii de requesturi. De aceea o parte din treaba ii va ramane si celui care integreaza unealta. Spre exemplu, Hash Table Center fiind Open Source tu ai putea sa-l integrezi in propriul DataCenter, pe un server separat iar latenta va fi aproape insesizabila. La interogari va fi cea mai tricky faza mai ales ca AES e suportat de MySQL inline de exemplu doar pe 128 de biti by default. Quote
kNigHt Posted August 24, 2011 Report Posted August 24, 2011 N-ar fi suficienti 128 de biti pentru securitatea datelor?Chiar, ma gandeam acum... cum faci un ORDER BY? Quote