PHP.mk документација

SQL инјекција

Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.

security.database.sql-injection.php PHP.net прокси Преводот се освежува
Оригинал на PHP.net
Патека security.database.sql-injection.php Локална патека за оваа страница.
Извор php.net/manual/en Оригиналниот HTML се реупотребува и локално се стилизира.
Режим Прокси + превод во позадина Кодовите, табелите и белешките остануваат читливи во истиот тек.
SQL инјекција

Референца за `security.database.sql-injection.php` со подобрена типографија и навигација.

security.database.sql-injection.php

SQL инјекција

SQL инјекција е техника каде напаѓач експлоатира недостатоци во код на апликација одговорен за градење динамички SQL прашања. Напаѓачот може да добие пристап до привилегирани делови од апликацијата, да ги извлече сите информации од базата на податоци, да ги промени постоечките податоци, или дури и да изврши опасни команди на системско ниво на домаќинот на базата на податоци. Уulnerabilност се јавува кога програмерите ги спојуваат или интерполираат произволни влезови во нивните SQL изјави.

Пример #1 Поделување на множеството резултати на страници ... и правење суперкорисници (PostgreSQL)

Во следниот пример, корисничкиот влез е директно интерполиран во SQL прашањето, дозволувајќи му на напаѓачот да добие суперкорисничка сметка во базата на податоци.

<?php

$offset
= $_GET['offset']; // beware, no input validation!
$query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
$result = pg_query($conn, $query);

?>
Нормалните корисници кликаат на линковите 'следно', 'претходно' каде што $offset е кодирано во URL. Скриптата очекува дека дојдовниот $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 and 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 and INSERT изјавите се исто така подложни на такви напади.

Пример #3 Од ресетирање лозинка ... до добивање повеќе привилегии (кој било сервер за бази на податоци)

<?php
$query
= "UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';";
?>
Ако злонамерен корисник ја поднесе вредноста ' or uid like'%admin% to $uid Ако злонамерен корисник ја поднесе вредноста $pwd to 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' -- to $prodАко напаѓачот ја поднесе вредноста $query , тогаш
<?php

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

?>
ќе биде: sa MSSQL Server ги извршува SQL изразите во серијата, вклучувајќи команда за додавање нов корисник во базата на податоци за локални сметки. Ако оваа апликација работеше како

Забелешка:

и услугата MSSQLSERVER работеше со доволно привилегии, напаѓачот сега би имал сметка со која би можел да пристапи до оваа машина.

A funny example of the issues regarding SQL injection

Некои од горенаведените примери се поврзани со специфичен сервер за бази на податоци, но тоа не значи дека сличен напад е невозможен против други производи. Вашиот сервер за бази на податоци може да биде слично ранлив на друг начин. Сликата е со дозвола од

» xkcd

Техники за избегнување WHERE, SETПрепорачаниот начин за избегнување на SQL инјекција е со врзување на сите податоци преку подготвени изрази. Користењето на параметризирани прашања не е доволно за целосно избегнување на SQL инјекција, но тоа е најлесниот и најбезбедниот начин за обезбедување влез во SQL изразите. Сите динамични литерали на податоци во VALUES и

клаузите мора да се заменат со места за задржување. Реалните податоци ќе бидат врзани за време на извршувањето и испратени одделно од SQL командата.

Врзувањето на параметри може да се користи само за податоци. Другите динамични делови од SQL прашањето мора да се филтрираат според познат список на дозволени вредности.

<?php

// The dynamic SQL part is validated against expected values
$sortingOrder = $_GET['sortingOrder'] === 'DESC' ? 'DESC' : 'ASC';
$productId = $_GET['productId'];
// The SQL is prepared with a placeholder
$stmt = $pdo->prepare("SELECT * FROM products WHERE id LIKE ? ORDER BY price {$sortingOrder}");
// The value is provided with LIKE wildcards
$stmt->execute(["%{$productId}%"]);

?>

Подготвените изјави се обезбедени од PDO, од MySQLi, и од други библиотеки за бази на податоци.

SQL инјекциските напади главно се засноваат на експлоатирање на кодот што не е напишан со оглед на безбедноста. Никогаш не верувајте на никаков влез, особено од клиентската страна, дури и ако доаѓа од селективно поле, скриено поле за внесување или колаче. Првиот пример покажува дека таков едноставен упит може да предизвика катастрофи.

Стратегијата за одбрана во длабочина вклучува неколку добри практики за кодирање:

Richard dot Corfield at gmail dot com

Белешки од корисници 1 белешка

Richard dot Corfield at gmail dot com
пред 14 години
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.
На оваа страница

Автоматски outline од активната документација.

Насловите ќе се појават тука по вчитување.

Попрегледно читање

Примерите, changelog табелите и user notes се визуелно издвоени за да не се губат во долгата содржина.

Брз совет Користи го outline-от Скокни директно на главните секции од активната страница.
Извор Оригиналниот линк останува достапен Кога ти треба целосен upstream context, отвори го PHP.net во нов tab.