Принципи перевірки та очищення

Основний принцип – це не довіряти жодним даних і завжди перевіряти чи очищати дані, що отримуються з будь-яких джерел: POST/GET/AJAX параметри, БД, зовнішні API, RSS-канали. Інші принципи які випливають із цього розглянемо нижче.

Я думаю і так зрозуміло, що якщо ігнорувати перевірку даних, ваш сайт рано чи пізно зламають.

Перевірка (валідація) даних

Валідація даних означає розгляд вхідних даних і перевірка чи підходять вони для використання, перш ніж що-небудь з ними робити.

Дані форми

Вхідні дані зазвичай надходять з форми, наданої користувачеві, але це також можуть бути дані, що надходять від будь-якого зовнішнього джерела, наприклад: RSS-канали, AJAX запити, інших викликів API.

Небагато прикладів валідації даних:

  • Переконайтеся, що поля заповнені.
  • Переконайтеся, що введений номер телефону містить лише цифри та пунктуацію.
  • Переконайтеся, що введена поштова адреса є правильною.
  • Переконайтеся, що поле для введення кількості більше 0.

Валідація даних має бути виконана якомога раніше. Таку перевірку потрібно робити відразу при отриманні даних форми і потім працювати з даними.

Перевірка форми може бути виконана JavaScript, перш ніж форма буде відправлена. Покладатися на таку перевірку не можна! JavaScript – це клієнтська частина і там дані можна підробити, відключивши скрипт перевірки форми або відправивши дані безпосередньо на сервер. Кінцеву перевірку даних завжди потрібно робити саме у PHP!

Очищення даних

Коли незалежно від обставин потрібно прийняти дані або вивести на екран, їх потрібно очистити від небезпечних символів. Очищення потрібне:

  • перед збереженням даних у БД.
  • перед виведенням даних на екран.
  • Іноді перед перевіркою даних – спочатку очищаємо, потім перевіряємо чи підходить. Наприклад, видаляємо прогалини на кінцях рядків і перевіряємо чи підходить значення.


Чим перевіряти вхідні дані?

Для цього є купа функцій з ядра WordPress і з PHP. Повний список .


Принципи перевірки та очищення даних


Не довіряйте жодним даним

Будь-які дані, що вводяться користувачем, потенційно небезпечні, навіть якщо вони виводяться в адмінці, тільки для адміністратора.

Ставтеся до даних, що отримуються з бази даних, як до потенційно небезпечних. Навіть якщо при додаванні даних ви здійснили їх очищення. Справа в тому, що дані можуть використовуватись у різних контекстах. Наприклад, заголовки можуть містити лапки і викликають помилки, якщо використовувати їх в атрибуті html тега.


Перевіряйте на вході, очищайте на виході

Дані потрібно очищати якомога пізніше, в ідеалі прямо перед виведенням на екран. Логіка думаю зрозуміла: не думаємо про очищення взагалі, крім випадків виведення даних на екран.

Дані, що приймаються навпаки: потрібно очищати якомога раніше, в ідеалі прямо на вході. Але при цьому їх також потрібно чистити перед записом до бази даних. Справа в тому, що очищення для SQL запиту може відрізнятися від початкового очищення, наприклад при вході ми видалили всі теги і думаємо, що дані очищені, але така очищення не убезпечить від SQL ін’єкцій, тобто. це різні контексти очищення…


Довіряйте WordPress

Усі «основні» функції WordPress (обгортки, функції вищого порядку) перевіряють та очищають дані. Тому при використанні таких функцій не потрібно думати про перевірку або очищення даних, що передаються. Наприклад, WordPress сам підготує дані для використання в запиті:

$posts = get_posts(array(
	's' => $_GET['s']
)));

До таких функцій можна віднести всі функції, які щось виводять на екран або щось додають у базу даних і при цьому ви не складаєте SQL запит самостійно, наприклад: $wpdb->update() , $wpdb->insert( ) , wp_update_post() і т.д. Висновок: the_title() , the_content() тощо.


Краще зайвий раз очистити

Якщо розібратися, то очищення даних не завжди потрібне. Але при розробці і так доводиться за багатьом стежити, і відволікатися, втрачаючи дорогоцінний час і увагу на очищення часом нераціонально. Тому якщо сумніваєтеся, краще зайвий раз очистити в потрібному контексті перед виведенням/введенням, ніж потім ловити баги, або ще гірше мати дірки в коді.

Існує кілька підходів до того, як потрібно очищати/перевіряти дані. Кожен із них підійде для різних випадків.


Білий список

Перевіряти дані з наявного білого списку і допускати їх, якщо вони є.

Приклад використання оператора порівняння
$val = '1 неперевірений рядок';

if ( 1 === $val ) {
	echo 'Допустиме значення';
}
else {
	wp_die( 'НЕ допустиме значення');
}

Важливо, щоб дані перевірялися з урахуванням типу ( === або !== ).

Зверніть увагу, що ми використовували оператор ===а не ==. Це важливо, тому що при порівнянні ==перевірку буде пройдено – $val перетвориться на 1.

Приклад з in_array()
$val = '1 небезпечний рядок';

$ safe_values ​​= array (1, 5, 7); // білий список

if ( in_array( $val, $safe_values, true ) ) {
	// `true` вказує, що потрібно враховувати тип даних - точна перевірка
	echo 'Допустиме значення';
}
else {
	wp_die( 'Неприпустиме значення');
}

Зверніть увагу, що ми використовували третій параметр true для in_array(). Це важливо, тому що без нього перевірка буде пройдена – $ val перетвориться на 1.

Приклад зі switch()
$val = '1 небезпечний рядок';

switch (true) {
	case 1 === $val: // потрібно окремо перевіряти з урахуванням типу, а не сподівається на switch
		echo 'Допустиме значення';
		break;

	default:
		wp_die( 'Неприпустиме значення');
}

Важливо, щоб дані перевірялися з урахуванням типу ( === або !== ).

Зверніть увагу, що окремо перевіряємо значення за допомогою ===а не просто case 1. Це важливо, тому switch за умовчанням перетворює тип і якщо так не зробити, то перевірка буде пройдена – $ val перетвориться на 1.


Чорний список

Не пропускати дані, якщо вони є у чорному списку. Найчастіше це найкраща перевірка, якщо така перевірка підходить під вашу логіку.

Робиться також як білий список, тільки якщо дані не приймаються.


Дані з числової колонки у базі даних завжди безпечні

Якщо дані в БД зберігаються в числовій колонці, то такі дані завжди безпечні, тому що при записі туди не може потрапити нічого, крім числа.

Числові дані потрібно завжди перетворювати на числа на вході:

$count = (int) $_GET['count']; // 10
$price = (float) $_POST['price']; // 52.5


Приклади


Приклад перевірки даних

Потрібно переконатися, що дані прийшли у потрібному форматі, інакше їх не допускати.

// Пройде якщо $data складається тільки з літер та цифр: 'AbCd1zyZ9' - так, 'foo!#$bar' - ні
if (! ctype_alnum($data)) {
	wp_die( 'Неправильний формат');
}

// перевірка за символами: може бути лише 0-9.-
if ( preg_match( '/[^0-9.-]/', $data ) ) {
	wp_die( 'Неправильний формат');
}


Приклад очищення даних

Коли незалежно від обставин потрібно прийняти дані, їх можна очистити від небезпечних символів.

// коли потрібно отримає лише число
$trusted_integer = (int) $untrusted_integer;

// коли потрібно отримає лише малі літери
$trusted_alpha = preg_replace( '/[^az]/i', "", $untrusted_alpha );

// коли потрібно отримає стандартний ярлик (slug)
$trusted_slug = sanitize_title( $untrusted_slug );

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *