Писане на сигурен код в PHP. Част 1
21-10-2012
Започвам една поредица от уроци или статии все тая. Уроците са свързани с това как да пишем по-сигурен код на PHP. Надявам се, да се научите как да избягвате, някой грешки в уеб програмирането и по този начин да направите вашите сайтове по-сигурни - както за вас, така и за клиента(потребителя).
PHP е сравнително лесен език, много хора го знаят дори без да имат технически познания. Е.. зажалост това е и коренния проблем на повечето уеб приложения изградени от начинаещите програмист(уеб). Те не са наясно с потенциалните проблеми в своите приложения, а сега ще изброя, някой начини как да се защитим.

Виждам доста често проблеми със сигурността на големи "Студия", което малко ме .. притеснява. Имат сериозни клиенти, а сигурността не е на ниво. Не искам да правя АНТИреклама и няма да споменавам имена, но съм им изпратил по един И-мейл /е.. само когато ми се е занимавало да им казвам и е бил голям "бъга"/

Глобалните променливи.
В много програмни езици се създава променлива, която се използва в "по-късен" етап. PHP-то има опция "register_global", която може да бъде конфигурирана от php.ini или .htacces.
Тази опция позволява използването на глобалните променливи без предизвестие.

Помислете за следното:
if ($password == "parola") {
$authorized = 1;
}
if ($authorized == 1) {
echo "yeah, very good :D";
}


На пръв поглед няма проблеми, но в всъщност... има проблеми. Тъй като човек може по "невнимание" да промени променливата "authorized".

Изглежда добре, но, когато "register_globals" е включен, можем да добавим към сайта "saita.com/index.php?authorized=1" и ще вземем достъп до сайта, като идентифициран потребител.

Това може да се избегне, като изключите тази опция. За щастие, много Хостинг компании е изключват по подразбиране. Въпреки това, ако все още трябва да използват глобални променливи, трябва да обявят предварително важни променливи:

$authorized = 0; //виж този ред по-горе го няма.
if ($password == "parola") {
$authorized = 1;
}
if ($authorized == 1) {
echo "yeah, very good :D";
}


Съобщенията за грешките са полезни заради тяхното отстраняване от скрипта/сайта/.. Всеки уеб разработчик се нуждае от тях(грешките) за да ги поправи. НО за разлика от разработчика ГРЕШКАТА е в полза за хахора, който може да дадена информация и да се възползва от нея.

Като версията на дб-то, пътя до вашият уеб сайт: /home/user/public_html/ (по подразбиране).. Така, че след отстраняването на грешки по сайтовете си, е хубаво да деактивирате тази опция.

Това може да стане , чрез няколко варианта.
.htaccess, php.ini или направо в php скрипта. Трябва да се определи правилото "error_reporting 0".
<?php
// Turn off all error reporting
error_reporting(0);
?>


.htaccess
php_value error_reporting 0
php_flag display_errors Off


php.ini -> http://php.net/manual/en/errorfunc.configuration.php

SQL Инжекциите (SQLi, SQL Injection, http://en.wikipedia.org/wiki/SQL_injection)
Толкова пъти съм го дъфкал .. вече ми е писнало - банално е, но да има много уязвими уеб приложения към SQLi. Една от силната страна на PHP езика е бързото взаимодействие с базата от данни.
По-голямата част уеб сайтове в Интернет са изградени на принципа PHP + MySQL.

Както казах.. все още има МНОГО уязвими уеб приложения. Въпреки че според мен, разните PHP frameworks които налагат неща като prepared statements, някои ден ще видят сметката на това и след няколко години тези уязвимости ще бъдат рядкост. Знам ли.

И така. Най-често срещата уязвимост вече разбрахте, коя е. Да е казвам ли пак? Използва се за неоторизирано изпълнение на SQL заявка към базата данни.

Повече за SQLi и защита от тях ще напиша в следващата поредица. Все пак доста , често сме обсъждали тази тема.

Манипулацията на файлове.
Много от сайтове, които в момента работят в Интернет имат адреси, които изглеждат по този начин:
index.php?act=news.php

Сега да разясним. index.php свързва news.php(в повечето случай в адрес бара, не се изписва .php). Тук потребителят може лесно да промените името на файла "blabla.php".
Например, при не правилно написан код, лесно можем да отидем във файла /etc/passwd на сървъра ни. Това е файл, които съдържа цялата информация за потребителите в сървъра. Най-обикновен текстов файл, чийто собственик е суперпотребителя(root) и само той може да редактира съдържанието му, останалите потребители по дефиниция могат само да го четат. Всички редове в този файл имат строго определен формат:

username:password:userID:groupID:comment:home_directory:login_comm

Впрочем, тук паролата неможем да е видим тя е маскирана(скрита) съдръжа се във файла /etc/shadow - само суперпотребителя(root) , може да го чете и редактира. Докато /etc/passwd файла , може да бъде прочитан не само от root.

Да се върнем на манипулациите.

index.php?page=/etc/passwd

При уязвим код, ще ни изкара информация от вида на:
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
adm:x:3:4:adm:/var/adm:
lp:x:4:7:lp:/var/spool/lpd:

.......

И т.н. В хахорството на това му се вика LFI или иначе казано: Local File Inclusion Аttack.

В такъв случай, най-добре е да се напише кода както трябва.

Мислех да ви кажа, да използвате "safe_mode_include_dir", но .. той е премахнат в PHP 6.0. Връщаме се на варианта, че трябва да напишете правилно кода си.

Предсказуемостта
Нека предположим за момент, че сайта ви е привлякла вниманието на един хахор. Той иска да хакне админ панела просто, за да смени началната страница с няк'в измислен дефейс или да се сдобие с по-голям достъп. Не е трудно да се досетите, че първият адрес, където би изпробвал да отвори или ще е http://sait.com/admin/ или http://sait.com/administrator/ като този. Просто не бъдете предвидими.

Когато пишете вашия сайт, просто му задавайте сложни имена на папките, които са ВАЖНИ. Например, Административния панел може да бъде и на адрес: http://sait.com/t1kadmin37a/ може да не е толкова лесно, за запомняне, но добавя допълнителна сигурност на сайта. За директорията на админ панела трябва, да изберете нещо запомнящо се, но не твърде обикновено - травиално.
А, да.. щях да забравя. Не слагайте потребителски имена и пароли от вида на: admin : admin / admin : 12345 / administrator : imetonasaita / admin : admin123

И прочие. Слагайте лесно запомняща се, но трудно предвидима за хахора парола. Също така е сменявайте през определен интервал от време - например на 1 месец?

Искам да кажа, че доста хостинг компании в нашата държава нямат голяма сигурност. Най-вече при Споделения хостинг и възможността, уеб сайта ви да бъде хакнат грешката не винаги е ваша.
Сайта е изложен на риск 24/7/365 в годината за това, през определено време, просто му отделяйте няколко минути и преглеждайте файловете си, да не би да има някой злонамерен код в тях. Можете и да си напишете един скенер, които да върши тази работа.

Очаквайте.. част 2. Обмислям да ви обясня как да се защитите от SQLi, XSS, Файл Ъплоад Атака (FUA) - така го наричам аз и Защита на бисквитките..

Можете да погледнете и урока за защита от CSRF на този адрес: http://web-tourist.net/login/login/view.php?st=3441

Доста, често се допуска и тази уязвимост - в повечето случай дори не и се обръща внимание. Което ме подсеща, как преди доста години бяха се налазили форумите с точки (използваше се CashMOD, който има опция за трансфер на точките.. Е.. :)) Имаше CSRF и някой потребители останаха без точки други с много точки и вземаха домейни.))

Лек ден! :)


РЕ: Ако имате някакви предложения просто ми пишете ЛС.



/ Трябва да сте регистриран за да напишете коментар /
От: proba
6:25 22-10-2012
Много е добро урокът, браво!
Но за това за разбиране на директория "/home/user/public_html/" може да стане и чрез cookie editor ако изтриеш PHPSESSID и връща грешка но и чрез грешки в страницата пак би могло да се види да.
От: Ticketa
11:52 22-10-2012
Самото съдържание , ако го изчистиш вади грешка, иначе не би трябвало. Защото при презареждането на страницата се "прави" нова бисквитка. Впрочем като се замисля е хубаво да се драсне един class , който да записва сесиите в дб-то и да се избегне тоя проблем. :)

Има и друг проблем, повечето хостинг компании си записват сесиите в /tmp директорията :))

Ако имаме примерен скрипт:


И направим един "рефреш" на страница, ще се създаде файл в /tmp

$ cat /tmp/sess_128476329596325923985(тук в повечето случай е md5())
username|s:5:"proba";

Мисълта ми, е че ако някой си записва паролите в Сесии е малко тъпичко, 'щото ако се разбие md5() - в повечето случай, си взима достъп. Преди време cPanel имаше подобни проблеми.

Най-добре в този случай е да се ползва: ini_get('session.save_path');
Но ще драсна в следващата част, как да се предпазим от такива проблеми. Ако за сега някой има подобен проблем по-горе съм написал как да си изключи показването на грешки в страницата. :)
От: kikity_94
17:49 22-10-2012
Много добър урок браво :) Някой дребни работи ми се изясниха напълно вече :)
От: Slavei
13:56 31-10-2012
Урока щеше да е добър преди 7-8 години.
Сега register_globals не същестува.
настройките са грешки - ОК
"Манипулация на файлове" - честно казано не смятам, че останаха такива сайтове, но би било полезно за начинаещите да го имат в предвид. За съжаление, дори не е загатнато как да се предпазим.
От: Ticketa
19:40 31-10-2012
Аз до колкото знам register_globals е премахната в PHP 6.0. КАТО register_globals може да е включена в някоя хостинг компания. Да не говорим , че почти всички хостинг компании предлагат хостинг, които поддържа PHP 4.3 и PHP 5.


""Манипулация на файлове" - честно казано не смятам, че останаха такива сайтове, но би било полезно за начинаещите да го имат в предвид. За съжаление, дори не е загатнато как да се предпазим."

Какви сайтове не са останали? Я пак? Явно не си се интересувал относно това. :)

"дори не е загатнато как да се предпазим" e, чето аз ако напиша цяла лекция и книга, май ще ми стигне съдържанието на страницата.

Мен ми се струва, че повечето само говорите, а не сте си направили и труда поне веднъж да направите нещо смислено. Но все пак такъв е манталитета на тая държава. Хейтърска работа , но не ми пука.
От: Slavei
16:59 12-11-2012
Явно ти пука.
Похвално, че си написал урок. Написал съм коментар отдолу с цел критика, за да бъде следващият урок по-добър. Ако имаш проблем с критиката не публикувай нищо :P

Относно пхп6 бих те посъветвал да прочетеш малко за версия 5.4 - повечето неща планирани за шестицата влязоха в нея. (да не говорим, че и в 5.3 има неща, които бяха планирани за версия 6)

ОК, може да съм сбъркал и все още да се пишат файлове, които според гет параметър да инклудват файл...
1