Как стать автором
Обновить

Комментарии 33

Еще одним моментом реализация блокировки аккаунта после нескольких неудачных попыток авторизации пользователем

Идите нафиг с такими правилами. Сами открываете возможность DoS атаки на самого себя. 20 переборов пароля на каждого пользователя — и все ваши пользователи заблокированы.
Вероятно Вы правы. Стоило наверное добавить то что блокировать нужно на время по IP, а не сам никнейм. По таймауту разблокировать. Более того учитывайте что DoS атака опять же будет достаточно долгой если дать sleep, как указано было выше.

Не стоит посылать или еще что-то. Я же сказал что жду замечаний и дополнений, а не посылов. Вы указали ошибку, остальные учли. Я в том числе.
sleep тоже неверное решение, ибо у вас будут просто так простаивать потоки c PHP интерпретатором, а это потребляет много памяти, кстати это ещё один вектор для DOS атаки, хехе, я ваш хостинг с такой защитой через прокси серверы легко в даун отправлю. Почитайте про limit_req_zone для nginx или mod_evasive для apache.

Вообще советы так себе на мой взгляд:
— п.4 — антисовет (лично меня очень сильно раздражают сайты которые придумывают мне пароли, вместо этого лучше призывать к повсеместному внедрению OAuth),
— п.7 от SQL инъекций не спасёт, да и от XSS тоже вряд ли,
— а что вы имели в виду в п.8?

P.S. остальные в основе КОпетанские, и большую часть из них можно отбросить одним единственным призывом пользоваться фреймворками, где почти все эти проблемы УЖЕ решены.
Все всегда легко если уже знаешь это. Чем больше знаешь, тем больше все очевидно. И КОпетан находиться всегда рядом. =)

п.4 предлагает генерировать пароль и отправлять на почту вместо ссылки с подтверждением email. Войдя пользователь сам может сменить свой пароль на тот который захочет в настройках профиля.

п.7. Говорит вконце о наличии библиотек, которые уже занимаются чисткой и от XSS и закрытием не закрытых тегов, прочее.

п.8. Согласен, достаточно размытый получился. Говориться о том что:
1) Красивее ссылка, ее проще скопировать и отправить кому-то другому.
2) Поисковики хоть и умеют в некоторой степени отбрасывать данные из ссылки, выделяя саму ссылку, но все же ссылка становиться раздутой.
3) Видимость отправляемых данных. Большинству пользователей это ни к чему вообще, да и пользы думаю в этом мало, если и есть какая-то.

П.С. Учитывая Ваш весьма высокий уровень судя по критике, добавьте пару правил от себя =) Было бы для меня и других хорошей подсказкой. =)
4 — уже писали что большинство пользователей не будет менять пароль, соответственно будут трепать нервы по поводу восстановления паролей + запутанной для них системе логина(пожилые люди и женщины не могут со своим паролем в систему зайти, а тут ещё и какой-то предложат и что-то менять надо...) + у кого-то почта с задержкой минут в 10-15 и они тупо на ваш ресурс не попадут ибо им будет лень ждать. Тем более с чего вы взяли что можете указывать пользователю какой ему пароль выбирать, это в корне неверно.
7 — вы бы лучше дали рекомендации развёрнуто с примерами, ибо это и есть тот самый пункт из-за которого большинство уязвимостей и есть на сайтах. Собственно уже на нём можно отдельную статью написать, хехе.
8. ну-ка расскажите-ка мне, как вы передадите ссылку по которой другой человек при помощи метода POST зайдёт… =)
вообще этот пункт достаточно спорен, потому что для различных фильтров в интернет магазинах, например, очень хорошо передавать их значения в URL, ибо человек может передать дугому адрес страницы где есть уже отобранные товары интересующие его.
Очень удобная практика передавать какие-то параметры в URL в виде ЧПУ(SEF) (опять же никакие POSTы не нужны).
Ваше высказывание неверно и с точки зрения REST, хотя это должен быть основополагающий принцип работы с любым сайтом.
Также есть проблема запроса браузером в момент ухода страницы когда введены данные в поля формы, потому после сабмита форм надо делать редирект на эту же страницу, если вы планируете дальнейшую работу с ней.
теперь по вашим пунктам:
1) И длинная и короткая ссылки копируются — клик правой кнопкой + «скопировать ссылку», чем именно длинную сложнее копировать?
2) для этого есть SEF
3) я выше немного осветил этот вопрос

P.S. Я считаю что лучше идти вглубь, нежели вширь. Тем более статья уже объёмная и с большим количеством разнообразной информации, неопытного человека это только запутает, а опытный ничего не подчерпнёт.
Спасибо, принял к сведению. Не могу отнести себя к опытным, уже очевидно что проигрываю по части опыта Вам и многим другим, но все же мне лично иногда не хватало именно обширных статей, которые указывали бы куда именно кинуть свой взгляд по ширине всего вопроса и что я мог пропустить. Данный пост не панацея от всех болезней, в нем и ожидалось получить множество поправок, от действительно опытных пользователей. Теперь же, те кто будут видеть данный пост увидят то чего может еще не видели в тексте и в комментариях, на которые есть посыл в посте, увидят и то на что реально стоит обратить внимание. Возможно повторюсь, что те для кого многое здесь очевидно и неверно, уже подзабыли как сами достигали того уровнять что у них есть сейчас. У многих этот путь еще впереди.
sleep тоже неверное решение, ибо у вас будут просто так простаивать потоки c PHP интерпретатором, а это потребляет много памяти, кстати это ещё один вектор для DOS атаки, хехе, я ваш хостинг с такой защитой через прокси серверы легко в даун отправлю. Почитайте про limit_req_zone для nginx или mod_evasive для apache.

А за это спасибо =)
Нужна блокировка и по IP, и по логину. Тогда ни пользователя не взломают с парка серверов, ни кучу пользователей с одного не заблокируют.
Несколько не согласен с 4-м пунктом.
Пользователь, получив стандартный пароль, как минимум в 40-50% случаях не будет его менять на свой. Генерация пароля происходит, наверняка, с помощью простейших функций рандома (т.е. без применения криптографических функций рандома [к примеру в C# это System.Security.Cryptography.RNGCryptoServiceProvider]) А это означает, что «стандартные» пароли есть возможность относительно легко узнать…

Как вариант для «избежать» использовать (применительно к C#) криптографические способы генерации случайных чисел (я не в курсе как у php с этим дела обстоят), либо, кидать пользователю временную ссылку для подтверждения регистрации…
Спасибо за уточнение. Добавил в текст.
А еще, при восстановлении пароля, нельзя генерировать сразу же новый, т.к. зная адрес жертвы, можно доставить геморой ей, путем бесконечной инициации восстановления пароля.
Логично отправлять на почтовый ящик ссылку (опять же), по которой он «активирует» режим смены пароля… (но кажется, это уже было описано в статье)
у вас в 5 пункте:
либо автоматически генерировать пароль ему и отправлять, а он уже пусть сам его меняет авторизовавшись на сайте.

Хотя прочитав еще разок, понял, что генерировать после подтверждения через e-mail, инициации смены пароля.
В статье сводиться все к тому что отправляется ключ для смены пароля, который нужно ввести уже в следующей форме. Если пользователь игнорирует сообщение, пароль остаеться тем же. Но точно знает уже что была попытка сменить его пароль. =)
Отправлять надо ссылку где этот ключ вставляется автоматически, а при переходе на ссылку будет уже форма смены пароля. Чем меньше пользователю приходиться всякой бесполезной информации вводить, тем больше пользователей будет у ваших сайтов =)
Лимитировать количество попыток восстановления пароля на промежуток времени? =)
Если уж такие «строгие» меры использовать, то привязывать пользователя к номеру телефона… но это уже не для огромных проектов — паранойя
Да, чем больше параноя, тем больше мощностей на нее уходит. Да и с учетом что чем больше кода, тем больше вероятность ошибки в нем, легче тоже не особо становиться =) Баланс между безопасностью и производительностью. =)
А вот чтобы не парится вообще-вообще, достаточно отказаться от регистрации, заменив ее авторизацией через ВК/Фейсбук/МаилРу/Гугл — это есть у 99% юзеров (у кого нет — тот красноглазый параноик так что вряд ли он принесет пользу обычному сайту и скорее всего не будет платным клиентом), а все заботы о безопасности передаются профессионалам (хоть и сторонним сервисам но я думаю, там побольше безопасности чем у среднего сайта) + пользователь не заморачивается с новым аккаунтом
Хороший вариант. На одном сайте так и делал. Но зачастую такие моменты зависят от заказчика, а ему часто «свое» подавай. =)
Да уж… Судя по тому как ушла карма и рейтинг я скоро окажусь в полных минусах. Первый блин явно получился комом.
Да ладно, статья замечательная. Можно, конечно, попридираться по мелочам, но прекрасно подходит как правильный вектор развития, чтобы знать куда копать.

p.s. В следующей статье поругайте копирайтеров с михалковым и сможете писать ещё много полезных технических статей.
По поводу п. 1.

Применение суперпозиции хеша хоть и увеличивает время хеширования, зато одновременно и увеличивает вероятность коллизий. Поэтому лучше изначально использовать медленный алгоритм, чем быстрый несколько раз. Так на pnp.net не рекомендуют пользоваться алгоритмами md5 и sha1, предлагая хеширование blowfish.

Для генерации соли в PHP есть замечательная функция uniqid(), используя префикс можно легко и быстро получить гарантированно уникальную соль.
п. 3
Чтоб избежать «киберсквоттинга» логинов, достаточно использовать в качестве логина email с подтверждением. И ограничить время на подтверждение, например, сутками.

п. 4
По поводу этого пункта уже высказались в комментариях. Я думаю, на email надо отправлять одноразовую ссылку для «смены» пароля. Сам пароль должен будет изменить пользователь. Для пущей надежности можно проверять чтоб новый пароль не совпадал со старым.

п. 6
Очень здравая мысль. Только не надо громоздить хеши. Впрочем, я данном случае это не критично, и может быть полезно для экономии размера БД.

п. 7
Хотя вы и упоминаете библиотеки для работы с БД, но лучше в принципе убрать из этого пункта всю информацию, кроме рекомендации использовать библиотека. Для новичком было бы здорово привести примеры библиотек (хотя бы фрймворки из п. 13).

п. 19
Сейчас в веб-разработке очень актуальна денормализация БД с целью ускорения запросов. Неплохо бы это упомянуть.

п. 21
Достаточно спорное утверждение насчет JOIN. Очень сильно зависит от конкретной ситауции. Бывает, наприер, два последовательных SELECT быстрее.
Спасибо. Обо всем кратко и точно =) Внес ваши правки в текст. =) Так собственно материал и оттачивается до эталонного состояния, в котором уже сейчас есть действительно много полезного.
Хороший, сборник рецептов, спасибо!
Но с грамотностью, конечно, бедаа.
п.1. В PHP рекомендуется использовать функцию crypt. Про md5 уже давно пора забыть. С приходом пхп 5.5 будут уже встроенные функции для задания пароля.

От апача можно избавиться и заменить на php-fpm.

Нормализация? Не, не слышал, особенно на больших объемах данных и росте проекта. Денормализация как раз более актуальна.

Индексировать поля надо с умом, иначе можно добавить много проблем самому себе же. Не каждый индекс приносит добро. Сначала надо профилировать медленные запросы и смотреть их EXPLAIN и уже только после этого принимать решение насчет создания ключей и каких именно.

п.8. Что значит ничего лишнего? Через просмотр хедеров виден и Request и Response, где все видно и отлично видно.

п.7. Использование strip_tags — имхо, зло. Во-первых даже потому, что при невалидном вводе вы можете потерять часть текста, который будет вырезан функцией:

Because strip_tags() does not actually validate the HTML, partial or broken tags can result in the removal of more text/data than expected.


Поэтому наш способ (и имхо, правильный) — экранирование, превращение в HTML entities (htmlspecialchars()), но никак не вырезание, это злейшее зло.

п.22. Целостность легко достигается с помощью FOREIGN KEY и ON DELETE CASCADE и еже с ними. Для этого конечно нужна будет InnoDB или производные (XtraDB etc)

п.25. Если сайт разрастается и нагрузка растет — самое время перейти на PerconaDB — форк MySQL, оптимизированный под нагрузки. MariaDB является альтернативой, имхо, только для желающих использовать MyISAM.
Спасибо. Вынес поправку к п.1 в текст пунктом 0.

п. 22. Согласен. Пункт и предпологает рассмотрение методов достижения целостности с помощью ключей где это возможно или же продуманных алгоритмов сохранения целостности в случае невозможности использования ключей. Основная суть не пропустить как-раз таки накопление муссора.=)
п. 25 может разрозить холивар если будет указывать на что-то конкретное, всегда найдутся противники для любой СуБД, по этому надеюсь лишь что пользователи на свое рассуждение рассмотрят те или иные реализации со всеми вытекающими в конкретных статьях по каждой из них сами. =) Это материал далеко не одной статьи. Но себе на заметку взял.
Забавное утверждение, вы бы хотя бы поставили MariaDB и посмотрели. Там есть тот же самый движок XtraDB со всеми вытекающими плюсами и минусами + свой движок Aria + они ещё оптимизатор постоянно прокачивают, а вот про PerconaDB я не уверен что они этим занимаются. Единственное отличие перконы что я вижу — кластеризация, у марии вроде бы нету ещё решения для этого, но большинству людей это попросту не нужно.

P.S. у меня на двух хостингах стоит MariaDB и в новых проектах ни одной MyISAM таблицы нет
столько навалено, что неясно, кому это вообще адресовано? Совершенно точно можно заявить, что один человек почти никогда не разберётся со всеми советами. Тут как минимум нужен хороший админ + хороший программист.
В целом советы дельные, но когда речь идёт о паролях, то нелишним было бы упомянуть про bcrypt и PBKDF2.
Ну одна из идей самой статьи показать человеку какой-то пробел в знаниях, если он что-то пропустил. )) Для себя я уже отметил достаточно много пробелов согласно комментариев. Я понимаю что многие отнесутся к попытке быть хорошим админом и одновременно хорошим программистом скептически, но думаю что это не невозможно. =)

Спасибо. Упомянул =)
Все пароли из маленьких латинских букв и цифр длинной от 4 до 7 цифр захешированные с солью в md5(md5()) на соверменном общедоступном железе можно перебрать за меньше чем минуту, потому говорить о «существенном увеличении безопасности в случае утечки» при использовании md5(md5()) глупо и безответственно.
Несколько ранее был добавлен пункт 0, подсказанный пользователями. В нем же уточнялось что во всех пунктах ниже md5 используется только как пример. Но за ссылку и доп. инфу спасибо =) принял к сведению.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории