Чому небезпечно включати параметр php register_globals, shublog

Зазвичай напишуть, що використовувати його не рекомендується (якщо взагалі напишуть - прим.ред.), Та все. В результаті, само собою, програміст просто не здогадується, до чого може привести використання register_globals.
У цій статті я постараюся витягнути з танка всіх тих, хто в ньому сидить, і розтлумачити, що до чого (спеціально для тих, хто на бронепоїзді - прим.ред.). Все таки не дарма деякі хостери відключають цю директиву. Отже ...
Про те, як це працює
В налаштуваннях PHP (файл php.ini) є така директива register_globals. Сенс її полягає в тому, що якщо вона включена (register_globals = on), то всі змінні, передані через GET і POST, будуть зареєстровані автоматично як глобальні. Що це означає?
Наприклад, ми передаємо сценарієм index.php методом GET деяке значення page: index.php? Page = 2. Передане значення зберігається в масиві GET і може бути використано в сценарії як $ _GET [ 'page']. Однак якщо у нас включена register_globals, то для переданого значення буде створена змінна $ page, яка доступна в будь-якій частині сценарію index.php.
Невеликий підсумок і доповнення. При включеному register_globals створюється три копії змінної: в масиві GET, в масиві GLOBALS і просто сама змінна ($ _GET [ 'page'], $ GLOBALS [ 'page'], $ page), в той час як при вимкненому register_globals передане значення може бути доступно тільки через масив GET ($ _GET [ 'page']). Запам'ятали.
Розглянемо простий приклад, щоб зрозуміти, що нам світить (від 3 до 5 років - прим.ред.). Щоб було простіше, скажу відразу, що $ login і $ password - це змінні, передані методом GET / POST.
Коротко про те, що робить сценарій:Рядок 2. Робимо запит до БД з метою витягнути справжній пароль для введеного користувачем логіна.
Рядок 3. Отримуємо цей пароль і присвоюємо його змінній $ real_pass.
Рядок 4. Порівнюємо справжній і введений пароль і якщо вони співпадуть, то змінній $ check буде присвоєно true.
Запропонований сценарій по визначенню самий дірявий на світлі і зараз я покажу Вам ці дірки. Умова - register_globals включений.
Припустимо, передача йде методом GET. Тоді url буде виглядати приблизно так:
www.site.com/index.php?login = adminpassword = qwerty
Ясна річ, що відразу ж створюються глобальні змінні $ login і $ password. А тепер подивіться сценарій. У ньому є змінна $ check. А що якщо її передати через урл?
Думаю, у кого-то виникло питання, а звідки крякери дізнається про змінну check, що вона за все відповідає? Якщо Ви нікому не показували сценарій, то він навряд чи це дізнається. Однак не всі використовують свої сценарії, CMS та інше, а користуються тим, що є в мережі. У таких випадках крякери, наприклад, може вивчити код CMS і робити атаки на сайти, створені за його допомогою.
Проте, не всі хостери відключають register_globals і навіть, якщо Ваші сценарії будуть заточені на відсутність включеного register_globals, то крякери все одно може зламати Ваш сценарій, використовуючи вразливість цієї директиви.
Візьмемо наш приклад. Щоб його захистити на випадок, якщо register_globals включений, потрібно після рядка if ($ password == $ real_pass) $ check = true; дописати наступне: else $ check = false ;. В цьому випадку, навіть якщо методом GET буде передана змінна check дорівнює одиниці, то сценарій при неправильному паролі все одно встановить $ check = false.
Так, ще зверну Вашу увагу на те, що якщо вимкнути register_globals, то наш приклад працювати не буде. А щоб він запрацював, треба перед сценарієм написати $ login = $ _POST [ 'login']; $ Password = $ _POST [ 'password'];
і зробимо два основні висновки:
1) При включеному register_globals можна передавати різні змінні, значення для яких отримувати через GET або POST не розраховувати.
2) Не стільки небезпечний сам register_globals, скільки криво написаний сценарій.
З побажаннями вдалої тижні,
Олександр Шуйського