Pull to refresh

Comments 185

Отличная статья! Мне очень понравился стиль изложения: что написал программист — как это можно сломать — как защититься.

Но мне всё-таки кажется, что таким важным вещам лучше учить сразу. Если человек уже год пишет рабочие сайты и ещё не разу не слышал об этих мерах безопасности, у него есть хороший повод пересмотреть свой код :)

Подсказка авторам книг и другой учебной литературы: если рассказываете про MySQL, то одним из пунктов обязательно нужно рассказать про SQL injection.
> Но мне всё-таки кажется, что таким важным вещам лучше учить сразу.
Это я про то, что программиста с 12-18 месяцев стажа уже нельзя назвать начинающим.
С утра посмотрел и тоже немножко усомнился в своей адекватности. %)
Исправил.
Явно преувеличен стаж, безопасность — это следующий урок любого программиста, который выучил как сделать "Hello World!" тремя и более способам. Приведенные проблемы относятся к начальному уровню, то есть для новичков.

Для валидации данных полезно использовать такие функции как intval, ctype_*. Если набор возможных значений заведомо известен, то in_array тоже сойдет. В куки вообще лучше хранить только хэш сессии, а всё остальное на сервере или в БД. Динамически подключаемые файлы должны проверяться на местонахождение, ограничивать папку для возможных файлов, например. А лучше, конечно, иметь список допустимых файлов.
По поводу стажа согласен. Да и вообще, таких статей в интернете куча. И во всех написано тоже самое. Надоели эти статьи для новичков, даёшь что-нибудь интересно для Pro.
> куки вообще лучше хранить только хэш сессии
не согласен, сессии тоже не самый лучший вариант, так как при нетрудной атаки, можно создать такое количество сессий, что сервак не выдержит... Подробнее в гугле.

А куки я считаю нормальным местом для хранения данных. А то, что у юзера могут вытащить куки трояном, то это его вина, а не программиста.
Троян — не единственный вариант. Ещё есть XSS. А есть вообще такие данные (например, сумма заказа, или уровень прав доступа) — которые нельзя хранить в кукисах по соображениям безопасности.
XSS может быть только по вине программиста, если программист внимательный, то он избежит данной ошибки.
UFO just landed and posted this here
А куки я считаю нормальным местом для хранения данных. А то, что у юзера могут вытащить куки трояном, то это его вина, а не программиста.

Sniffing, XSS, дополнительный траффик, отключенные куки.

И о юзерах надо заботиться, если они — ваши клиенты. Ваше заявление из разряда «плевал я на поддержку IE, нефиг пользоваться левым браузером».
то есть вы хотите сказать, что в сессиях лучше и безопаснее хранить к примеру логин и пароль, чем в куках?
Зачем хранить логин и пароль? Храните ID пользователя.
На крайняк - храните в зашифрованном виде.
> Зачем хранить логин и пароль?
затем, чтобы человек после авторизации мог не вводить свой пароль пару дней. К примеру вот прям тут(на етом сайте) в куках хранится hha - это ID юзера, и hhb - пароль в зашифрованом(md5) виде. Если я не ошибаюсь конечно.

> На крайняк - храните в зашифрованном виде.
А если так, то какую вы здесь видеть дырку?
<?
// Для наглядности
$login = "12345"; // Логин
$pass = "mypass"; // Пароль
$ip = $_SERVER['REMOTE_ADDR']; // IP
$hash = md5($pass.$ip); // Получаем зашифрованный пароль и айпи в одну строку. То есть теперь у нас пароль привязан к IP. И если его украдут у пользователя, то на другой машине он будет безполезен.

// Сохраняем инфу в куки
setcookie("login", $login, ...
setcookie("pass", $hash,...
?>

На странице проверки авторизации:

if(isset($_COOKIE['login']) and isset($_COOKIE['pass']))
{
// Запрос, который вытащит пароль юзeра с ID $_COOKIE['login']
mysql_query....


// Представим, что в переменной $user['pass'] лежит пароль вытащенный сейчас из БД
if(md5($user['pass'].$_SERVER['REMOTE_ADDR']) === $_COOKIE['pass'])
{
// юзер авторизован
}
else
{
// не авторизован
}
?>
В вашем примере есть дыра.
Во первых, могут (и наиболее вероятно) украсть из локальной подсетки с тем же IP.

Во вторых выдавая хеш пользователю, вы раскрываете алгоритм шифровки, что не хорошо.


А зачем вам хранить пароль?
if (isset($_SESSION['userid'])) $db->get('... WHERE `id` = '.$_SESSION['userid']));

Зачем проверка на пароль вообще?
Эмм, как зачем. :D Вы когда где-нибудь авторизируетесь, вы что только логин вводите?

> Во вторых выдавая хеш пользователю, вы раскрываете алгоритм шифровки, что не хорошо.
Я не спорю, можно создавать рандомный хеш при авторизации, сохранять его в БД и ложить в куке и потом просто сверять два хеша.
Я не спорю, можно создавать рандомный хеш при авторизации, сохранять его в БД и ложить в куке и потом просто сверять два хеша.

Так это и есть сессии!
session_register это и делает без лишних телодвижений.

Идентификатор сессии и есть авторизация.
ну у сессии ограниченное время жизни. как я понимаю, потому куки и нужны
У меня отключены куки. Что мне делать? =)
у меня нет интернета, что мне делать?
/* люди до сих пор размышляют, что делать с теми у кого отключены куки, но таких уже не осталось */
ну как же не осталось - у нас портал 4.2К пользователей, так я как-то системку для опросов и тестов написал, с использованием куки, так потом выяснилось, что у многих они отключены, пришлось потом исправлять.
Даже не ID пользователя можно хранить в куках и зашифрованный пароль, а ID авторизации (не сессии) и md5 какой-то случайной строки.
Накой вообще что-то хранить в куках, если есть сессии?
Максимум что я храню в куках - дату последнего визита или на других проектах - уникальный ID посетителя (чтобы статистику обсчитывать более точно).
В куках хранить инфу только для автоматического захода через N-ное количество времени. У вас же сессии 2 недели не живут? ;)
Этого ещё не хватало, чтоб они жили по 2 недели ))
Т.н. сеансовый ключ. Чем вам не нравится PHPSESSID, при условии VDS или приватного сервера, конечно?
Не понял, при чём здесь выделенные и приватные сервера? Сессиями пользуюсь во всю. Куками гораздо реже. Но именно для автоматического захода спустя большой промежуток времени, предпочитаю хранение инфы в куках.
На шаред-хостинге легко украсть содержимое сессии, украв куку.

Как вы передаете сессионный ключ между страницами?
В куках. Ограничиваю время жизни сессии. Да и у меня собственный сервер.
папка tmp имеет права доступа 0777 и её легко может прочитать любой скрипт, находящийся на том же хостинге. Дальше рассказывать?
Много ли народу берёт под свои проекты VDS?
"20 долларов то не лишние..." :)
Мне проще отдать $20, зная, что это будет мой (почти) сервер, в котором я сам буду ставить Apache(Nginx), PHP, MySQL(SQLite,PostgreSQL) и никакой супер-админ не поставит какую-нибудь хрень.

За всех, конечно, сказать не могу.
Во-во. Мне тоже проще, но другим - нет )
Да.

Но пароль-то зачем хранить в любом случае?

Если очень нужно (зачем?), то храните хеш. По сути данные в сессии хранятся в файловой системе так же, как БД, так что никакой опастности, если только не будет перехвачен session ID, но для этого можно добавить привязку к IP, User-Agent, ...
А вам не кажется, что чтобы перехватить session ID нужно одинаково столько же времени, сколько и на кражу кук? Ну разве что, вы будете передавать сессион ид в УРЛ... но это сейчас не в моде + юзер может сам случайно передать свой ID сессии злоумышлинику...
Да, но украв session ID, злоумышленник будет иметь просто тупой хеш, а украв пароль из куков, или даже его хеш, злоумшленник будеть иметь более важную информацию :)
Если плюшки-печенюшки выключены, то session id всегда передаётся по url.
Разберитесь с механизмом работы сессий.
Кто вам сказал, что я не знаю об этом?
> Ну разве что, вы будете передавать сессион ид в УРЛ... но это сейчас не в моде

Вот тут написано, что Вы этого не знаете. Модно/немодно - это размышления не программиста, а блондинки в супермаркете.
где можно почитать про это =) ?
про программистов и кодеров
Поищите в Гугле. Не помню просто на каком сайте это пробегало.
+ по урл передовать не безопасно
+ разве тока блондинки носят модный шмот? а да точно, я забыл, программисты строго классику:D
1. Согласен.
2. Ошибаетесь =) Не поверите, иногда программисты занимаются не только программированием. Я вот например ещё резидент в одном крупном клубе )

Короче, мы уже начали с Вами придираться к образным фразам. Давайте оставим это занятие для других...
В итоге мы получаем, что хранение пароля и логина в сессиях и куках одинаково опасно, только сессии ещё могут и положить сервак, если грамотно DDOSнуть и тогда их кол-во перерастет за несколько сотен тысяч..
В итоге чего? О_о

Говорю же, нельзя давать даже хеш пароля! Взламывается даже md5!
Здесь я согласен, возможен вариант как я описал выше "10 июля 2007 15:29 "
А чем он отличается от мною с самого начала предлагаемых сессий?
тем что сессиями можно уложить сервер, читайте ниже "10 июля 2007 15:37"
Есть ли взлом md5 без банального брутфорса?
Гуглил-гуглил, не нашел ничего интересного :(
1 000 000 сессий по 200 байт это 200 Mb. Согласен, никакой сервак не выдержит. :))
Проконсультируйтесь у сис.админов по этому поводу.
Сессии создаются в ТМП. Время жизни 30 минут.

Каждый раз при создании сессии проверяется уникальность сгенерированного кода. 5000 файлов практически уводят сервер в даун
Уникальность проверяется чтением папки ТМП, сосбственно чтение и убивает сервер
Похоже на страшную сказку по запугиванию юнцов-кодеров. Это абсолютная чушь. Да и кстати вы можете сами указывать session_name.
Нет не сказка, об этом мне рассказывал человек Tibor - который когда-то создал самый быстрый и безопасный клон нюки - xNuke. Также он давно занимается создание и поддержкой проектов, с очень большой посещаемостью.
> Это абсолютная чушь
Аргументы?
Мне как раз очень нужно это все, спасибо. Только вот появилась надежда на продолжение. =)
есть очень хорошее правило - никогда не доверять тому, что отправил пользователь через браузер. Абсолютно всё нуждается в проверке.

Есть два относительно надёжных места хранения инфромации - это сессии и БД
Слишком сумбурно и непоследовательно.
Пишется "не делайте так", "потенциальная опастность", а объяснений "почему" нет.
В пятой версии появилась константа E_STRICT, показывающая строгие замечания по поводу кода. Разумеется, их желательно видеть, но они не входят в E_ALL, потому будем использовать числовое значение error_reporting(8191)

Только что константы были, теперь какое-то непонятное число. Почему не
error_reporting(E_ALL | E_STRICT)?
И правда, непонятно. Я редактировал после, потому получилось бессвязно.

PHP 4 не знает E_STRICT и будет ругаться. А используя числовое значение, мы уверены в корректной работе.
а кто мешает проверить на наличие E_STRICT и при его отсутствии создать его с нужным значением?
поправьте ошибку в заголовке.
"Безопасности", а не "Безопастности".
лучше не нужно, это сразу очень сильно характеризует адекватность статьи...
"Поэтому их необходимо перехватывать и упорядычивать."
ошибки не надо перехватывать, их надо исправлять

"Создаём функцию для фильтрации (mysql_real_escape_string - длинно)"
переименование функций - зло, пользуйся редакторами с автокомплитом

"Не проверяйте на наличие плохих символов. Проверяйте на отсутствие нехороших. Вместо"
разницы абсолютно никакой, всё зависит от ситуации

"Данный материал для начинающих программистов (ИМО, до 12-18 месяцев стажа)."
добрая половина материала вообще не рекомендуется к прочтению, как растлевающая умы молодым и неокрепшим в профессиональном смысле разработчикам
> добрая половина материала вообще не рекомендуется к прочтению, как растлевающая умы молодым и неокрепшим в профессиональном смысле разработчикам
Согласен.
добрая половина материала вообще не рекомендуется к прочтению, как растлевающая умы молодым и неокрепшим в профессиональном смысле разработчикам

/me морг-морг глазами
В смысле?
в смысле - статью новичкам лучше не читать, им будет только хуже...
ты это поймёшь, чуть попозже...
и не надо язвить, к критике надо относиться с пониманием
К критике в стиле «подрастёшь — поймешь» и обращению на «ты», думаю, можно относиться и с иронией. ;)
эм... тебя так задевает обращение на вы?
хм...
ну если ты действительно не принял (не понял) 3 моих замечания, разве это не повод рассуждать о том - что ты поймёшь их позже (см. дорастёшь) не?
Просто, как я видел раньше, на хабре принято обращаться на «вы». Кроме того, в контексте «подрастёшь — поймёшь», переход на ты имеет дополнительный эмоциональный окрас. А в принципе мне до лампочки, так что можете общаться и на ты :)

Конструктивно рассмотрим ваши замечания:
"Поэтому их необходимо перехватывать и упорядычивать."
ошибки не надо перехватывать, их надо исправлять

То-есть ваш код такой идеальный и 100-процентно хороший, что никогда и нету таких ситуаций, когда он вывалится с ошибкой? Например перегруз БД, когда она плюётся «Невозможно выполнить»?
"Создаём функцию для фильтрации (mysql_real_escape_string - длинно)"
переименование функций - зло, пользуйся редакторами с автокомплитом

Согласен, но я имел ввиду немного другое, и сейчас дополнил статью.
Фильтрация данных может измениться, может произойти переход на другую БД, а менять «myqsl_» на «foosql_» во всём коде даже с автозаменой нехорошо.
"Не проверяйте на наличие плохих символов. Проверяйте на отсутствие нехороших. Вместо"
разницы абсолютно никакой, всё зависит от ситуации

Разница есть. Разрешая только a-z0-9_, мы уверены, что эти символы ничего плохого не сделают. Запрещая '"`\, мы можем забыть запретить нулл-байт или другие контрольные символы.
"Данный материал для начинающих программистов (ИМО, до 12-18 месяцев стажа)."
добрая половина материала вообще не рекомендуется к прочтению, как растлевающая умы молодым и неокрепшим в профессиональном смысле разработчикам

Это неконструктивное замечание. =)
"То-есть ваш код такой идеальный и 100-процентно хороший, что никогда и нету таких ситуаций, когда он вывалится с ошибкой? Например перегруз БД, когда она плюётся «Невозможно выполнить»?"
я не говорил про Ваш код, я не говорил про свой код. Я лишь откомментировал Ваш совет новичкам
"Поэтому их необходимо перехватывать и упорядочивать."
После этой фразы начинающие программисты будут считать, что перехват и умалчивание ошибок - нормальная практика, вместо того, что бы писать хороший код

"Фильтрация данных может измениться, может произойти переход на другую БД, а менять «myqsl_» на «foosql_» во всём коде даже с автозаменой нехорошо."
экранирование переменных - меньшее что Вас будет заботить при переходе на другую СУБД. Даже при использовании DBAL, так или иначе диалект sql будет иным

"Разница есть. Разрешая только a-z0-9_, мы уверены, что эти символы ничего плохого не сделают."
проверяя preg_match('/^[a-z]+$/', $var); или preg_match('/[^a-z]/', $var); мы в варианте 1 проверяем на вхождение в дозволенный интервал, в варианте 2 - на вхождение в недозволенный. Оперируя вашей фразой - вариант 1: проверка на отсутствие плохих символов, 2: проверка на наличие плохих
т.е. как раз тот вариант - когда разницы никакой

"Это неконструктивное замечание. =)"
хм.. как бы то ни было - я бы не посоветовал её читать никому из начинающих. в этом плане гораздо полезнее тот же phpfaq.ru
>>"Поэтому их необходимо перехватывать и упорядочивать."
>После этой фразы начинающие программисты будут считать, что перехват и умалчивание ошибок - нормальная >практика, вместо того, что бы писать хороший код
До появления исключений, многие эмулировали их через trigger_error, и это нормально. Излишние проверки часто замусоривают систему, особенно работе на разных слоях, приходится дублировать проверки везде. Перехват ошибок нормальная практика и как-то странно с этим спорить. Идеального кода не бывает.

Насчет проверки данных. Различают два понятия: валидация и фильтрация. То, что описано в статье именно валидация, т.е. проверка по белому списку. С другой стороны фильтрацию тоже никто не отменял. У них логически разные предназначения
Пример: пользователь пишет комментарий (e-mail и текст). E-mail нужно проверять по
Обрезалося! Добавьте, пожалуйста!

Предпологаю, что вы хотели сказать, что email надо вылидировать, а текст фильтровать, и будете правы.
Да именно это и хотел. Не дополните ли статью на тему фильтрации? А еще бы хорошо заменить все таки авторизацию, на аутентификацию, тоже разные вещи все таки.
Поправил.
И разницу между авторизацией и аутентификацией подметил. :)
UFO just landed and posted this here
"переименование функций - зло, пользуйся редакторами с автокомплитом"
а повышать читаемость кода тоже зло? или делать обвертки с возможностью дополнить их в будущем?
стороннему программисту, который будет читать код - проще понять нативные функции, чем никому не нужные врапперы. так что читабельность тут только страдает.
К примеру, if (is_email($data)) гораздо читабельнее, чем if (preg_match('/QLNqufQPPIDHQWODn,amnDWALjdnqdQLOWHFQLO/',$data)) =)
не юлите
я говорил о конкретном частном создании алиаса на функцию, а не об инкапсуляции сложной логики
Не проверяйте на наличие плохих символов. Проверяйте на отсутствие
нехороших.

- явно имелось ввиду:
Не проверяйте на наличие плохих символов. Проверяйте на отсутствие
хороших.
Тоже внесу несколько своих замечаний:
1. E_STRICT - вещь замечательная хотябы потому, что выдает замечания по depricated (устаревшим) функциям (начинающему программисту пригодится).
2. Можно ловить ошибки и errorHandler, однако куда красивее display_error в нет, а писать в логи, естественно после запуска. Иначе пользователь у вас будет видеть всегда "Мол, «простите, облажались маленько»...", а вы будуте часами искать ошибки.
3. Про register_globals, ну не знаю кто ее еще применяет...
4. По поводу слешей: отключайте меджик слеши вполучаемых переменых и используйте mysql_real_escape_string, зачем огород городить и придумывать велосипед...
5. И инклудах используйте define, так советует PHP.
6. Прор куки согласен, храните в сессии.
1. Согласен. Я так и написал. :)
2. На мой взгляд, позволять пользователю видеть пустую страницу вместо извинения — очень плохо. Он будет неудомевать, пробовать заново. А в логи моя функция так и так пишет. Вы бы в начале прочитали её ещё раз. ;)
4. Начинающие программисты вряд ли имеют доступ к глобальному конфигу и знания, как выключить magic_quotes. Очень часто вы находитесь на shared сервере, а set_ini тут не работает, поскольку к моменту выполнения set_ini magic_quotes уже поработали.
5. Не могли бы вы перефразировать? Никак не пойму. :(
2. Естественно выводить что-то, я разве против. Где у вас там запись в логи?
4. Сложно найти хостинг где не работает .htaccess и в нем нельзя прописать magic_quotes в оф.
5. Попробую объяснить:

<?php
$x = '/usr/local/php/includes';
include($x.'include.php');
?>

Unsafe use of variable in call include()/require() (line 4)
2. "// Запись в БД или отсылка по почте вебмастеру."
4. Мммм... Согласен.
5. А что делать, если я динамически выбираю модуль? Грубо говоря из $_GET?
2. log_errors проще, а еще представьте ту ситуацию когда у вас отсылка по почте или запись в БД тоже будет выдавать ошибку, что тогда:)
5. Проверяйте, конечно, хорошенько что там инклудите:)
В стиле «давай сделаем два ящика — на рамблере и на mail.ru, сделаем переадресацию с одного на другой и обратно и отправим одно письмо!» :)
UFO just landed and posted this here
Кстати я из БД вытаскиваю.
4. Начинающие программисты вряд ли имеют доступ к глобальному конфигу и знания, как выключить magic_quotes. Очень часто вы находитесь на shared сервере, а set_ini тут не работает, поскольку к моменту выполнения set_ini magic_quotes уже поработали.

В крайнем случае можно использовать старый как мир способ

set_magic_quotes_runtime(0);

function strips(&$el)
{
if (is_array($el))
foreach($el as $k=>$v) strips($el[$k]);
else
$el = stripslashes($el);
}
if (get_magic_quotes_gpc())
{
sk_ga_strips($_GET);
sk_ga_strips($_POST);
sk_ga_strips($_COOKIE);
sk_ga_strips($_REQUEST);
if (isset($_SERVER['PHP_AUTH_USER'])) sk_ga_strips($_SERVER['PHP_AUTH_USER']);
if (isset($_SERVER['PHP_AUTH_PW'])) sk_ga_strips($_SERVER['PHP_AUTH_PW']);
}


Вставить перед исполнением каждого php-скрипта. Лучше, в отдельный файл это запихнуть и каждый раз подключать.

Недостатки, конечно, налицо, но если сайт не такой и посещаемый, то вполне приемлимое решение.
Ну да... Вот он в статье и приведён. :)

array_map > foreach
UFO just landed and posted this here
Я согласен, что такой информации много. Но её должно быть много. Потому начинающие как раз и не знают, что искать. И надо, чтобы они попадали на такую информацию.

И мне достаточно одного единственного "спасибо" в топике, чтобы понять, что не зря я это написал, что бы там профи не рассказывали. :)
Карма, в отличие от этого, мне до лампочки. ;)
UFO just landed and posted this here
ого, нехило! и оно растет! уже 946, прям как в гугле
Хорошо говорите, респект.

Кстати, за линк спасибо. :)
> Во первых, функция error_reporting позволяет нам решить, какие ошибки мы хотим видеть.
Я хочу видеть все, но что бы пользователь не видел никаких, поэтому использую:
http://ru2.php.net/manual/ru/ref.errorfu…
Статья неплохая, однако: было б лучше, если Вы обосновывали некоторые положения простыми примерами, так сказать "на слониках". Например, касательно register_globals: то что это плохо Вы сказали, а _реального примера_ того, как это могут использовать для взлома нет.
Отличная статья. Я даже не начинающий, так, любитель-самоучка, мне было интересено. :)
Хорошая статья. Рекомендовал бы начинающим.)
Классная статья. Сейчас мне нужно приступать к разработке и я хорошо освежил безопасность в голове. Спасибо.
эту информацию надо знать, а не помнить ;)
Автору - респект. Когда я начинал заниматься PHP, то таких мануалов не было и приходилось всему учиться на своих ошибках.

Кстати, новичкам ещё будет полезен вот этот сайт: http://www.omsk777.ru/all.php?act=web
Новичкам больше будет полезен ман и phpclub
Я тоже люблю сказать RTFM. Только я так отвечаю на вопросы. В ман можно лезть, когда знаешь, за чем лезешь. Просто так перечитывают ман никак не начинающие.
1. Изучая предмет не системно, а по принципу how-to, больших результатов не достигнешь.
2. RTFM это одно, а профессиональное комьюнити - несколько иное.
3. Есть поиск по этому комьюнити, выдающий решения по большинству вопросов, в том числе и по безопасности.
4. По PHP очень удобный ман.
5. Приведеный в пример сайт - потуги таких же "профессионалов", которые, не научившись языку, раздают советы направо и налево.
6. "Просто так" ман никто не перечитывает.
Я просто так перечитываю ман. ._.
Если у меня кто-то из работников отвечает клиенту RTFM, то получает наряд вне очереди :))
Мы сейчас о клиентах или о программистах говорим? Я программист и смело посылаю всех, включая директора, к RTFM. Но дело не в этом! Я никого не посылал читать ман, если человек является ах***ным программистом, тогда конечно... зачем ему читать ман, он же и так все знает.
А если серьезно... Меня бесят эти ах***но профессиональные сайты, на которых опубликованы статьи, раскрывающие тему "2*2=4", преподносящие предмет обсуждения как бином Ньютона или решение теоремы Ферма, блин, пиз*ец, сенсация, оказывается magic_quotes_gpc надо вырубать.... А кто-нибудь здесь знает вообще, что такое GPC, и как это расшифровывается?
Нет, разумеется, давайте каждому (здесь есть тег, чтоп слова зачоркивать? Хотел вписать "лизать жопу") объяснять вещи, которые должны срабатывать на автомате... Наряд вне очереди... Хе-хе, Вы пойдите хорошего спеца по PHP найдите, потом будете раз 88 (восемьдесят восемь) думать насчет нарядов. Кстати, это ведь Вы написали статейку про Code Style (мол, надо то комментировать, это комментировать, отступы скобочки и т.д.). Вероятно, чуваки прозябающие в "нарядах", не знают, что такое "стиль кодирования", и мне от этого вас откровенно жаль.
Да верю, верю, что Вы круты и смелы :-) Много видел таких крутых и смелых.

У нас пишут не на PHP, и я не отвлекаю своих людей от клиентских проектов на лично мои интересы и хобби ;-)

Тег, чтоб слова зачеркивать? RTFM('HTML') :-)
Статья понравилась, спасибо за неё. Тут, по крайней мере, собраны все основные источники небезопасности приложений: читать о каждом подробнее можно уже в других публикациях.

Немного расстроил стиль большинства критиков: вместо исправления ошибок, лишь указывают на них (а ведь люди квалифицированные, могли бы предложить свои конкретные добавочки). Хотя, безусловно, имеются и содержательные комментарии. За них тоже большое спасибо.
Господа, не буду оригинален, но пора на свалку языки, допускающие подобное.
Пока все нормальные языки двигались в сторону контроля типов и строгих конструкций, скриптовые языки всегда пытались услужить программистам, убирая "ненужную" декларативную писанину. Использовать в веб среде язык, не делающий существенного различия между кодом и данными и допускающий динамический code-injection просто безумие. Поэтому любой php скрипт по дефолту остается дырявым, пока не доказано обратное. Я призываю всех обратить внимание в сторону Java EE: JSP/JSTL и фреймворков типа JSF.
Очередной холивар? Давайте.
Откуда это нормальные языки двигались к строгим типам? От нетипизированных ассемблеров?
Вам не кажется, что изначально строгие типы, это ограничение компилирующих языков?
Что значит "не делающий существенного различия между кодом и данными"? Вы знакомы с функциональным программированием и т.п? PHP по "неделанью различий" очень далеко до многих языков. Хотя вы можете считать их всех ненормальными.
Поэтому любой php скрипт по дефолту остается дырявым, пока не доказано обратное

Хватит выдвигать безумные лозунги, их тьма. Мотивируйте.
Кстати, что вы подразумеваете под "скриптовыми" языками?
Вероятно интерпритируемые языки =)
А PHP не просто интерпретатор, а транслирующий. Java и C#, кстати, в некотором смысле тоже. Однако, различие интерпретатор/компилятор влияет только на скорость исполнения, но никак не на дырявость, типизированность и тому подобное.
Скрипт, же переводится, как сценарий. Скрипты выполняются в других системах, манипулируя уже существующими объектами. Браузерный Javascript - скриптовый язык, а PHP никакой не скриптовый.
Я-то это понимаю...
Но PHP всё-таки скриптовый язык... У него даже это по-моему в документации написано.
Документация нагло вводит в заблуждение =)
Всё может быть, но я склонен верить ей - не зря же её писали +)
Про данный случай ничего не говорю, но вообще в РНР документации порой проскальзывают косяки, особенно в переводной.
PHP скриптовый и даже то, что парсенный код может повторно запускаться при установки некоторого софта никак на это не влияет.
Эх... vi против emacs, кто-нибудь? :)

Я не знаю JSP, JSF, но я думаю, что человек умеющий может написать дырявый и опасный код и там, не правда ли? :)
UFO just landed and posted this here
а никакой вступительной статьи только для "Java EE: JSP/JSTL и фреймворков типа JSF" нет? что-то я ничего толкового найти не смог.
Еще бы :)
В J2EE Tutorial-е про JSP/JSTL/JSF первые 500 страниц.
Вот мощь Enterprise-технологий :)
в контексте о magick quotes:
Для борьбы с неправильными разработчиками, разработчики PHP решили все эскейпить. Теперь разработчики защищаются от разработчиков PHP выключением magick quotes )))
Разработчики 300 раз уже извинились за magick quotes и register_globals, и safe_mode. Ну хватит их уже пинать. Все эти опции включаются обычно недалёкими админами.
Спасибо, я как раз начинающий в php, статья понравилась.

Насчет error_reporting(8191), так конечно нельзя, а что если код будет читать кто-то не читавший с вашу статью :) и попробуй догадайся, что-это.

Стойт написать, что-то вроде:

if(!defined(E_STRICT)) define(E_STRICT, 2048);

хотя вам видней, я же начинающий
if (!defined("E_STRICT")) define("E_STRICT", 2048);
кавычки не забываем :)
конечно, просто непривычно брать в кавычки имена переменных и констант
Это еще не имя константы :)
Хм... Начинающие так не пишут =) Новички бы понаставили кучу {} скобок и писали бы без пробелов после запятых =)
Да. я это понял уже после своего комментария ) Просто у меня php был первым языком.
Вы говорите об оформлении кода. Это приходит со временем. На алгоритм же не влияет никак.
Осознал уже после нажатия кнопки "добавить" )
Не поверите, в первой редакции этой статьи было так и написано.
Но я подумал, что это излишество. Что такое 8191, можно узнать там же, где и что такое E_STRICT.
А так две дополнительных комманды.
использование magic numbers в коде - плохой стиль программирования, как ни крути. почитайте книгу Макконнелла - там это рассмотрено очень подробно.
Хорошая статья, напомнила мне мой период паранои в первые месяцы программирования на PHP.

Пожелания к статье: больше примеров "на слониках".
Например, сказано что register_globals - зло, а примеры взлома с их использованием не приведены.
Фраза "валидируйте все, что вводит пользователь" пугает своей сложностью =) Я бы сказал "Проверяйте" и "Trust no one" =)
Кстати, о SQL-инъекциях. Я часто использую функцию для выполнения запросов, увиденную мною в книге Котерова. Изначально расчитана на MySQL, но легко меняется и для другой СУБД.

Выглядит так:
mysql_qw('INSERT INTO users (name) VALUES (?)', $u_name);

Работает аналогично sprintf: заменяет символы ? в строке запроса (1й параметр функции) на соответствующие ему значения и выполняет запрос. Перед заменой значения обрабатываются mysql_escape_string() и заключаются в кавычки.


Код функции:

$v) {
if (!$i) continue; // это шаблон
if (is_int($v)) continue; // целые числа не нужно экранировать
$args[$i] = "'".mysql_escape_string($v)."'";
}
// На всякий случай запорняем 20 последних аргументов недопустимыми
// значениями, чтобы в случае, если число "?" превышает количество
// параметров, выдавалась ошибка SQL-запроса (поможет при отладке).
for ($i=$c=count($args)-1; $i<$c+20; $i++)
$args[$i+1] = "UNKNOWN_PLACEHOLDER_$i";

// Формируем SQL-запрос.
return call_user_func_array("sprintf", $args);
тогда уж лучше использовать класс DB simple все от того же Дмитрия Котерова http://dklab.ru
Ну классы - это уже для продвинутых, мы говорим о начинающих
Начинающим нужно начинать с классов.
UFO just landed and posted this here
UFO just landed and posted this here
Абсолютно согласен, при грамотном использовании ООП самые большие методы (функции) не более 20 строк получаются, при том с предельно ясной логикой. К тому же, на число строк в большей степени может влиять желание вписать код в 80тисимвольный предел по ширине для удобочитаемости и вот примерно такие sql запросы:

SELECT COUNT(*) AS `before`
FROM `some_table`
WHERE
`some_id` = '{$this->somvar}' AND (
`someoneelsevar` > '{$this->someproperty}' OR
(
`voices_number` = '{$this->onemoreproperty}' AND
`id` user_id}'
))

Уже не говоря о перевязке двух и более таблиц с различными JOIN'ами, группировками и т.д.
Ой, из-за маленького окошечка с синтаксисом напутал :(
UFO just landed and posted this here
Ну из-за одного запроса, имхо, менять привычный БД-Струмент не стоит. К тому же некоторые фичи DbSimple, заявленные как преимущества, мне кажутся сомнительными.
и как на мускуле эти джойны работали? они сервак не ложили?
У начинающего должно точно в голову засесть объектно-ориентированное программирование, чтобы он не видел смысла писать что-то без использования классов. Сам же потом благодарить будет.
UFO just landed and posted this here
Речь идет о технологии Placeholder'ов, которая поддерживается, например такой штукой, как PEAR::DB и последователями (точно не помню ADODB кажется тоже держит плейсхолдеры), а также некоторыми БД на уровне их API для PHP, кроме того, смотрим про PDO Functions в мане
Да, забыл упомянуть названия, спасибо.
Может быть стоило просто дать ссылку на http://ru.php.net/manual/ru/security.php?
Может просто было написать RTF PHPM и не писать ни статьи ни камментов? =)
Хочу сказать спасибо за статью. Хотя для себя в ней ничего не прочел. Но знаю как это сложно собраться с духом и систематизировать свой опыт. Так как лишен хабара-потенции, то немогу добавить плюс. %)
Статья неплохая, как памятка, если случилась внезапная амнезия. Или тем, кто вообще только начинает, пожалуй.

Вообще, чем больше я читаю статей по PHP, тем больше убеждаюсь в том, что заинтересованные делятся на две большие группы: те, кто хотят учится программированию и те, кто хотят учится программированию на PHP. Одна аббревиатура и один предлог решают вообще все, как не удивительно. Взять хотя бы ту прелестную радость, с которой php-шники открывают уже привычные вещи. Например, статьи в духе "что такое private в классах и где это использовать". Или "зачем нужны абстрактные классы". Круто.

Автору респект, что грамотно оформляет материалы. Приятно смотреть.
Чтож вы нас (PHP-программистов) совсем за варваров чумазых держите? Разве идеология ООП и его принципы как-то принципиально отличаются в PHP, или, если чувак начал писать вызовы со "стрелочками", то он типа ОО программист на PHP?
Сюрприз: вы ушли в крайность и утрируете. Я не говорю, какие возможности предоставляет тот или иной язык. Я говорю про образ мышления и подход к разработке среднестатистического программиста.

Кстати, я сам достаточно много пишу на PHP. Потому что альтернатив, которые "стоят вообще везде" у него нет. Разве что Perl.
Да, наверное, вы правы, я погорячился. Подход среднего представителя PHP фауны сообщества обусловлен жывучестью PHP приложений, содержащих ошибки, "собачкой", выключаемыми display_errors и настраиваемым error_reporting. Отсюда лень, невнимательность исполнителя и его же пофигизм.
UFO just landed and posted this here
Видимо стоит разделять такие понятия как "php-шник" и "PHP-программист", как линуксоидов и Пользователей Linux ;)
UFO just landed and posted this here
Sign up to leave a comment.

Articles