Bezpečnostní chyba systému Zen Cart

V tomto článku se zaměřím na bezpečnostní chybu v systému Zen Cart. Jedná se o celosvětově používaný open source internetový obchod. Používají jej tisíce malých i velkých e-shopů. Mnoho z nich však neví, jaké riziko podstupují pokud po instalaci neprovedou bezpečnostní kroky uvedené v dokumentaci Zen Cart. Systém totiž obsahuje nebezpečnou chybu, která umožňuje útočníkům převzít správu nad celým e-shopem. Najít v současné době nezabezpečenou instalaci Zen Cart není těžké a proto zde problém rozeberu podrobně.

Způsob vniknutí do administrace Zen Cart

Vniknout do nezabezpečené verze administrace Zen Cart není vůbec složité, podívejte se sami:

  1. Zadejte do prohlížeče url Vašeho Zen Cartu (např.: http://muj-zencart.cz/)
  2. Za lomítko napište název adresáře obsahující administraci obchodu (většinou http://muj-zencart.cz/admin)
  3. Vyberte si jakoukoliv stránku administrace. V mém případě Tools -> Server Info (http://muj-zencart.cz/admin/server_info.php)
  4. Pro verzi 1.2 přidejte za lomítko "login.php". Pro verzi 1.3 "password_forgotten.php"
  5. Navštivte url, v mém případě: http://muj-zencart.cz/admin/server_info.php/password_forgotten.php
  6. Jste v administraci? Pak máte problém.

Kde udělali vývojáří Zen Cartu chybu?

Chyba se týká této části kódu:

if (!(basename($PHP_SELF) == FILENAME_LOGIN . '.php'))
{ 
 if (!isset($_SESSION['admin_id'])) 
 { 
  if (!(basename($PHP_SELF) == FILENAME_PASSWORD_FORGOTTEN . '.php')) 
  { 
    zen_redirect(zen_href_link(FILENAME_LOGIN, '', 'SSL')); 
  } 
 } 
} 

Pro lepší pochopení lze kód zjednodušit na:

if(!(basename($PHP_SELF) == "login.php"))
{ 
 if (!isset($_SESSION['admin_id']))
 { 
  if(!(basename($PHP_SELF) == "password_forgotten.php"))
  { 
   // presmerovat na ../admin/login.php 
  } 
 } 
} 

Proměnná $PHP_SELF obsahuje relativní adresu souboru k document_root. V případě "http://www.muj-zencart.cz/neco/skript1.php/skript2.php" bude obsah $PHP_SELF roven "neco/skript1.php/skript2.php". Proveden bude skript1.php. PHP funkce basename vrací část cesty obsahující název souboru. Funkce basename("neco/skript1.php/skript2.php") tedy vrátí "skript2.php". A to je zdroj problému. Pro $PHP_SELF = "admin/server_info.php/password_forgotten.php" Zen Cart špatně vyhodnotí název právě prováděného skriptu a útočníkovi povolí vstup do administrace. V tomto případě Zen Cart vyhodnotí jako právě prováděný skript password_forgotten.php zatímco se provádí skript server_info.php

Jak Zen Cart zabezpečit?

Zabezpečení Zen Cartu proveďte takto:

1) Způsob uvedený v dokumentaci Zen Cart spočívá v prostém přejmenování adresáře "admin" na jakýkoliv jiný název. Útočník totiž musí znát url adresu k Vaší administraci. Jako výchozí je adresa administrace: http://muj-zencart.cz/admin. Přejmenováním adresáře "admin" například na "eshopadmin3" změníte adresu administrace na http://muj-zencart.cz/eshopadmin3. Tím útočníkovi výrazně snížíte šance na úspěch.

2) Po přejmenování adresáře "admin" stále existuje riziko, že Váš e-shop bude napaden. Proto aplikujte patch číslo 20090619 (http://www.zen-cart.com/forum/showthread.php?t=130161). Tento patch opravuje nebezpečný kód.

Zen Cart a sdílený webhosting

I přes rozšířenost Zen Cart ho na sdíleném webhostingu provozovatelé nevidí rádi. Důvodem je především jeho vyšší náročnost na systémové prostředky a horší bezpečnost. Zákazníky na webhostingu Klenot.cz, kteří používali nezabezpečenou verzi Zen Cart jsme na chybu upozornili a spolupracujeme s nimi na vyšším zabezpečení aplikace. Sami tento systém pro provoz internetového obchodu nedoporučujeme.