SQL-ΠΈΠ½ΡŠΠ΅ΠΊΡ†ΠΈΠΈ

SQL-ΠΈΠ½ΡŠΠ΅ΠΊΡ†ΠΈΡ β€” Ρ‚Π΅Ρ…Π½ΠΈΠΊΠ°, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ ΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ нСдостатками Π² ΠΊΠΎΠ΄Π΅ прилоТСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° построСниС динамичСских SQL-запросов. Π—Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ доступ ΠΊ ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ Ρ€Π°Π·Π΄Π΅Π»Π°ΠΌ прилоТСния, ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΈΠ· Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…, подмСняСт Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ выполняСт опасныС ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ систСмного уровня Π½Π° ΡƒΠ·Π»Π΅ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…. Π£ΡΠ·Π²ΠΈΠΌΠΎΡΡ‚ΡŒ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚, ΠΊΠΎΠ³Π΄Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½ΠΈΡ€ΡƒΡŽΡ‚ ΠΈΠ»ΠΈ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΠΎΠ»ΠΈΡ€ΡƒΡŽΡ‚ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Π² SQL-запросах.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #1 ΠŸΠΎΡΡ‚Ρ€Π°Π½ΠΈΡ‡Π½Ρ‹ΠΉ Π²Ρ‹Π²ΠΎΠ΄ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° и… созданиС ΡΡƒΠΏΠ΅Ρ€ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² Π‘Π£Π‘Π” PostgreSQL

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ Π²Π²ΠΎΠ΄ интСрполируСтся Π² SQL-запрос, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΡƒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΡƒΡ‡Ρ‘Ρ‚Π½ΡƒΡŽ запись ΡΡƒΠΏΠ΅Ρ€ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ….

<?php

$offset
= $_GET['offset']; // ΠžΡΡ‚ΠΎΡ€ΠΎΠΆΠ½ΠΎ, Π½Π΅Ρ‚ Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ Π²Π²ΠΎΠ΄Π°!
$query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
$result = pg_query($conn, $query);

?>
Π’ стандартном сцСнарии ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ Π½Π°ΠΆΠΈΠΌΠ°ΡŽΡ‚ Π½Π° ссылки Β«Π’ΠΏΠ΅Ρ€Ρ‘Π΄Β» ΠΈ «Назад», Π² URL-адрСсах ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ смСщСниС, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ пСрСмСнная $offset. Π‘ΠΊΡ€ΠΈΠΏΡ‚ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ входящСС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ для ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ $offset β€” число. Однако, Ρ‡Ρ‚ΠΎ Ссли Π²Π·Π»ΠΎΠΌΡ‰ΠΈΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΡƒ Π²Π·Π»ΠΎΠΌΠ°Ρ‚ΡŒ систСму ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ ΠΊ URL-адрСсу ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅:
0;
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
  select 'crack', usesysid, 't','t','crack'
  from pg_shadow where usename='postgres';
--
Если Π±Ρ‹ это ΡΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ, скрипт прСдоставил Π±Ρ‹ Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΡƒ доступ ΡΡƒΠΏΠ΅Ρ€ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 0; записали, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ΅ смСщСниС для исходного запроса ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ запрос.

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅:

Распространённый ΠΏΡ€ΠΈΡ‘ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ заставляСт SQL-парсСр ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡΡ‚Π°Π»ΡŒΠ½ΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ запроса Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°, β€” ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ символов --, которая ΠΈΠ³Ρ€Π°Π΅Ρ‚ Π² SQL Ρ€ΠΎΠ»ΡŒ синтаксиса ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π².

Π•Ρ‰Ρ‘ ΠΎΠ΄ΠΈΠ½ способ Ρ€Π°ΡΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΏΠ°Ρ€ΠΎΠ»ΠΈ ΡƒΡ‡Ρ‘Ρ‚Π½Ρ‹Ρ… записСй Π² Π‘Π” β€” Π°Ρ‚Π°ΠΊΠΎΠ²Π°Ρ‚ΡŒ страницы с Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°ΠΌΠΈ поиска. Π—Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΡƒ трСбуСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Π΅ΡΡ‚ΡŒ Π»ΠΈ Π² запросС ΠΊ сСрвСру ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΏΠ°Π΄ΡƒΡ‚ Π² SQL-запрос ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ. Π­Ρ‚ΠΈ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ Π² Ρ„ΠΎΡ€ΠΌΠ΅ ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ поиска, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ условий WHERE, ORDER BY, LIMIT ΠΈ OFFSET Π² запросС SELECT. Если Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ UNION, Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅Ρ‚ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠΌΡƒ запросу Π΅Ρ‰Ρ‘ ΠΎΠ΄ΠΈΠ½, Ρ‡Ρ‚ΠΎΠ±Ρ‹ вывСсти список ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ ΠΈΠ· ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹. ΠΠ°ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ рСкомСндуСтся Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΏΠ°Ρ€ΠΎΠ»ΠΈ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #2 Π’Ρ‹Π²ΠΎΠ΄ списка статСй… ΠΈ ряда ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ (любой сСрвСр Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…)

<?php

$query
= "SELECT id, name, inserted, size FROM products
WHERE size = '
$size'";
$result = odbc_exec($conn, $query);

?>
Π‘Ρ‚Π°Ρ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ запроса ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΡƒΡŽΡ‚ с Π΄Ρ€ΡƒΠ³ΠΈΠΌ SELECT-запросом, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ раскроСт всС ΠΏΠ°Ρ€ΠΎΠ»ΠΈ:
'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--

Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΠΈ UPDATE ΠΈ INSERT Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΠ΄Π²Π΅Ρ€ΠΆΠ΅Π½Ρ‹ Ρ‚Π°ΠΊΠΈΠΌ Π°Ρ‚Π°ΠΊΠ°ΠΌ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #3 ΠžΡ‚ сброса пароля до… получСния Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΠΉ (любой сСрвСр Π±Π°Π· Π΄Π°Π½Π½Ρ‹Ρ…)

<?php

$query
= "UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';";

?>
Если Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ отправляСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ' or uid like'%admin%' для ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ $uid, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ администратора, ΠΈΠ»ΠΈ просто присваиваСт ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ $pwd Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ hehehe', trusted=100, admin='yes, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΠΈ, Ρ‚ΠΎΠ³Π΄Π° запросы ΠΏΠ΅Ρ€Π΅ΠΏΠ»Π΅Ρ‚Π°ΡŽΡ‚ΡΡ:
<?php

// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ $uid: ' or uid like '%admin%
$query = "UPDATE usertable SET pwd='...' WHERE uid='' or uid like '%admin%';";

// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ $pwd: hehehe', trusted=100, admin='yes
$query = "UPDATE usertable SET pwd='hehehe', trusted=100, admin='yes' WHERE
...;"
;

?>

Π₯отя остаётся ясным, Ρ‡Ρ‚ΠΎ для ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΉ Π°Ρ‚Π°ΠΊΠΈ Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΡƒ Π½ΡƒΠΆΠ½Ρ‹ хотя Π±Ρ‹ частичныС знания ΠΎΠ± Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π΅ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…, эту ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ часто ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ Π»Π΅Π³ΠΊΠΎ. НапримСр, ΠΊΠΎΠ³Π΄Π° ΠΊΠΎΠ΄ β€” Ρ‡Π°ΡΡ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ обСспСчСния ΠΈ Π»Π΅ΠΆΠΈΡ‚ Π² ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠΌ доступС. Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ Ρ‚Π°ΠΊΠΆΠ΅ раскрываСтся ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ, Π΄Π°ΠΆΠ΅ Ссли ΠΊΠΎΠ΄ Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π»ΠΈ, обфусцировали ΠΈΠ»ΠΈ скомпилировали, ΠΈ Π΄Π°ΠΆΠ΅ собствСнным ΠΊΠΎΠ΄ΠΎΠΌ Ρ‡Π΅Ρ€Π΅Π· ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ сообщСний ΠΎΠ± ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ…. Π”Ρ€ΡƒΠ³ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ подстановку Ρ‚ΠΈΠΏΠΈΡ‡Π½Ρ‹Ρ… ΠΈΠΌΡ‘Π½ Ρ‚Π°Π±Π»ΠΈΡ† ΠΈ столбцов: Ρ„ΠΎΡ€ΠΌΠ° Π²Ρ…ΠΎΠ΄Π° Π² систСму, которая ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ users с ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ столбцов id, username ΠΈ password.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #4 Атака Π½Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΡƒΡŽ систСму сСрвСра Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… (MSSQL Server)

Π‘Ρ‚Ρ€Π°ΡˆΠ½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ получСния доступа ΠΊ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌ уровня ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы Π½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… хостах Π±Π°Π· Π΄Π°Π½Π½Ρ‹Ρ….

<?php

$query
= "SELECT * FROM products WHERE id LIKE '%$prod%'";
$result = mssql_query($query);

?>
Если Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ a%' exec master..xp_cmdshell 'net user test testpass /ADD' -- для ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ $prod, Ρ‚ΠΎ пСрСмСнная $query Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π½Π°:
<?php

$query
= "SELECT * FROM products
WHERE id LIKE '%a%'
exec master..xp_cmdshell 'net user test testpass /ADD' --%'"
;
$result = mssql_query($query);

?>
MSSQL Server выполняСт ΠΏΠ°ΠΊΠ΅Ρ‚Π½Ρ‹Π΅ SQL-запросы, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ для добавлСния Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ… Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… ΡƒΡ‡Ρ‘Ρ‚Π½Ρ‹Ρ… записСй. Если Π±Ρ‹ это ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ запустили ΠΎΡ‚ ΠΈΠΌΠ΅Π½ΠΈ супСрадминистратора sa, Π° слуТбу MSSQLSERVER запустили Π±Ρ‹ с достаточными привилСгиями, Ρƒ Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΠ° появилась Π±Ρ‹ учётная запись с доступом ΠΊ локальной машинС.

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅:

Π§Π°ΡΡ‚ΡŒ ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½Ρ‹Ρ… ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² привязана ΠΊ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌΡƒ сСрвСру Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…, Π½ΠΎ это Π½Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΎ нСвозмоТности ΠΏΠΎΡ…ΠΎΠΆΠ΅ΠΉ Π°Ρ‚Π°ΠΊΠΈ Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚Ρ‹. Π‘Π΅Ρ€Π²Π΅Ρ€ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΠ΄Π²Π΅Ρ€ΠΆΠ΅Π½ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌ уязвимостям.

Π—Π°Π±Π°Π²Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, связанных с SQL-ΠΈΠ½ΡŠΠ΅ΠΊΡ†ΠΈΡΠΌΠΈ

Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ любСзно прСдоставил сайт Π²Π΅Π±-комиксов » xkcd

Π’Π΅Ρ…Π½ΠΈΠΊΠΈ Π·Π°Ρ‰ΠΈΡ‚Ρ‹

Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌΡ‹ΠΉ способ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ SQL-ΠΈΠ½ΡŠΠ΅ΠΊΡ†ΠΈΠΉ β€” ΡΠ²ΡΠ·Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½Π½Ρ‹ΠΌΠΈ инструкциями. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… запросов нСдостаточно, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π° 100 ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚ΠΎΠ² ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ внСдрСния SQL-ΠΈΠ½ΡŠΠ΅ΠΊΡ†ΠΈΠΉ, Π½ΠΎ это ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ ΠΈ бСзопасный способ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ SQL-инструкциям. Π›ΠΈΡ‚Π΅Ρ€Π°Π»Ρ‹ динамичСских Π΄Π°Π½Π½Ρ‹Ρ… Π² условиях WHERE, SET ΠΈ VALUES трСбуСтся Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ заполнитСлями. Π‘Π΅Ρ€Π²Π΅Ρ€ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… свяТСт фактичСскиС Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ ΠΎΡ‚ SQL-ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹.

Π‘Π΅Ρ€Π²Π΅Ρ€ примСняСт связываниС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π΄Π°Π½Π½Ρ‹Ρ…. Π”Ρ€ΡƒΠ³ΠΈΠ΅ динамичСскиС части SQL-запроса трСбуСтся ΠΎΡ‚Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎ извСстному списку Ρ€Π°Π·Ρ€Π΅ΡˆΡ‘Π½Π½Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #5 ИзбСганиС SQL-ΠΈΠ½ΡŠΠ΅ΠΊΡ†ΠΈΠΉ срСдствами ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½Π½Ρ‹Ρ… инструкций модуля PDO

<?php

// ДинамичСская Ρ‡Π°ΡΡ‚ΡŒ SQL-запроса провСряСтся Π½Π° соотвСтствиС ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΌ значСниям
$sortingOrder = $_GET['sortingOrder'] === 'DESC' ? 'DESC' : 'ASC';
$productId = $_GET['productId'];

// SQL-запрос подготавливаСтся с Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»Π΅ΠΌ
$stmt = $pdo->prepare("SELECT * FROM products WHERE id LIKE ? ORDER BY price {$sortingOrder}");

// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ пСрСдаётся с подстановочными Π·Π½Π°ΠΊΠ°ΠΌΠΈ LIKE
$stmt->execute(["%{$productId}%"]);

?>

ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½Π½Ρ‹Π΅ инструкции ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ PDO, MySQLi ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π±Π°Π· Π΄Π°Π½Π½Ρ‹Ρ….

Атаки с Π²Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅ΠΌ SQL-ΠΈΠ½ΡŠΠ΅ΠΊΡ†ΠΈΠΉ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ основаны Π½Π° ΠΊΠΎΠ΄Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ написали Π±Π΅Π· ΡƒΡ‡Ρ‘Ρ‚Π° Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ бСзопасности. Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π΄ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Π½ΠΈΠΊΠ°ΠΊΠΈΠΌ Π²Ρ…ΠΎΠ΄Π½Ρ‹ΠΌ Π΄Π°Π½Π½Ρ‹ΠΌ, особСнно со стороны ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Π΄Π°ΠΆΠ΅ Ссли Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ значСния ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‚ ΠΈΠ· HTML-Π±Π»ΠΎΠΊΠ° SELECT, скрытого поля Π²Π²ΠΎΠ΄Π° ΠΈΠ»ΠΈ ΠΈΠ· cookie. ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠΉ простой запрос Π»Π΅Π³ΠΊΠΎ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ катастрофС.

БтратСгия Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠΉ Π·Π°Ρ‰ΠΈΡ‚Ρ‹ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π½Π°Π±ΠΎΡ€ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊ Ρ…ΠΎΡ€ΠΎΡˆΠ΅Π³ΠΎ ΠΊΠΎΠ΄Π°:

  • НС ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΠΉΡ‚Π΅ΡΡŒ ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠ°ΠΊ ΡΡƒΠΏΠ΅Ρ€ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΈΠ»ΠΈ Π²Π»Π°Π΄Π΅Π»Π΅Ρ† Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ с ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ привилСгиями.
  • ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠΉΡ‚Π΅ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Π½Π° соотвСтствиС Ρ‚ΠΈΠΏΡƒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ оТидался. Π’ PHP содСрТится ΠΌΠ½ΠΎΠ³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, ΠΎΡ‚ ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ is_numeric() ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ‚ΠΈΠΏΠ° символов Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ctype_digit() ΠΈ Π΄Π°Π»Π΅Π΅ ΠΊ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ΅ Perl-совмСстимых рСгулярных Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ.
  • Если ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ числовыС Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, рассмотритС ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ ctype_digit(), Π½Π΅Π·Π°ΠΌΠ΅Ρ‚Π½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚Π΅ Ρ‚ΠΈΠΏ Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ settype() ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ числовоС прСдставлСниС Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ sprintf().
  • Если Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… Π½Π΅ поддСрТиваСтся связываниС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, Π²ΠΎΠ·ΡŒΠΌΠΈΡ‚Π΅ Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ΅ нСчисловоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ пСрСдаётся Π² Π‘Π” Ρ‡Π΅Ρ€Π΅Π· Ρ…Π°Ρ€Π°ΠΊΡ‚Π΅Ρ€Π½ΡƒΡŽ для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ экранирования строки: mysql_real_escape_string(), sqlite_escape_string() ΠΈ Ρ‚. Π΄. ΠžΠ±Ρ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ addslashes() ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Ρ… срСдах (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π‘Π£Π‘Π” MySQL Π² ΠΎΠ΄Π½ΠΎΠ±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠΉ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΠ΅ с ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Ρ‘Π½Π½Ρ‹ΠΌ Ρ€Π΅ΠΆΠΈΠΌΠΎΠΌ NO_BACKSLASH_ESCAPES), поэтому ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Π‘Π” Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ.
  • Ни Π² ΠΊΠ°ΠΊΠΎΠΌ случаС Π½Π΅ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚Π΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ Π‘Π”, особСнно ΠΎ структурС. Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ Π΄Π°ΡŽΡ‚ Ρ€Π°Π·Π΄Π΅Π»Ρ‹ «БообщСния ΠΎΠ± ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ…Β» ΠΈ Β«Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΈ логирования ошибок».

ΠšΡ€ΠΎΠΌΠ΅ сказанного, Π²Ρ‹Π³ΠΎΠ΄Ρƒ ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ ΠΎΡ‚ логирования запросов Π»ΠΈΠ±ΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ скрипта, Π»ΠΈΠ±ΠΎ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…, Ссли Π‘Π” ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅. ΠžΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π΅ Π² состоянии ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ Π½Π°Π²Ρ€Π΅Π΄ΠΈΡ‚ΡŒ, Π½ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΠΏΡ€ΠΈ трассировкС прилоТСния, Π·Π°Ρ‰ΠΈΡ‚Ρƒ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ ΠΎΠ±ΠΎΠΉΡ‚ΠΈ. Польза Ρ„Π°ΠΉΠ»Π° ΠΆΡƒΡ€Π½Π°Π»Π° Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π½Π΅ Π² самом Ρ„Π°ΠΉΠ»Π΅, Π° Π² ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ содСрТит Π»ΠΎΠ³. НСдостатку ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Π΅ΡΡ‚ΡŒ ΠΈΠ·Π±Ρ‹Ρ‚ΠΎΡ‡Π½ΠΎΠ΅ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅.

οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 1 note

up
41
Richard dot Corfield at gmail dot com ΒΆ
14 years ago
The best way has got to be parameterised queries. Then it doesn't matter what the user types in the data goes to the database as a value. 

A quick search online shows some possibilities in PHP which is great! Even on this site - http://php.net/manual/en/pdo.prepared-statements.php
which also gives the reasons this is good both for security and performance.