Skip to content

Commit

Permalink
database extensive update
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Dec 17, 2024
1 parent 1e10b0d commit 327af83
Showing 49 changed files with 12,795 additions and 4,396 deletions.
1 change: 1 addition & 0 deletions database/bg/@left-menu.texy
Original file line number Diff line number Diff line change
@@ -4,3 +4,4 @@
- [Изследовател |Explorer]
- [Размисъл |Reflection]
- [Настройване |configuration]
- [Рискове за сигурността |security]
927 changes: 653 additions & 274 deletions database/bg/explorer.texy

Large diffs are not rendered by default.

145 changes: 145 additions & 0 deletions database/bg/security.texy
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
**Риск за сигурността**
***********************

.[perex]
Базите данни често съдържат чувствителни данни и позволяват опасни операции. Базата данни Nette предоставя редица функции за сигурност. От решаващо значение е обаче да се разбере разликата между безопасни и опасни API.


SQL инжектиране .[#toc-sql-injection]
=====================================

SQL инжектирането е най-сериозният риск за сигурността при работа с бази данни. То възниква, когато непроверен потребителски вход стане част от SQL заявка. Атакуващият може да инжектира свои собствени SQL команди, като по този начин получава или променя данни в базата данни.

```php
// ❌ БЕЗОПАСЕН КОД - уязвим към SQL инжекция
$database->query("SELECT * FROM users WHERE name = '$_GET[name]'");

// Нападателят може да въведе нещо подобно на: ' ИЛИ '1'='1
// Получената заявка ще бъде:
// SELECT * FROM users WHERE name = '' OR '1'='1'
// Това връща всички потребители!
```

Същото се отнася и за Database Explorer:

```php
// ❌ КОД ЗА БЕЗОПАСНОСТ
$table->where('name = ' . $_GET['name']);
$table->where("name = '$_GET[name]'");
```


Безопасни параметризирани заявки .[#toc-safe-parameterized-queries]
===================================================================

Безопасният начин за вмъкване на стойности в SQL заявките е чрез параметризирани заявки. Базата данни Nette предоставя няколко начина за използването им.


Заместващи въпросителни знаци .[#toc-placeholder-question-marks]
----------------------------------------------------------------

Най-простият метод е да се използват заместващи въпросителни знаци:

```php
// ✅ Безопасни параметризирани заявки
$database->query('SELECT * FROM users WHERE name = ?', $_GET['name']);

// ✅ Безопасно условие в Explorer
$table->where('name = ?', $_GET['name']);
```

Същото важи и за всички други методи в Database Explorer, които позволяват вмъкване на изрази с въпросителни знаци и параметри.

.[warning]
Стойностите трябва да са от скаларен тип (`string`, `int`, `float`, `bool`) или `null`. Ако например `$_GET['name']` е масив, Nette Database ще включи всички негови елементи в SQL заявката, което може да е нежелателно.


Масиви от стойности .[#toc-value-arrays]
----------------------------------------

За клаузите `INSERT`, `UPDATE` или `WHERE` можем да използваме масиви от стойности:

```php
// ✅ Безопасен INSERT
$database->query('INSERT INTO users', [
'name' => $_GET['name'],
'email' => $_GET['email'],
]);

// ✅ Безопасен UPDATE
$database->query('UPDATE users SET', [
'name' => $_GET['name'],
'email' => $_GET['email'],
], 'WHERE id = ?', $_GET['id']);
```

Nette Database автоматично ескапира всички стойности, предадени чрез параметризирани заявки. Трябва обаче да осигурим правилния тип данни на параметрите.


Ключовете на масива не са сигурен API .[#toc-array-keys-are-not-a-safe-api]
===========================================================================

Докато стойностите в масивите са безопасни, същото не може да се каже за ключовете:

```php
// ❌ БЕЗОПАСЕН КОД - ключовете могат да съдържат SQL инжекция
$database->query('INSERT INTO users', $_GET);
$database->query('SELECT * FROM users WHERE', $_GET);
$table->where($_GET);
```

За командите `INSERT` и `UPDATE` това е критичен недостатък в сигурността - атакуващият може да вмъкне или промени всяка колона в базата данни. Например, той може да зададе `is_admin = 1` или да вмъкне произволни данни в чувствителни колони.

В условията на `WHERE` това е още по-опасно, защото позволява **SQL enumeration** - техника за постепенно извличане на информация за базата данни. Нападателят може да се опита да проучи заплатите на служителите, като инжектира в `$_GET` по този начин:

```php
$_GET = ['salary >', 100000]; // започва да определя диапазони на заплатите.
```

Основният проблем обаче е, че `WHERE` условията поддържат SQL изрази в ключовете:

```php
// Законосъобразно използване на оператори в ключовете
$table->where([
'age > ?' => 18,
'ROUND(score, ?) > ?' => [2, 75.5],
]);

// ❌ БЕЗОПАСНО: атакуващият може да инжектира свой собствен SQL
$_GET = ['1) UNION SELECT name, salary FROM users WHERE (is_admin = ?' => 1];
$table->where($_GET); // позволява на нападателя да получи администраторски заплати
```

Това отново е **SQL инжекция**.


Създаване на бял списък на колоните .[#toc-whitelisting-columns]
----------------------------------------------------------------

Ако искате да разрешите на потребителите да избират колони, винаги използвайте бял списък:

```php
// ✅ Безопасна обработка - само разрешени колони
$allowedColumns = ['name', 'email', 'active'];
$values = array_intersect_key($_GET, array_flip($allowedColumns));

$database->query('INSERT INTO users', $values);
```


Динамични идентификатори .[#toc-dynamic-identifiers]
====================================================

За динамични имена на таблици и колони използвайте заместителя `?name`:

```php
// ✅ Безопасно използване на надеждни идентификатори
$table = 'users';
$column = 'name';
$database->query('SELECT ?name FROM ?name', $column, $table);

// ❌ UNSAFE - никога не използвайте потребителски вход
$database->query('SELECT ?name FROM users', $_GET['column']);
```

Символът `?name` трябва да се използва само за доверени стойности, дефинирани в кода на приложението. За стойности, предоставени от потребителя, отново използвайте бял списък.
1 change: 1 addition & 0 deletions database/cs/@left-menu.texy
Original file line number Diff line number Diff line change
@@ -4,4 +4,5 @@ Databáze
- [Explorer]
- [Reflexe |reflection]
- [Konfigurace |configuration]
- [Bezpečnostní rizika |security]
- [Upgrade |upgrading]
Loading

0 comments on commit 327af83

Please sign in to comment.