SQL injekcijas (3). Aizsardzība.

Autors: alijs  (alijs (at) navigator.lv)
Kategorija: Drošība

Ieteikt draugiem


Iepriekšējie saistītie raksti:
SQL injekcijas (1). Caurums drošībā.
SQL injekcijas (2). Iespējamais uzbrukums.

Iepriekšējos rakstos redzējām, cik nopietnas problēmas var sagādāt SQL injekcijas. Tomēr pret tām ir iespējams aizsargāties. Ja kods būs uzrakstīts pareizi, tad datu bāze no šāda veida uzbrukumiem būs pasargāta. Lai izprastu galvenos principus, kas jāievēro, rakstot pareizu kodu, paanalizēsim esošo piemēru.

Piemērā tika izmantots SQL vaicājums:

select name from webusers where login='$login' and password='$password'



Uzreiz jāsaka, kas šis nav tas sliktākais piemērs, jo mainīgie vaicājumā ir ielikti pēdiņās. Apskatīsim mazliet savādāku piemēru - mums ir web lapa, kuras saturs ir dinamisks un tiek ņemts no datu bāzes. Lai noteiktu, kādu saturu attēlot, tiek izmantots GET parametrs, kas nododas URL adreses laukā. Piemēram: www.example.lv/page.php?content_id=3

Šajā gadījumā mēs ar SQL vaicājumu iegūstam lapas saturu "content" no datu bāzes:

select content from contents_table where content_id=$_GET['content_id']



Zinot, ka satura ID ir tips number, programmētāji bieži vien nelieto pēdiņas SQL vaicājumā. Kas pēc SQL sintakses ir atļauts un parastā gadījumā arī strādās korekti. Tomēr nevajag aizmirst, ka arī URL adresē ir iespējams cipara vietā nodot jebkādu simbolu virkni, un līdz ar to pastāv SQL injekciju bīstamība. Turklāt bez pēdiņu izmantošanas sastādīt "slikto" vaicājumu ir daudz vienkāršāk. Piemērs: www.example.lv/page.php?content_id=1; delete from contents_table; Šajā gadījumā tiks izpildīti divi vaicājumi, turklāt otrais nodzēsīs visus datus no tabulas contents_table. Diez vai tas būtu vēlams...

Tāpēc ieteikums Nr. 1 - izmantojot SQL vaicājumos PHP mainīgos, jāliek tos pēdiņās. MySQL pieļauj gan vienkāršās ('), gan dubultās (") pēdiņas. Var izmantot vienas vai otras.

Tomēr kā redzējām iepriekšējos piemēros, tad pēdiņu izmantošana nepaglāba no SQL injekcijām. Kāpēc? Tādēļ, ka mainīgie arī varēja saturēt pēdiņas un līdz ar to bija iespējams modificēt SQL vaicājumu pēc saviem ieskatiem. Ja mēs nodrošināsim, ka mainīgie pēdiņas saturēt nedrīkstēs, tad šāda iespēja zudīs. Jo viss, kas tiks ievadīts, atradīsies starp divām pēdiņām un līdz ar to tiks uzskatīts par vienkāršu simbolu virkni, nevis vaicājuma daļu.

Ieteikums Nr. 2 - nodrošinām, ka vaicājumos izmantotie mainīgie nesaturēs pēdiņas. Ir vairāki veidi, kā to panākt:

  • izmantot str_replace() PHP f-ju, lai aizvietotu pēdiņas ar citiem simboliem;
  • izmantot htmlspecialchars() PHP f-ju, lai aizvietotu bīstamos simbolus ar citiem - šis bieži vien ir ieteicamais variants, jo aizvieto arī citus "nepatīkamus" simbolus.

    Principā, ja ir ievēroti 2 iepriekš minētie nosacījumi, tad mēs jau varam justies diezgan droši. Vismaz attiecībā uz SQL injekcijām. Jo, lai kādas vērtības arī tiktu ievadītas, SQL vaicājumā tās atradīsies starp divām mūsu pēdiņām un tiks izmantotas kā parasts teksts.

    Tomēr "pareizi" rakstot kodu, būtu jāievēro vēl vairākas lietas:

    ievadīto datu validācija. Ja lauks ir paredzēts telefona numura ievadei, tad nav iemesla ļaut tur ievadīt burtus. Tāpat reālā vārdā vai uzvārdā diez vai parādīsies cipari. Tāpēc ievadītās vērtības ir jāpārbauda, piemēram, ar regulārajām izteiksmēm, pirms tās tiek izmantotas. Jāatceras, ka pārbaudes nepieciešamas arī tādiem laukiem, kurus lietotājs normālā situācijā nevar ievadīt, piemēram, hidden vai checkbox formas laukiem. Arī to vērtības ir iespējams izmainīt, tāpēc arī tās ir jāpārbauda.

    jāuzmanās ar simbolu slash (slīpsvītra) ievadītajos datos, jo tas ir speciālais simbols un to var izmantot, piemēram, lai uzrakstītu speciālos simbolus, kas apzīmē, piemēram, rindas beigas vai pārnešanu jaunā rindā.

    jāierobežo tiesības datu bāzes lietotājam, kurš tiek izmantot, slēdzoties no PHP koda. Tas ļaus izvairīties no DELETE un DROP konstrukcijām. Vairumā gadījumu šim lietotājam pietiks ar SELECT tiesībām.

    jāatceras, ka šis nav vienīgais iespējamais uzbrukuma veids web lapai, tādēļ jāpadomā arī par cita veida drošību.

    Veiksmīgi!



    Komentāri

    Grifs, 2010-04-20 00:29:49

    Vel var izmantot šadu funkciju mysql_real_escape_string(); atkrit ķepa ar str_replace(); cik nu testeju 99% uzhakot nesanaca caur šo funkciju DB! :)


    alijs, 2010-04-20 19:36:49

    Nu jā, varianti jau ir vairāki... savā ziņā gaumes lieta, ko lietot. Galvenais, lai būtu droši.

    Ja par 99% nesanāca uzhakot, tad par 1% sanāca? :) Kādā veidā?


    Grifs, 2010-04-20 22:42:58

    1% pate ka viss nav 100% droš un nekad nebus! :) (ka jau tu ari esi minejis) :)


    a.s.y., 2010-04-21 10:44:15

    Jap, 100% drošs nekad nevari būt... bet tomēr SQL injekcijas ir no tām lietām pret ko var nodrošināties gandrīz pilnīgi 100%. Nu vismaz 99.9999%

    Principā, ja kods ir drošs, tad injekcijas nebūs iespējamas. Protams, vienmēr var atrast kādu citu vājo vietu (piem. caurumus operētājsistēmā vai citos softos), bet vismaz par klasiskām SQL injekcijām nebūs jāsatraucas.


    Grifs, 2010-04-21 12:35:37

    Ta gan! :)

    Lai pievienotu komentāru, autorizējies!

  •  
    Par mums | Sadarbība | Noteikumi | Kontakti | Lapas karte © mycompany.lv 2008 - 2010