Do czego używa się register_globals na serwerze

Jeśli kiedykolwiek miałeś do czynienia z PHP w jego starszych wersjach, to pewnie słyszałeś o czymś takim jak register_globals. Ta funkcja (a właściwie dyrektywa konfiguracyjna) była kiedyś bardzo popularna i powszechnie używana. Wielu programistów z lat 2000-2010 doskonale ją pamięta – często z nostalgią, ale też z lekkim dreszczem grozy. Dlaczego? Bo register_globals to narzędzie, które w teorii miało ułatwić życie, ale w praktyce… często je komplikowało, i to bardzo poważnie.

W tym artykule opowiem Ci co to jest register_globals, do czego się go używało, dlaczego zostało wyłączone i czym je można zastąpić w nowoczesnych projektach. Jeśli interesujesz się bezpieczeństwem, PHP lub administracją serwerów, to koniecznie przeczytaj do końca.

Czym właściwie jest register_globals?

register_globals to ustawienie konfiguracyjne w PHP, które automatycznie „rejestrowało” zmienne pochodzące z różnych źródeł (takich jak formularze, ciasteczka, adres URL czy sesje) jako globalne zmienne w skrypcie.

Brzmi skomplikowanie? Przykład najlepiej to wyjaśni.

Załóżmy, że masz prosty formularz HTML:

<form method="GET" action="test.php">
  <input type="text" name="imie">
  <input type="submit" value="Wyślij">
</form>

Teraz, gdy użytkownik wpisze w pole „imie” wartość np. Janek i wyśle formularz, przeglądarka wywoła adres:

test.php?imie=Janek

W nowoczesnym PHP, żeby pobrać wartość z tego pola, musisz napisać:

<?php
$imie = $_GET['imie'];
echo "Cześć, $imie!";
?>

Ale kiedyś, gdy register_globals było włączone, PHP automatycznie tworzyło zmienną $imie z tą wartością. Nie musiałeś używać $_GET, $_POST ani żadnych superglobalnych tablic. Po prostu:

<?php
echo "Cześć, $imie!";
?>

Do czego używało się register_globals?

W latach 90. i na początku 2000. register_globals wydawało się genialnym rozwiązaniem. Programiści nie musieli pamiętać, z jakiego źródła pochodzi dana zmienna – wszystko było dostępne „z automatu”.

Używano tego głównie do:

  1. Szybkiego prototypowania – można było błyskawicznie napisać działający kod, bez zbędnych tablic.
  2. Prostych aplikacji formularzowych – np. strony kontaktowe, loginy, rejestracje.
  3. Skryptów CMS i forów – wczesne wersje takich systemów jak phpNuke, Mambo czy stare fora oparte o PHPBB często wykorzystywały register_globals.
  4. Skryptów serwerowych – admini serwerów często włączali to ustawienie w php.ini, żeby ułatwić działanie starszych aplikacji.

W skrócie – register_globals miał być wygodny. Nie musiałeś sprawdzać, czy coś przyszło przez $_POST, $_GET, $_COOKIE czy $_SESSION. Po prostu używałeś zmiennych globalnych jak $user, $id, $message, i gotowe.

Dlaczego register_globals to był błąd?

Problem z register_globals polegał na tym, że włączał niebezpieczne skróty. W zasadzie każdy mógł „wstrzyknąć” wartość do zmiennej globalnej przez adres URL, formularz lub ciasteczko.

Spójrz na ten przykład:

<?php
if ($is_admin) {
  echo "Witaj w panelu administratora!";
}
?>

Jeśli register_globals było włączone, użytkownik mógł wywołać stronę tak:

panel.php?is_admin=1

I bum! PHP automatycznie utworzyło zmienną $is_admin = 1. W efekcie każdy mógł uzyskać dostęp do panelu admina, bez logowania, bez hasła, bez autoryzacji.

To był koszmar bezpieczeństwa.

W ten sposób można było łatwo ominąć walidację, nadpisać zmienne, a nawet wykonywać kod w kontekście serwera.

Z tego powodu register_globals zaczęto uznawać za jedną z największych dziur bezpieczeństwa w historii PHP.

Jak wyłączyć register_globals?

W nowszych wersjach PHP (od PHP 4.2.0, czyli od 2002 roku) register_globals domyślnie było już wyłączone, a od wersji PHP 5.4 (2012 rok) – całkowicie usunięte z języka.

Ale jeśli korzystasz z jakiegoś starego serwera lub retro aplikacji, może się zdarzyć, że natrafisz na taki zapis w pliku php.ini:

register_globals = On

Aby to wyłączyć, wystarczy zmienić na:

register_globals = Off

i zrestartować serwer Apache lub Nginx.

Alternatywnie można to ustawić w pliku .htaccess:

php_flag register_globals off

Lub nawet w samym kodzie PHP (choć to niezalecane):

ini_set('register_globals', 0);

Co zamiast register_globals?

Dziś mamy o wiele bezpieczniejsze i bardziej przejrzyste metody pracy z danymi użytkownika. Zamiast automatycznych zmiennych globalnych używamy superglobalnych tablic, czyli:

  • $_GET – dane przekazane przez adres URL,
  • $_POST – dane z formularzy,
  • $_COOKIE – dane z ciasteczek,
  • $_SESSION – dane sesji,
  • $_SERVER – informacje o serwerze i zapytaniu,
  • $_FILES – pliki przesłane przez formularz.

Przykład poprawnego, bezpiecznego kodu:

<?php
if (isset($_POST['username'])) {
    $username = htmlspecialchars($_POST['username']);
    echo "Witaj, $username!";
} else {
    echo "Podaj swoje imię.";
}
?>

Jak widzisz, wszystko jest jawne – od razu wiadomo, skąd pochodzi dana zmienna. Dodatkowo, dzięki funkcjom takim jak htmlspecialchars(), możemy chronić się przed atakami XSS.

Dlaczego nie warto polegać na starym kodzie z register_globals

Często spotykam się z sytuacją, gdy ktoś odziedziczył stary projekt napisany w PHP 3 lub 4. W kodzie roi się od linii typu:

if ($user == "admin" && $pass == "tajnehaslo") {
    include("panel.php");
}

Na pierwszy rzut oka wygląda to dobrze, ale jeśli register_globals było włączone, wystarczyło dopisać do adresu:

login.php?user=admin&pass=tajnehaslo

i system wpuszczał każdego.

Dlatego przy modernizacji starego kodu pierwszym krokiem powinno być całkowite usunięcie zależności od register_globals i przepisanie logiki na superglobalne tablice.

Jak sprawdzić, czy kod używa register_globals

Jeśli chcesz sprawdzić, czy Twoja aplikacja opiera się na register_globals, możesz poszukać miejsc, w których zmienne są używane bez wcześniejszego przypisania.

Na przykład:

echo $id;

bez żadnego $_GET['id'] wcześniej.

Możesz też napisać prosty skrypt PHP, który przeskanuje pliki projektu i znajdzie podejrzane zmienne. Oto przykładowy kod:

<?php
$directory = './'; // katalog z kodem
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
$pattern = '/\$\w+\s*[^=]*;/'; // szuka użyć zmiennych

foreach ($rii as $file) {
    if ($file->isDir()) continue;
    $content = file_get_contents($file->getPathname());
    if (preg_match_all($pattern, $content, $matches)) {
        foreach ($matches[0] as $match) {
            echo "Znaleziono potencjalne użycie zmiennej w pliku: " . $file->getPathname() . "\n";
        }
    }
}
?>

Ten prosty skrypt przeanalizuje pliki PHP i wypisze miejsca, w których mogą być używane niezainicjalizowane zmienne.

Najczęstsze błędy po wyłączeniu register_globals

Jeśli wyłączysz register_globals w starym kodzie, może się okazać, że nic nie działa. Strony przestaną widzieć dane z formularzy, sesje nie będą się zapisywać, a użytkownicy nie będą mogli się logować.

Typowy przykład błędu:

Warning: Undefined variable: login

Wtedy wystarczy dopisać kilka linii kodu:

$login = $_POST['login'] ?? '';
$haslo = $_POST['haslo'] ?? '';

lub w starszym PHP:

if (isset($_POST['login'])) $login = $_POST['login'];

Dzięki temu kod będzie działał poprawnie bez potrzeby register_globals.

Czy da się dziś jeszcze używać register_globals?

Technicznie rzecz biorąc – nie. Od wersji PHP 5.4 ta opcja została trwale usunięta z silnika PHP. Nie da się jej włączyć, nawet jeśli ustawisz ją w php.ini.

Istnieją jednak „obejścia” – np. ręczne pisanie funkcji, które symulują działanie register_globals. Ale naprawdę – nie rób tego.

Oto przykład, jak można to zrobić (czysto edukacyjnie!):

<?php
function fake_register_globals() {
    foreach ($_REQUEST as $key => $value) {
        $GLOBALS[$key] = $value;
    }
}
fake_register_globals();

Ten kod robi dokładnie to, co dawniej robił register_globals. Ale zauważ – jest potencjalnie niebezpieczny, bo każda zmienna przekazana w adresie lub formularzu stanie się globalna.

Taki kod to zaproszenie dla hakerów. Nigdy nie używaj go w prawdziwej aplikacji.

Podsumowanie – register_globals to przeszłość

Podsumujmy najważniejsze rzeczy, które warto zapamiętać:

register_globals to stara funkcja PHP, która automatycznie tworzyła zmienne globalne z danych przesłanych przez użytkownika.
– Było to wygodne, ale skrajnie niebezpieczne – umożliwiało łatwe ataki i wstrzykiwanie danych.
– Od wersji PHP 5.4 funkcja została usunięta z języka.
– Zamiast tego należy używać superglobalnych tablic ($_GET, $_POST, $_COOKIE, $_SESSION itd.).
– Jeśli masz stary kod, koniecznie go zmodernizuj i usuń wszelkie zależności od register_globals.

Na koniec: moja rada dla Ciebie

Jeśli zajmujesz się programowaniem PHP, pamiętaj – bezpieczeństwo to nie opcja, to obowiązek. Nawet jeśli coś wydaje się prostsze i szybsze, może być jednocześnie bardziej niebezpieczne.

register_globals to świetny przykład na to, jak „magiczne” ułatwienia mogą obrócić się przeciwko nam. Dziś mamy lepsze narzędzia, standardy i praktyki, które nie tylko chronią nasze aplikacje, ale też czynią kod bardziej czytelnym i zrozumiałym.

Więc jeśli kiedykolwiek spotkasz register_globals w kodzie – potraktuj to jak czerwoną flagę i znak, że czas na refaktoryzację. Twój serwer i Twoi użytkownicy będą Ci wdzięczni.

Szukasz taniego i dobrego hostingu dla swojej strony www? - Sprawdź Seohost.pl