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

Пользователь

Отправить сообщение

Защита от SQL-инъекций в PHP и MySQL

Время на прочтение26 мин
Количество просмотров255K
К своему удивлению, я не нашёл на Хабре исчерпывающей статьи на тему защиты от инъекций. Поэтому решил написать свою.

Несколько пространный дисклеймер, не имеющий прямого отношения к вопросу
Давайте признаем факт: количество статей (и комментариев) на тему защиты от SQL-инъекций, появившихся на Хабре в последнее время, говорит нам о том, что поляна далеко не так хорошо истоптана, как полагают некоторые. Причём повторение одних и тех же ошибок наводит на мысль, что некоторые заблуждения слишком устойчивы, и требуется не просто перечисление стандартных техник, а подробное объяснение — как они работают и в каких случаях должны применяться (а в каких — нет).

Статья получилась довольно длинной — в ней собраны результаты исследований за несколько лет — но самую важную информацию я постараюсь компактно изложить в самом начале, а более подробные рассуждения и иллюстрации, а так же различные курьёзы и любопытные факты привести в конце. Также я постараюсь окончательно развеять множественные заблуждения и суеверия, связанные с темой защиты от инъекций.

Я не буду пытаться изображать полиглота и писать рекомендации для всех БД и языков разом. Достаточное количество опыта у меня есть только в веб-разработке, на связке PHP/MySQL. Поэтому все практические примеры и рекомендации будут даваться для этих технологий. Тем не менее, изложенные ниже теоретические принципы применимы, разумеется, для любых других языков и СУБД.

Сразу отвечу на стандартное замечание про ORM, Active record и прочие query builders: во-первых, все эти прекрасные инструменты рождаются не по мановению волшебной палочки из пены морской, а пишутся программистами, используя всё тот же грешный SQL. Во-вторых, будем реалистами: перечисленные технологии — хорошо, но на практике сырой SQL постоянно встречается нам в работе — будь то legacy code или развесистый JOIN, который транслировать в ORM — себе дороже. Так что не будем прятать голову в песок и делать вид, что проблемы нет.

Хоть я и постарался подробно осветить все нюансы, но, вполне возможно, некоторые из моих выводов могут показаться неочевидными. Я вполне допускаю, что мой контекст и контексты читателей могут различаться. И вещи, которые кажутся мне сами собой разумеющимися, не являются таковыми для некоторых читателей. В этом случае буду рад вопросам и уточнениям, которые помогут мне исправить статью, сделав её более понятной и информативной.

Ещё только начав интересоваться темой защиты от инъекций, я всегда хотел сформулировать набор правил, который был бы одновременно исчерпывающим и компактным. Со временем мне это удалось:

Правила, соблюдение которых гарантирует нас от инъекций


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

Всего два пункта.
Разумеется, практическая реализация этих правил нуждается в более подробном освещении.
Но у этого списка есть большое достоинство — он точный и исчерпывающий. В отличие от укоренившихся в массовом сознании правил «прогонять пользовательский ввод через mysql_real_escape_string» или «всегда использовать подготовленные выражения», мой набор правил не является катастрофическим заблуждением (как первое) или неполным (как второе).

Но вперёд, читатель — перейдём уже к подробному разбору.
Читать дальше →
Всего голосов 128: ↑98 и ↓30+68
Комментарии97

Настройка виндового веб-сервера без RDP

Время на прочтение4 мин
Количество просмотров5.1K
Совсем недавно понадобилось настроить очередной веб-сервер. Как раз в это время у меня было весеннее обострение PowerShell. В общем, в качестве небольшой разминки, я решил настроить веб-сервер без RDP.
Читать дальше →
Всего голосов 81: ↑61 и ↓20+41
Комментарии56

Сделай сам: SQL JOIN на Java

Время на прочтение7 мин
Количество просмотров84K
Я часто собеседую разработчиков и часто задаю им простой, как кувалда, вопрос — как внутри работает JOIN в SQL? В ответ я обычно слышу бессвязное мычание про волшебные деревья и индексы, которые быстрее. Когда-то мне казалось, что каждый программист специалист должен знать то, с чем работает. Впоследствии жизнь объяснила мне, что это не так. Но мне все еще не понятно, как можно годами теребить базёнку, даже не догадываясь, а что там у нее «под капотом»?

Давайте проведем ликбез и вместе посмотрим, как же работают эти джойны, и даже сами реализуем парочку алгоритмов.

SQL JOIN
Читать дальше →
Всего голосов 82: ↑58 и ↓24+34
Комментарии128

Немного об архитектурах программного обеспечения

Время на прочтение7 мин
Количество просмотров64K


Никаких сомнений, что за последнее время мир только укрепил свою зависимость от программного обеспечения. Приложения должны обладать высокой доступностью, качественно выполнять требуемые функции и иметь адекватную стоимость. Эти характеристики, в той или иной степени, определяет архитектура ПО.
Читать дальше →
Всего голосов 21: ↑18 и ↓3+15
Комментарии2

Процедурная генерация случайных игровых подземелий

Время на прочтение6 мин
Количество просмотров65K
image

В посте подробно рассматривается техника генерации случайных подземелий. Основной алгоритм генерации, пример работы которого можно посмотреть здесь, используется разработчиками игры TinyKeep. Оригинальный пост от разработчика был размещён на reddit.

Оригинальное описание алгоритма


1. Сначала я задаю нужное количество комнат – к примеру, 150. Естественно, цифра произвольная, и чем она больше, тем сложнее будет подземелье.

2. Для каждой комнаты я создаю прямоугольник со случайными шириной и высотой, находящимися в пределах заданного радиуса. Радиус не имеет большого значения, хотя разумно предположить, что он должен быть пропорционален количеству комнат.

Вместо равномерно распределённых случайных чисел (какие выдаёт генератор Math.random в большинстве языков), я использую нормальное распределение Парка-Миллера. В результате вероятность появления маленьких комнат превышает вероятность появления больших. Зачем это надо, объясню позже.

Кроме того я проверяю, что соотношение длины и ширины комнаты не слишком велико. Нам не нужны как идеально квадратные комнаты, так и сильно вытянутые.

3. И вот у нас есть 150 случайных комнат, расположенных на небольшом пространстве. Большинство из них наезжают друг на друга. Теперь мы осуществляем их разделение по технологии separation steering, чтобы разделить прямоугольники так, чтоб они не пересекались. В результате они не пересекаются, но находятся достаточно близко друг от друга.

4. Заполняем промежутки клетками размером 1х1. В результате у нас получается квадратная решётка из комнат различного размера.

5. И тут начинается основное веселье. Определяем, какие из клеток решётки являются комнатами – это будут любые клетки с шириной и высотой, превышающими заданные. Из-за распределения Парка-Миллера мы получим сравнительно небольшое количество комнат, между которыми есть довольно много свободного пространства. Но оставшиеся клетки нам также пригодятся.

6. Следующий шаг – связывание комнат вместе. Для этого мы строим граф, содержащий центры всех комнат при помощи триангуляции Делоне. Теперь все комнаты связаны меж собой непересекающимися линиями.

7. Поскольку нам не нужно, чтобы все комнаты были связаны со всеми, мы строим минимальное остовное дерево. В результате получается граф, в котором гарантированно можно достичь любой комнаты.

8. Дерево получается аккуратным, но скучным – никаких вам замкнутых ходов. Поэтому мы случайным образом добавляем обратно примерно 15% ранее исключённых рёбер графа. В результате получится граф, где все комнаты гарантированно достижимы, с несколькими замкнутыми ходами.

9. Чтобы превратить его в коридоры, для каждого ребра строится серия прямых линий (в форме Г), идущих по рёбрам графа, соединяющим комнаты. Тут нам пригождаются те клетки, которые остались неиспользованными (те, что не превратились в комнаты). Все клетки, накладывающиеся на Г-образные линии, становятся коридорами. А из-за разнообразия размеров клеток стены коридоров будут неровными, что как раз хорошо для подземелья.

И вот пример результата!

Осторожно — под катом много монстров анимированных гифок!
Читать дальше →
Всего голосов 53: ↑49 и ↓4+45
Комментарии16

Настраиваем свою комнатную Service Bus for Windows Server

Время на прочтение12 мин
Количество просмотров23K


Достаточно часто встречается необходимость связать вместе несколько разнородных систем, либо обеспечить их синхронизацию. Конечно, случаи бывают разные и уникальные, однако, написание собственного решения, как правило, достаточно затратно, как по времени, так и по ресурсам.

Среди серьезных компании, пожалуй, можно выделить облачные решения от Amazon (SQS) и Microsoft (Service Bus). Однако, несмотря на бурное развитие Public Cloud, такие решения не всегда применимы, что называется On-Premises. Иными словами, есть потребность в таких решениях, но на собственных закрытых площадках. В связи с этим, Microsoft сделали грамотный шаг, сделав доступным Service Bus в Private Cloud, или как минимум на одной машине с установленной Windows 7 и выше. В версии Service Bus 1.0 было доступно управление через PowerShell, а с релизом 1.1 появилась возможность интеграции в консоль Azure Pack.

В этой статье я постараюсь описать процесс настройки Service Bus for Windows Server максимально подробно, в картинках. Так как лучше один раз увидеть процесс полностью, чем несколько раз прочитать по частям в разных источниках.

Осторожно трафик! Под катом много картинок.
Читать дальше →
Всего голосов 15: ↑13 и ↓2+11
Комментарии2

Удачная модель ветвления для Git

Время на прочтение10 мин
Количество просмотров998K
Перевод статьи Vincent Driessen: A successful Git branching model

В этой статье я представляю модель разработки, которую использую для всех моих проектов (как рабочих, так и частных) уже в течение года, и которая показала себя с хорошей стороны. Я давно собирался написать о ней, но до сих пор не находил свободного времени. Не буду рассказывать обо всех деталях проекта, коснусь лишь стратегии ветвления и управления релизами.



В качестве инструмента управления версиями всего исходного кода она использует Git.

Читать дальше →
Всего голосов 180: ↑171 и ↓9+162
Комментарии105

Юнит-тестирование в PHP

Время на прочтение13 мин
Количество просмотров188K
Язык PHP очень легок для изучения. Это, а так же обилие литературы «Освой _что_угодно_ за 24 часа» породило большое количество, мягко говоря, некачественного кода. Как следствие, рано или поздно любой программист, который выходит за рамки создания гостевой книги или сайта-визитки сталкивается с вопросом: «а если я здесь немножко добавлю, все остальное не ляжет?» Дать ответ на этот вопрос и на многие другие может юнит-тестирование.

В самом начале хочется оговориться — здесь речь не будет идти о TDD и методологиях разработки ПО. В данной статье я попробую показать начинающему PHP-разработчику основы использования модульного тестирования на базе фреймворка PHPUnit
Начнем?..
Всего голосов 97: ↑90 и ↓7+83
Комментарии90

Новый профилировщик памяти в Visual Studio 2015

Время на прочтение3 мин
Количество просмотров29K
Долгие годы С++ программисты, пишущие под Linux язвительно пеняли разработчикам на С++ под Windows отсутствием в Visual Studio нормального профилировщика памяти. Вот в Линуксе, дескать, есть Valgrind, который решает все проблемы, а в студии что: расставляй какие-то макросы, анализируй какие-то логи — мрак. Клевета! Хотя и правда. Вернее, это было правдой до выхода Visual Studio 2015, в которой наконец-то (ура 3 раза!) присутствует нормальный профилировщик памяти, позволяющий ловить утечки памяти с закрытыми глазами, одной левой и даже не просыпаясь!

В этой статье мы посмотрим, что он умеет и как им пользоваться.


Читать дальше →
Всего голосов 49: ↑43 и ↓6+37
Комментарии13

Пишем документацию API при помощи RAML

Время на прочтение10 мин
Количество просмотров77K
RAML

Удобство работы с любым API во многом зависит от того, как написана и оформлена его документация. Cейчас мы ведём работу по стандартизации и унификации описания всех наших API, и вопросы документирования для нас особенно актуальны.
После долгих поисков мы решили оформлять документацию в формате RAML. Так называется специализированный язык для описания REST API. О его возможностях и преимуществах мы расскажем в этой статье.
Читать дальше →
Всего голосов 34: ↑31 и ↓3+28
Комментарии39

Получаем i18n список стран, регионов, населенных пунктов из ВКонтакте

Время на прочтение5 мин
Количество просмотров64K

Получить базу данных стран, регионов, населенных пунктов с переводом названий и связями бесплатно и без регистрации? Это реально!


При разработке небольшого стартап-проекта с большими амбициями столкнулся с необходимостью в базе данных стран, регионов и городов, с переводом названий хотя бы на самые распространенные языки (английский, русский, испанский, немецкий и т. д.). Готовое решение найдено не было, поэтому стал искать источники, из которых можно спарсить необходимые данные. На ум сразу пришли известные социальные сети. В этой статье уже описывалось получение данных из ВКонтакте, но покопавшись в документации API ВКонтакте, был приятно удивлен, найдя открытые документированные методы получения геоданных:

database.getCountries — Возвращает список стран.

database.getRegions — Возвращает список регионов.

database.getCities — Возвращает список населенных пунктов.

database.getCountriesById — Возвращает информацию о странах по их идентификаторам

database.getCitiesById — Возвращает информацию о городах по их идентификаторам.

Это основные, интересные нам методы, к тому же не требующие авторизации и использования токенов. Больше методов можно посмотреть в разделе документации.

Пример url для обращения к методу получения списка стран представлен ниже (аналогично происходит обращение по протоколу https):
http://api.vk.com/method/database.getCountries?v=5.5&need_all=1&count=10
Читать дальше →
Всего голосов 21: ↑17 и ↓4+13
Комментарии12

Сборщик почты (делаем простые вещи сложно)

Время на прочтение21 мин
Количество просмотров26K

В качестве предисловия


Наверное, многие из вас в своей практике сталкивались с задачей сбора почты с ряда ящиков. Зачем это может быть нужно? Наверное, потому что это универсальный механизм обмена данными между системами. Множество библиотек под любые языки, реализующих SMTP, POP3, IMAP, готовые решения по реализации стэка сообщений (как я сложно назвал почтовый ящик...) и т.д.

Неудивительно, что многие интеграционные задачи реализуются именно через почту. Тут в дело вступает некий сервис, который умеет эту почту быстро забирать, категоризировать и выполнять необходимые действия.

Кому достаточно приведенного ниже кода — дальше могут не читать:

         foreach (var mailbox in mailboxes)
                using (var client = new Pop3Client())
                {
                    client.Connect(Hostname, Port, false);
                    client.Authenticate(User, Password);

                    var count = client.GetMessageCount();
                    for (var i = 0; i < count; i++)
                    {
                        Mail = client.GetMessage(i + 1);
                        var cat = SortMail(Mail);
                        DoSomething(Mail, cat);
                    }
                }

Читать дальше →
Всего голосов 14: ↑12 и ↓2+10
Комментарии5

Экзамен 70-485 Advanced Windows Store App Development Using C#

Время на прочтение19 мин
Количество просмотров8.4K

Пока все прогрессивные разработчики предвкушают выход Windows 10 и готовятся разрабатывать приложения под нее, я, после сдачи теста 70-485, хочу поделиться с вами углубленными возможностями разработки приложений под Windows 8 и 8.1. Благо, у разработки по 10 и под 8.1 очень много общего. Эта статья по задумке должна помочь вам сдать экзамен 70-485, но может быть интересна в любом случае, если вы разрабатываете приложения Windows Store. Она содержит в себе некоторые must know сниппеты, описание возможностей и классов WinRT, а также некоторые моменты, по которым могут быть заданы каверзные вопросы.
Под катом обо всем понемногу. Так как все охватить невозможно, получилась своеобразная памятка.
Читать дальше →
Всего голосов 15: ↑13 и ↓2+11
Комментарии3

Основы многопоточности в .NET Framework

Время на прочтение15 мин
Количество просмотров125K


Многопоточность — одна из самых сложных тем в программировании, с ней постоянно возникает масса проблем. Без четкого понимания внутренних механизмов будет очень трудно предсказать результат работы приложения, использующего несколько потоков. Мы не будем здесь дублировать массу теоретической информации, которой очень много в сети и умных книгах. Вместо этого сконцентрируемся на конкретных и наиболее важных проблемах, на которые нужно обращать особое внимание и обязательно помнить о них в процессе разработки.
Читать дальше →
Всего голосов 41: ↑39 и ↓2+37
Комментарии15

50+ лучших дополнений к Bootstrap

Время на прочтение5 мин
Количество просмотров202K


Благодаря популярности CSS фреймворка Bootstrap, для него разработали массу различных дополнений. Даже сейчас вы можете использовать Bootstrap практически для любой задачи при разработке и оформлении вебсайта.

Для статьи я подобрал наиболее полезные дополнения «на все случаи жизни».
Читать дальше →
Всего голосов 123: ↑111 и ↓12+99
Комментарии25

Что такое SPF

Время на прочтение5 мин
Количество просмотров51K
Думаю, никому не нужно объяснять, какой проблемой является спам в наше время. Борьба с этим злом — дело не простое, и если хочется приблизится к идеалу, требующее сочетания нескольких элементов. Одним из этих элементов является протокол SPF. Будучи опубликованным в апреле 2006 года в RFC 2006 года к настоящему времени протокол имеет статус «экспериментальный», и достаточно неплохую распространенность.

SPF взят на вооружение такими гигантами, как Google, Яндекс, Mail.Ru, Microsoft, Рамблер. Yahoo не поддерживает SPF, а пытается продвигать свою разработку DKIM, к слову, не слишком успешно.

Итак — как же работает SPF?
Читать дальше →
Всего голосов 51: ↑50 и ↓1+49
Комментарии43

DKIM — это просто

Время на прочтение3 мин
Количество просмотров380K
Здравствуйте.

Хочу поделиться своим небольшим опытом прикручивания DKIM (DomainKeys Identified Mail) к своему домену и почтовому серверу.

Мы имеем:
Задача:
  • Разобраться в системе подписи сообщений DKIM, что бы gmail признал её валидной и выдал заветные: dkim=pass.

Читать дальше →
Всего голосов 35: ↑30 и ↓5+25
Комментарии34

Проектирование Web API в 7 шагов

Время на прочтение14 мин
Количество просмотров77K
7steps Разработка веб API это нечто большее чем просто URL, HTTP статус-коды, заголовки и содержимое запроса. Процесс проектирования – то, как будет выглядеть и восприниматься ваш API – очень важен и является хорошей инвестицией в успех вашего дела. Эта статья кратко описывает методологию для проектирования API с опорой на преимущества веба и протокола HTTP, в частности. Но не стоит думать, что это применимо только для HTTP. Если по какой-то причине вам необходимо реализовать работу ваших сервисов используя WebSockets, XMPP, MQTT и так далее – применяя большую часть всех рекомендаций вы получите практически тот же API, который будет хорошо работать. К тому же полученный API позволит легче разработать и поддерживать работу поверх нескольких протоколов.

Хороший дизайн затрагивает URL, статус-коды, заголовки и содержимое запроса


Обычно руководства по проектированию Web API фокусируются на общих концепциях: как проектировать URL, как правильно использовать HTTP статус-коды, методы, что передавать в заголовках и как спроектировать дизайн содержимого, которое представлено сериализованными данными или графом объектов. Это всё очень важные детали реализации, но не настолько в смысле общего проектирования API. Проектирование API – это то, как сама суть сервиса будет описана и представлена, то что вносит значительный вклад в успех и удобность использования Web API.

Хороший процесс проектирования или методология предоставляют набор согласованных и воспроизводимых шагов для создания компонентов сервисов, которые будут доступны в виде Web API. Это значит, что такая прозрачная методология может быть использована разработчиками, дизайнерами и архитекторами для координации своих действий по реализации ПО. Использованная методология так же может уточнятся со временем по мере того, как улучшается и автоматизируется процесс без ущерба для деталей методологии. На самом деле, детали реализации могут меняться (например, платформа, ОС, фреймворки и стиль UI) независимо от процесса проектировки, когда эти две активности полностью разделены и задокументированы.
Читать дальше →
Всего голосов 30: ↑28 и ↓2+26
Комментарии8

Использование C# и Wix# для создания msi-пакетов

Время на прочтение9 мин
Количество просмотров40K
От переводчика: англоязычные it-блоггеры обычно начинают такие статьи со слов I'm so excited. Про Wix# я узнал совершенно случайно и спешу поделиться этим открытием с хабрасообществом, т.к. каждый, кто имел дело с «голым» WiX, знает, насколько неприятным может быть этот процесс. И вот теперь можно сделать msi-дистрибутив, написав всего лишь несколько строчек на C#! По-моему, это круто! А относительно недавно (4 дек 2014) автор Wix# Олег Шило дал интервью изданию InfoQ. Перевод этого интервью я и представляю вашему вниманию. И прошу не судить строго за кальку некоторых слов — тот же «деплоймент» мне как-то ближе, чем «развертывание».
Предоставим слово Олегу Шило, автору Wix#
Всего голосов 26: ↑24 и ↓2+22
Комментарии9

Использование технологии Microsoft Active Accessibility для доступа к содержимому браузера

Время на прочтение6 мин
Количество просмотров13K
Давайте придумаем решение вот такой-вот простенькой задачи.
Имеется: браузер (IE, Chrome или Firefox), уже запущенный пользователем.
Требуется: написать программу, которая получит URL, который в данный момент введён в адресной строке.

Давайте подумаем, каким образом эту простенькую задачу решить НЕ получится:

1. FindWindow + GetWindowText
Почему не получится
Первая идея — найти окно браузера, в нём дочернее окно адресной строки и взять URL оттуда. Практика показывает, что отдельное дочернее окно для адресной строки имеет только IE. FF и Chrome кросплатформенны, поэтому предпочитают весь свой контент отрисовывать самостоятельно.

2. Браузерное расширение, которое отдаст URL нашей программе (например, через запрос к localhost)
Почему не получится
Можно. Но во-первых, для трёх браузеров нужно будет написать 3 разных расширения, а во-вторых, для FF и Chrome мы будем вынуждены распространять его только через их магазины расширений. Писать программу, работоспособность которой зависит от того, зачешется ли сегодня левая пятка модератора — нет уж, увольте.

3. Давайте напишем сниффер и посмотрим что там пользователь открывал
Почему не получится
А давайте! Но что дальше? Даже если из потока трафика мы выделим данные, полученные именно браузером и расшифруем HTTP-протокол, мы всё-равно не узнаем именно текущий URL (ссылок в потоке будет много). Кроме того, сразу идут в сад HTTPS-соединения, HTTP/2, ссылки на локально открытые файлы, ссылки на внутренние страницы (типа chrome://settings) и т.д.

4. Давайте воспользуемся Remote Debugging Protocol ну или каким-нибудь Selenium-ом
Почему не получится
Не подходит из-за ограничения условий исходной задачи: браузер уже запущен, мы не можем запустить новый подконтрольный экземпляр, нам нужно взаимодействовать с уже имеющимся.

5. Может быть, хуки?
Почему не получится
Ну, внедриться-то мы в браузер сможем. А на что вешать хуки? Для IE всё ясно — SetWindowText для окна адресной строки (но с ним и более простой способ №1 проходил). А в FF и Chrome у нас нет каких-то чётко определённых объектов и интерфейсов, на которые мы можем завязаться. Можно что-то сделать с конкретной версией браузера, но универсального решения не получится.

6. Скриншот окна браузера, определение положения адресной строки, распознавание текста с картинки!
Почему не получится
Уже как-то начинает смахивать на отчаяние, правда? Прикинем все варианты цветовых схем ОС, разрешений, масштабов, учтём наличие в браузере плагинов, цветовых схем, нестандартного расположения элементов, right-to-left языковых локалей ну и закончим случаем, когда окно адресной строки слишком узкое, чтобы вместить URL полностью.

7. Ваш вариант
А напишите в комментариях, какие ещё решения вам приходят в голову и мы подумаем, получится или нет.

А теперь один из правильных ответов: мы воспользуемся уже старенькой, но весьма стабильной и поддерживаемой всеми браузерами во всех ОС с Win95 до Win10 технологией Microsoft Active Accessibility, которая даст нам возможность не только получить текущий URL (при чём одинаковым образом для всех браузеров), но и вообще дать доступ ко всему контенту браузера — от самого родительского окна с его заголовком, меню, тулбаром, вкладками и до содержимого открытой веб-страницы вплоть до самого последнего её элемента.
Читать дальше →
Всего голосов 22: ↑18 и ↓4+14
Комментарии20

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Зарегистрирован
Активность