Jump to content
Aerosol

Eliminarea SQL Injections cu ajutorul LINQ

Recommended Posts

Posted

Intoducere

Pe masur? ce numarul vulnerabilit??ilor de securitate ?i a încerc?rilor de a le exploata cresc, programatorilor li se cere s? trateze cu responsabilitate marit? securitatea aplica?iilor pe care le dezvolt?, la rândul lor dezvoltatorii mediilor de programare includ în platformele lor instrumente din ce în ce mai robuste. ?i totu?i to?i dezvoltatorii cad de acord c? cel mai efectiv mod de a proteja aplica?ia ?i de a preveni atacurile rau inten?ionate asupra sa, este de a proiecta ?i a implementa securitate programului din start. Din p?cate, echipelor de dezvoltare, de obicei le lipsesc antrenamentul necesar ?i resursele pentru a lua o decizie satisfacatoare asupra proiect?rii securita?ii aplica?iei.

A?a cum dezvoltatorii sunt cei asupra c?rora cade povara de avea grija de rezisten?a la atacuri a unui program, prima vulnerabilitate a aplica?iilor web despre care înva??, este o form? deosebit de periculoas? a înser?rilor de comenzi: înser?rile SQL( SQL injections). Inser?rile de comenzi sunt un nume generic dat tuturor vulnerabilita?ilor care permit unui atacator s? specifice serverul o comand?, prin introducerea unui input care altereaz? comenzile normal acceptate ?i provoac? aplica?ia web s? se comporte într-un mod nedorit. Pentru c? sunt cele mai cunoscute SQL injection sunt atacurile cele mai frecvente, cele mai periculoase ?i omniprezente. Din fericire acest tip de atac poate fi înl?turat cu u?urin?? în momentul în care se in?elege cu adevarat problema. Din fericire, pentru a veni în întâmpinarea programatorilor, noua tehnologie de acces la baza de date oferit? de Microsoft, propune dezvoltatorilor pe platforma .NET oportunitatea elimin?rii vulnerabilit??ilor de tip SQL injection, atunci când technologia este utilizat? corespunz?tor. Tehnologia este LINQ (Language Integrated Query) ?i este parte integrant? din .NET Framework 3.5.

Vedere de ansamblu

SQL injection este un tip de vulnerabiltate a securita?ii unei aplica?ii web în care un atacator ofer? date mali?ioase programului, provocându-l s? execute pe server comenzi SQL nea?teptate. De?i acest tip de atac este destul de u?or de prevenit, el este pe cât de r?spîndit, pe atât de fatal, pentru c? permite atacatorilor s? execute comenzi nedorite direct pe baza de date cu care se lucreaz?. În cazuri extreme atacatorii pot nu numai s? ob?in? acces la toate informa?iile din baza de date, ci s? o ?i poat? modifica, ?terge sau ad?uga tabele ?i baze de date sau chiar s? capete controlul asupra serverului de baze de date.

Dac? acest tip de atacuri este u?or de prevenit, de ce este atât de periculos? P?i în primul rând, baza de date a unei aplica?ii este o ?int? foarte atractiv? din motive evidente ?i prezint? un interes deosebit pentru atacatori. Un r?u inten?ionat poate detecta ?i exploata cu u?urin?? o aplica?ie web vulnerabil? la acest tip de atacuri. De aceea este evident, c? de?i gre?elile de tratare a SQL injections nu sunt cele mai frecvente din parte dezvoltatorilor, ele sunt cele mai des descoperite ?i exploatate cele mai frecvent.

Un mod u?or de a detecta o vulnerabilitate la atacuri de tip SQL injection este de a insera un meta character intr-o secven?? de caractere despre care se ?tie c? va fi utilizat? pentru a crea o comand? care va incerca s? acceseze baza de date. De exemplu, pe orice site care are un câmp de input, un atacator ar putea introduce un meta caracter, ca de exemplu apostroful (') într-un câmp de cautare, s? dea “Search” pentru a provoca executare comenzii. Dac? aplica?ia întoarce un mesaj de eroare, atacatorul nu numai c? ?tie c? a g?sit o aplica?ie vulnerabil?, dar mai poate impune serverul s? execute ?i alte comenzi mali?ioase. Un expert în probleme de securitate, Michael Sutton, a exemplificat recent u?urin?a cu care se pot descoperi aplica?iile web vulnerabile la SQL injection prin identificarea a sute de siteuri poten?ial vulnerabile în câteva minute, prin utilizarea Google API.

Anatomia SQL injection

Vom incerca, cu ajutorul unui exemplu, s? exemplific?m cât de u?or este s? se fac? gre?elile care pot duce la vulnerabilitatea unei aplica?ii fa?? de atacurile de tip SQL injections ?i cât de u?or pot fi prevenite cu ceva aten?ie atras? proiect?rii ?i program?rii aceluia?i program.

Aplica?ia web aleas? con?ine o pagin? simpl? de cautare a unui client, care este vulnerabil? la SQL injection. Pagina con?ine un textbox CompanyName ?i un datagrid, pentru a afi?a rezultatele ob?inute în urma c?ut?rii prin baza de date oferita de Microsoft ca exemplu: Northwind. Interogarea executat? în timpul caut?rii include o gre?eal? foarte frecvent întâlnit? în proiectarea aplica?iei ?i anume creaz? dinamic o comanda SQL din textul introdus de c?tre utilizator. Aceast? este gre?eala cardinal? în crearea aplica?iei, pentru c?, implicit se are încredere în datele introduse de utilizator ?i sunt trimise direct c?tre baza de date. Interogarea arat? a?a atunci când este ini?iat? de evenimentul ap?s?rii butonului Search:

 protected void btnSearch_Click(object sender, EventArgs e)
{
String cmd = "SELECT [CustomerID], [CompanyName], [ContactName]
FROM [Customers] WHERE CompanyName ='" + txtCompanyName.Text
+ "'";
SqlDataSource1.SelectCommand = cmd;
GridView1.Visible = true;
}

In scenariul prec?utat, dac? utilizatorul introduce de exemplu “Ernst Handel” ca pe numele unei companii, ap?sarea butonului Search, va genera, a?a cum se asteapta, înregistrarile pentru aceasta companie. Dar un atacator ar putea manipula lejer acest mod de crearea dinamic? a interog?rilor, de exemplu prin inserarea unui clauze UNION ?i încheierea secven?ei prin comentarii (--). Cu alte cuvinte, în loc de a introduce “Ernst Handel”, atacatorul introduce:

Ernst Handel' UNION SELECT CustomerID, ShipName, ShipAddress 
FROM ORDERS—

Ca rezultat, comanda SQL ce se execut? pe server adaug? cererea atacatorului ?i o transform? dinamic, s? arate a?a:

SELECT [CustomerID], [CompanyName], 
[ContactName]
FROM [Customers]
WHERE CompanyName ='Ernst Handel'
UNION SELECT CustomerID, ShipName,
ShipAddress
FROM ORDERS--'

Astfel se ob?ine o comand? SQL perfect legal?, care se va executa asupra bazei de date a aplica?iei, returnând to?i consumatorii din tabelul Orders, care au facut comenzi.

Rezultatul se poate vedea în figura al?turat?

Sql_injection.jpg

Metode tipice de evitare SQL injection

Mai sus am observat cât de simplu putem crea ?i exploata vulnerabilit??ile de tip SQL injection într-un program construit prost. Din fericire, a?a cum am men?ionat anterior SQL injections pot fi prevenite u?or urmând câteva m?suri de precau?ie. Cea mai utilizat? ?i mai pu?in costisoare ca timp, este s? se valideze inputul acceptat de la utilizator în mod corespunz?tor, atunci când sunt transformate în comenzi ce o s? acceseze baza de date. Orice date de intrare introduse de c?tre clien?i, fie direct prin în aplica?ia web sau stocate deja, trebuie s? fie validate dupa tipul serverului, lungime sau format, înainte de a trimise mai departe. Din nefericire, aceste m?suri bazate pe codul surs? nu sunt imbatabile ?i pot e?ua atunci când:

Modul de validare nu este definit corespunz?tor.

Validarea se execut? numai la nivelul clientului.

Validarea nu ia în calcul m?car un singur câmp al aplica?iei.

Un nivel în plus de prevenire SQL injections, implic? parametrizarea corect? a tuturor interog?rilor SQL din aplica?ie, fie c? e vorba de comenzi SQL dinamice sau proceduri stocate. De exemplu codul ar fi fost sigur, dac? interog?rile ar fi fost structurate în felul urm?tor:

SELECT [CustomerID], [CompanyName], [ContactName]
FROM [Customers]
WHERE CompanyName = @CompanyName

Interog?rile parametrizate trateaz? datele introduse ca pe ni?te valori facând parte din comenzile SQL, în acest fel facând imposibil ca serverul s? trateze iterog?rile parametrizate ca ?i cod executabil. Chiar dac? se utilizeaz? procedurile stocate, parametrizarea inputului este necesar?, pentru c? procedurile stocate nu ofer? protec?ie împotriva SQL injections peste interog?rile încorporate în procedur?. Chiar ?i cu aceste trat?ri simple, inserarea codului SQL este în continuare o mare problem?. De aceea într-o echip? de programatori educarea fiecarui membru asupra acestor tipuri de vulnerabilit??i, elaborarea standartelor de securitate pentru a a preveni atacurile ?i aplicarea standartelor ?i stabilirea regulii ca s? nu scape nimic valid?rii, este o necesitate. Acesta implic? introducerea multor variabile în efortul pentru securizarea aplica?iei, a?a c? ar fi mai productiv dac? s-ar selecta o tehnologie de acces la baza de date care face SQL injections imposibile. Printre ele se num?r? ?i LINQ.

Vedere general? asupra LINQ

În esen?? LINQ introduce un standard de tratare a tuturor interogarilor ?i opera?iilor de actualizare a datelor, indiferent de tipul de stocare a datelor: baze de date SQL, documente XML, obiecte .NET. atunci cand sunt construite aplica?ii care s? lucreze cu bazele de datate, componenta LINQ care permite programatorilor s? trateze datele rela?ionate ca ?i obiecte C# sau VB, este cunoscut? ca “LINQ to SQL”, care este considerat? ca parte din familia tehnologiilor ADO.NET. Atunci când a fost introdus? ini?ial a purtat numele de DLINQ.

“LINQ to SQL” permite tratarea datelor din aplica?ii ca obiecte native în limbajul folosit, abstractizând complexitatea managementului bazei de date ?i a conexiunilor din baza de date. De fapt, cu ajutorul LINQ, se pot afi?a ?i manipula date din baza de date, f?r? a scrie o singur? comanda SQL. La compilare, “LINQ to SQL” va traduce interog?rile integrate în cod, în SQL ?i le va executa asupra bazei de date. “LINQ to SQL” întoarce rezultatul interog?rii sub form? de obiecte, abstractizând complet interac?iunea cu baza de date ?i SQL. Nu exist? mod mai rapid de elimiare a amenin?arii cu SQL injection, dintr-o aplica?ie, decât a elimina SQL din aplica?ie. Acest lucru se ob?ine cu ajutorul “LINQ to SQL”.

Securizarea accesului la date cu ajutorul LINQ

“LINQ to SQL” atunci când este utilizat exclusiv pentru accesul la date, elimin? orice posibilitate de a se executa SQL injections în aplica?ie, pentru un motiv foarte simplu: orice interogare SQL pe care o executa LINQ este parametrizabil?. Orice date de intrare oferite din partea oric?ror fel de surse este tratat? ca un literal atunci când LINQ construieste comanda SQL din sintaxa interog?rilor integrat?. ?i mai mult, integrarea LINQ în Visual Studio Orcas asist? programatorii în construirea interog?rilor valide, prin tehnica IntelliSense ?i verificarea sintaxei în timpul compil?rii. Compilatorul detecteaz? multe dintre utiliz?rile eronate ale comenzilor, care ar putea produce defecte sau vulnerabilit??i în func?ionarea aplica?iei. În contrast, comenzile SQL scrise de mân? sunt parsate ?i interpretate asupra bazei de date la execu?ie f?r? ca s? ?tii daca sunt corecte sau nu. Singurul mod de a ataca “LINQ to SQL ” este ca un atacator s? încerce s? p?c?leasca LINQ s? creeze comenzi SQL ilegale sau nedorite. Din feiricire, limbajele ?i compilatoarele sunt proiectate ca sa ne fereasc? de asta.

Cu acest lucru stabilit, d?m exemplu în continuare cum se poate implementa exemplu cu cautarea clientului de mai devreme utilizând “LINQ to SQL” pentru a ne proteja de atacuri de tip SQL injection. Primul pas este de crea obiectul model al rela?iilor dintre date în cadrul bazei de date. Visual Studio Orcas are integrat Object Relational Designer( O/R Designer) care permite generarea întregului model pentru baza de date, prin tragerea tabelelor pe suprafa?a de designd ?i definirea rela?iilor. Pentru a crea obiectul model al tabelului Northwind Customers, cre?m un fisier de baze de date “LINQ to SQL” în aplica?ie, prin selectarea “Add New Item..” în cadrul proiectului ?i alegând ?ablonul “LINQ to SQL File”, care deschide O/R Designer. Pentru a construi automat obiectul model complet pentru tabelul Customers, select?m tabelul din Server Explorer ?i îl tragem pe suprafa?a O/R Designer. Dup? aceasta, se adaug? automat un fisier Cusotmer.designer.cs care define?te clasele pe care o sa le utiliz?m, astfel evitând lucrul direct cu baza de date.

Dup? definirea claselor obiectului model pentru informa?ia din tabelul Customers, putem interoga datele direct în codul din pagina de cautare a clien?ilor. Metoda Page_Load pentru pagina generata de LINQ ( LINQtoSQL.aspx.cs), instan?iaz? clasa CustomersDataContext creat? de O/R Designer, utilizând acela?i connection string ca ?i acel utilizat mai inainte. Exemplul de mai jos întoarce o colec?ie de obiecte de tip Customer, care sunt corespunz?toare cu rezultatele ob?inute din executarea interog?rii utilizând clauza WHERE:

 protected void Page_Load(object sender, EventArgs e)
{
string connectionString =
ConfigurationManager.ConnectionStrings
["northwndConnectionString1"].ConnectionString;

CustomersDataContext db = new
CustomersDataContext(connectionString);

GridView1.DataSource =
from customer in db.Customers
where customer.CompanyName ==
txtCompanyName.Text
orderby customer.CompanyName
select customer;

GridView1.DataBind();
}

Utilizând “LINQ to SQL”, dac? oferim ca valoarea c?utat? “Ernst Handel”, comanda SQL generat? ?i executat? de LINQ este:

 
SELECT [t0].[CustomerID], [t0].[CompanyName],
[t0].[ContactName], [t0].[ContactTitle], [t0].[Address],
[t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country],
[t0].[Phone], [t0].[Fax]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[CompanyName] = @p0
ORDER BY [t0].[CompanyName]}

Dup? cum se poate vedea, clauza WHERE este parametrizat? automat, prin aceasta devenind impenetrabil? la atacurile de tip SQL injection. Indiferent de valorile oferite de c?tre un utilizator, pentru c?utare, interogarea este sigur? ?i nu va permite datelor introduse s? fie executate direct de c?tre server. Dac? am introduce spre c?utarea ?irul de caractere utilizat mai inainte pentru a executa un SQL injection, interogarea nu va întoarce nici un rând. De fapt singura daun? pe care un utlizator ar putea s? o aduc? cu aceasta interogare, este s? execute un atac “brute force”, utilizând func?ia de c?utare, pentru a enumera toate înregistr?rile despre companiile din tabel, prin ghicirea tuturor valorilor posibile. Dar chiar ?i aceasta nu face mai mult decât s? ofere date facute publice deja ?i nu ofer? atacatorului posibiltatea s? insereze comenzi care s? ofere unele drepturi în plus pentru tabele sau baze de date.

De la LINQ la securitate

Dup? cum au ar?tat exemplele este foarte simplu s? se introduc? vulnerabilit??i de tip SQL injection în cadrul aplica?iilor web ?i nu este mai greu s? fie reparate. Dar nimic nu protejeaz? apriori programatorii de aceste gre?eli simple ?i în acela?i timp periculoase. Totu?i tehnologia “LINQ to SQL” propus? de Microsoft, elimin? posibilitatea de a executa atacuri de tip SQL injection asupra bazei de datate a unei aplica?ii, prin l?sarea programatorilor s? interac?ioneze direct cu obiectele model generate din datele rela?ionale ?i nu cu baza de date propriu-zis?. Infrastructura LINQ, integrat? în C# ?i Visual Basic, preia sarcina de construire a comenzilor SQL valide, prevenind atacurile de tip SQL injections ?i permi?ând programatorilor s? adopte stilul de programare care le este cel mai aproape. De aceea dac? se alege utilizarea “LINQ to SQL” ca o parte a unei noi aplica?ii .NET sau se alege s? se înlocuisc? cea veche, se face un pas spre aplica?ii mai sigure.

Source

  • Upvote 1
  • Downvote 1

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...