SMS-чат на коленках

image

Понадобился нам как-то смс-чат для небольшой группы пользователей. Основными требованиями были надежность и простота реализации. В наличии был средненький офисный компьютер с Windows ХР на борту, USB-модем Huawei E1550, сим-карта с положительным балансом и среднестатистический эникейщик.

Хотелось нам следующего: инженеры из числа оперативного персонала, заступая на дежурство, подключаются к группе чата и могут обмениваться между собой короткими текстовыми сообщениями. Это полезно при решении проблем, касающихся нескольких отделов (релейщиков и энергетиков, например). Когда присутствие в группе не требуется – можно выйти и сообщения не получать.

Теоретически все было просто. Берем GSM-модем, пишем программу, которая проверяет на нем входящие сообщения, выдергивает из них нужную информацию, производит обработку и передает по списку подключенных абонентов.

На практике все оказалось иначе. Активное гугление привело нас на несколько проектов, в том числе и на Хабр. Но все оказались довольно сложными. Ибо Delphi из нас никто особо не понимает, а проекты для Линукса мы не рассматривали в принципе – у нас все машины виндовые.

Последней находкой стала программа от питерской компании Headwind Solutions. Называется она «Персональный СМС Сервер». Программа платная, но есть 30 дней демо-режима. Мы начали ковырять ее.

Программа оказалась очень удобной и надежной. Основная фишка ее в том, что она избавляет от необходимости работать с модемом напрямую. Она сама работает с GSM-модемом, проверяет входящие сообщения и отправляет исходящие. Если поступает новое вызывает скрипт и передает ему два параметра: номер отправителя и текст сообщения. Все остальное решается скриптом. Уже из скрипта можно вызывать процедуру отправки сообщения в программу. Сообщений может быть много, программа сама поставит их в очередь на отправку и грамотно передаст. Скрипт написан на VBS.

Программа, кстати, может работать как служба Windows. Мы сначала проигнорировали эту возможность и совершенно напрасно служба работает стабильнее.

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

Подробнее остановимся на скрипте чата. Помимо самого скрипта, в том же каталоге понадобится создать три файла: hlr.txt, vlr.txt и vlr_back.txt.
Первый файл заполняем номерами абонентов, имеющих доступ к чату. Формат такой: мобильный номер без плюса <пробел> идентификатор абонента.

79111234567 Иванов (энергетик)
79111234568 Петров (WDM)
79111234569 Сидоров (RRL)

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

Скрипт поддерживает три команды. Начинаются они со знака # (решетка). Чтобы войти в группу чата нужно отправить смс на номер сим-карты модема с текстом #1, чтобы выйти #0. Для запроса текущего списка пользователей нужно отправить #?
Запросы от абонентов, не вошедших в группу, игнорируются.

Входящие сообщения обрабатываются следующим образом. В начало исходного сообщения ставится идентификатор абонента (у нас это фамилия сотрудника и его отдел), а затем это сообщение передается всем абонентам из файла vlr.txt. Отправитель получает квитанцию об отправке сообщения. В ней дублируется его сообщение и количество абонентов, которому оно отправлено. Передача квитанции была добавлена в качестве контрольной меры. Если квитанция получена, значит, чат исправен, деньги на сим-карте есть и всем участникам чата сообщение улетело.

Привожу наши настройки программы. Параметры подбирались несколько лет методом проб и ошибок:

image

И собственно скрипт:

Код чата на VBS
' Получаем значения переменных, которые передаются скрипту при его вызове Number = WScript.Arguments(0) Message = WScript.Arguments(1) Message = Trim(Message)   ' Обнуляем флаги, устанавливаем значение переменных FlagVlr = 0 FlagHlr = 0 FlagRX = 0 FlagSymbol=0 Users = "" Count = 0   ' Устанавливаем соответствие между переменными и именами файлов vlr = "vlr.txt" hlr = "hlr.txt" vlr_back = "vlr_back.txt"   ' Ищем номер абонента в списке HLR Set objFSO = CreateObject("Scripting.FileSystemObject") Set filehlr = objFSO.OpenTextFile(hlr, 1)  Do Until filehlr.AtEndOfStream     sLine = filehlr.ReadLine()     nSpace = InStr(sLine, " ")          If nSpace > 0 Then     Number_hlr = Left(sLine, nSpace - 1)     Name_hlr = Trim(Right(sLine, Len(sLine) - nSpace))     End If        If (Number_hlr = Number) Then     FlagHlr = 1     Name = Name_hlr     End If          If (Len(Users) = 2) Then     Users = ""     End If Loop filehlr.Close   ' Ищем номер абонента в списке VLR Set objFSO = CreateObject("Scripting.FileSystemObject") Set filevlr = objFSO.OpenTextFile(vlr, 1)  Do Until filevlr.AtEndOfStream     sLine = filevlr.ReadLine()     nSpace = InStr(sLine, " ")          If nSpace > 0 Then     Users = Users & ", "     Number_vlr = Left(sLine, nSpace - 1)     Name_vlr = Trim(Right(sLine, Len(sLine) - nSpace))     End If        Count = Count + 1      If (Number_vlr = Number) Then     FlagVlr = 1     Name = Name_vlr     End If           If (Len(Users) = 2) Then     Users = ""     End If      Users = Users & Name_vlr Loop filevlr.Close   ' Устанавливаем флаги в зависимости от наличия записи номера в файлах HLR и VLR  If (FlagHlr = 0) Then Flaguser = 0 End If   If (FlagHlr = 1) And (FlagVlr = 0) Then Flaguser = 1 End If   If (FlagHlr = 1) And (FlagVlr = 1) Then Flaguser = 2 End If   ' Устанавливаем значение текстовых сообщений  MessageAlreadyEnter = "Вы уже вошли в чат. Сейчас в группе: " & Users & "." MessageNowInGroup = "Сейчас в группе: " & Users & "." MessageEmpty = "Вы отправили пустое сообщение."   ' Устанавливаем значение текстовых сообщений при пустой группе  If (Count = 0) Then MessageNowInGroup = "В группе нет собеседников." End If  If (Count = 1) Then MessageAlreadyEnter = "Вы уже вошли в чат. В группе нет собеседников." End If   ' Обработка специальных сообщений  dlina = Len(Message) symbol = Trim(Message) symbol = Left(symbol, 1) If (symbol = "#") Then FlagSymbol = 1 End If   ' Обработка запроса на вход в группу  If (Message = "#1") And (Flaguser = 1) Then FlagVlr = 0 FlagSymbol = 0  Set filevlr = objFSO.OpenTextFile(vlr, 1) Set filevlrback = objFSO.OpenTextFile(vlr_back, 2) rec = Number + " " + Name filevlrback.WriteLine(rec)  Do Until filevlr.AtEndOfStream 	sw = filevlr.ReadLine() 	filevlrback.WriteLine(sw) 	Loop  filevlr.Close filevlrback.Close  Set filevlr = objFSO.OpenTextFile(vlr, 2) Set filevlrback = objFSO.OpenTextFile(vlr_back, 1) Do Until filevlrback.AtEndOfStream 	sw = filevlrback.ReadLine() 	filevlr.WriteLine(sw) 	Loop  filevlr.Close filevlrback.Close   ' ======= Отправляем сообщение об успешном входе в группу =======  Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") objSMSDriver.Connect() Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = "Вы успешно подключились к разговору. " + MessageNowInGroup objMsg.Send() End If   ' Обработка запроса на вход в группу, если абонент уже находится в ней  If (Message = "#1") And (Flaguser = 2) Then FlagVlr = 0 FlagSymbol = 0  Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") objSMSDriver.Connect() Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = "Вы уже подключены к разговору. " + MessageNowInGroup objMsg.Send() End If   ' Обработка повторного запроса на выход из группы  If (Message = "#0") And (Flaguser = 1) Then FlagSymbol = 0 End If   ' Обработка запроса на выход из группы  If (Message = "#0") And (FlagVlr = 1) Then FlagVlr = 0 FlagSymbol = 0   Set filevlr = objFSO.OpenTextFile(vlr, 1) Set filevlrback = objFSO.OpenTextFile(vlr_back, 2)  Do Until filevlr.AtEndOfStream 	sLine = filevlr.ReadLine() 	nSpace = InStr(sLine, " ")      	If nSpace > 0 Then 	Number_vlr = Left(sLine, nSpace - 1) 	Name_vlr = Trim(Right(sLine, Len(sLine) - nSpace)) 	rec = Number_vlr + " " + Name_vlr 	End If    	If (Number_vlr <> Number) Then 	filevlrback.WriteLine(rec) 	End If        Loop  filevlr.Close filevlrback.Close  Set filevlr = objFSO.OpenTextFile(vlr, 2) Set filevlrback = objFSO.OpenTextFile(vlr_back, 1) Do Until filevlrback.AtEndOfStream rec = filevlrback.ReadLine() filevlr.WriteLine(rec) Loop filevlr.Close filevlrback.Close   ' ======= Отправляем сообщение об успешном выходе из группы =======  Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") objSMSDriver.Connect() Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = "Вы успешно покинули группу." objMsg.Send()  End If   ' Обработка запроса на получение списка собеседников  If (Message = "#?") And (FlagVlr = 1) Then FlagVlr = 0 FlagSymbol = 0  Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") objSMSDriver.Connect() Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = MessageNowInGroup objMsg.Send() End If   ' Обработка неверной или несуществующей команды  If (FlagSymbol = 1) And (FlagHlr = 1) Then FlagVlr = 0 FlagSymbol = 0  Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") objSMSDriver.Connect() Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = "Команда не распознана. Команды: #1 - вход, #0 - выход, #? - список собеседников." objMsg.Send()  End If   ' Обработка пустого сообщения  If (Message = "") And (FlagVlr = 1) Then FlagVlr = 0  Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") objSMSDriver.Connect() Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = MessageEmpty objMsg.Send() End If   ' Обработка непустого сообщения  If (FlagVlr = 1) Then 		Message = Trim(Message) 		Set objFSO = CreateObject("Scripting.FileSystemObject") 		Set filevlr = objFSO.OpenTextFile(vlr, 1) 		Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") 		objSMSDriver.Connect() 		Do Until filevlr.AtEndOfStream 		sLine = filevlr.ReadLine 		nSpace = InStr(sLine, " ") 			If nSpace > 0 Then 			Number_buffer = Left(sLine, nSpace - 1) 			Name_buffer = Trim(Right(sLine, Len(sLine) - nSpace)) 				If (Number_buffer <> Number) Then 				Set objMsg = CreateObject("HeadwindGSM.SMSMessage") 				objMsg.To = Number_buffer 				objMsg.Body = Name & ": " & Message 				objMsg.Send() 				End If 			End If Loop filevlr.Close  Count_receipt = Count - 1  ' ======= Отправляем квитанцию =======  Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = "Message send to " & Count_receipt & " users. Text: '" & Message & "'" objMsg.Send()  ' ======= /Отправляем квитанцию =======   End If   ' ======= Конец скрипта =======  WScript.Quit 





Таким макаром мы получили простенький СМС-чат, который сейчас трудится на благо отечественных инженеров. Надеемся, что пригодится и вам.

ссылка на оригинал статьи http://habrahabr.ru/post/259057/

Тестируем Spring Rest контроллеры: проще, короче, надежнее. Spring Security Test + JSON Matcher



Здравствуйте!
Собственный JSON Matcher, использование Spring Security Test, недавно вошедший в Spring Security 4.0, и отказ от транзакций при тестировании сервисов позволяют сделать тесты проще и надежнее.

Я использовал данный подход при создании приложения на своем курсе Topjava (Maven/ Spring/ Security/ JPA(Hibernate)/ Rest(Jackson)/ Bootstrap(CSS)/ jQuery + plugins), исходный код проекта можно взять на github.

Данная статья не является еще одним учебником по тестированию Spring REST контроллеров и предполагает что вы уже с ним знакомы.

Про выгоды отказа от транзакций я уже писал в предыдущей публикации По следам Spring Pet Clinic. Maven/ Spring Context/ Spring Test/ Spring ORM/ Spring Data JPA. К перечисленным недостаткам использования @Transaction еще можно добавить невозможность посмотреть реальные запросы при выполнении метода сервиса к базе (например при включенном hibernate.use_sql_comments)

Здесь я напишу как проще, короче, надежнее тестировать Spring REST контроллеры.


Spring Security Test


До релиза Spring Security 4.0 это был отдельный проект, который вошел в Spring Security 4.0 как Improved Testing Support.
Теперь он есть в центральном maven репозитории и подключается так:

<properties>    <spring-security.version>4.0.1.RELEASE</spring-security.version> </properties> … <dependency>    <groupId>org.springframework.security</groupId>    <artifactId>spring-security-test</artifactId>    <version>${spring-security.version}</version> </dependency> 


Общий код для для тестирования контроллеров можно сделать абстрактным классом.
Подключение security к Spring MVC тестам стало немного проще:

    mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)              .apply(springSecurity()).build(); 


Для REST сервисов в проекте используется http-basic, поддержка которого в Spring Security Test есть среди многих других.
Для удобства создаем тестовые данные и делаем подключение httpBasic еще проще:

public static RequestPostProcessor userHttpBasic(User user) {    return SecurityMockMvcRequestPostProcessors            .httpBasic(user.getEmail(), user.getPassword()); }  mockMvc.perform(get(REST_URL).contentType(MediaType.APPLICATION_JSON)        .with(userHttpBasic(ADMIN)))        .andExpect(... 


При этом в тестах не происходит подмена security context, как приходилось делать раньше, а честно выставляются httpBasic «Authorization» хедер.


Проверка JSON-содержимого ответа через собственный ResultMatcher


Обычная практика во всех руководствах по тестированию REST: использовние json-path для выборочной проверки полей содержимого ответа json (на полную проверку обычно терпения не хватает). Или использование более продвинутых библиотек, что сути подхода не меняет.

Однако гораздо лучше сравнить сразу весть объект со всеми вложенными уровнями иерархии! Т.к. строковое представление JSON объектов сравнивать нельзя (у него может быть разное форматирование и порядок полей), нужно сериализовать содержимое ответа JSON в объект и сравнивать объекты. Spring MVC интегрирован с JSON библиотекой Jackson, поэтому мы можем настроить ObjectMapper как нам удобно (например отключить сериализацию ленивой загрузки полей объектов Hibernate) и сделать удобный утильный класс для JSON сериализации-десериализации.

Для использования в тестах синтаксиса Spring Test:

.andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) 


делаем собственный ResultMatcher с методами contentMatcher и contentListMatcher сравнения объектов и списка объектов соответственно. Достаточно настроить этот Matcher для работы с нужными объектами (в простейшем случае, если у объекта Hibernate метод equals сделан по равенству PK и его нельзя использовать для сравнения, можно сравнивать объекты через toString):

public static final ModelMatcher<UserMeal, String> MATCHER =                        new ToStringModelMatcher<>(UserMeal.class); 


Для более сложных случаев для сравнения придется сделать обертку над Hibernate объектом.
Зато теперь тесты на проверку объекта JSON в ответе REST с любым уровнем вложений JSON объекта будут выглядеть очень просто:

mockMvc.perform(get(REST_URL + "by?email=" + USER.getEmail())        .with(userHttpBasic(ADMIN)))        .andExpect(MATCHER.contentMatcher(USER))        .andExpect(... 


Тесты REST контроллеров проекта настроены на in-memory hsqldb, поэтому их можно запускать без подключения к DB.
Надеюсь что эти решения Вам пригодятся и спасибо за внимание.

ссылка на оригинал статьи http://habrahabr.ru/post/259055/

Вторая версия Evernote SDK для Android: новые возможности Evernote в ваших приложениях

Десятки тысяч разработчиков уже используют платформу Evernote, чтобы сделать свои приложения функциональнее и привлекательнее для 100 миллионов пользователей нашего сервиса. Очевидно, что значительная часть этого сообщества имеет дело с Android.

С недавним обновлением приложения Evernote для Android нам представилась возможность также подготовить Evernote SDK 2.0 для Android, мы рады пригласить разработчиков опробовать новые возможности в своих проектах.

Evernote for Android SDK на Гитхабе >>

image

Это обновление включает ряд важных изменений:

  • Новые системы сборки: добавлена поддержка Gradle и Android Studio, рекомендованных IDE для приложений на Android.
  • Переписан код: многие использованные ранее устаревшие функции Android были заменены новыми API. В своем же SDK мы сохранили программные интерфейсы и улучшили сетевую производительность.
  • Аутентификация сторонних приложений: для авторизации в Evernote с помощью OAuth сторонним приложениям больше не надо поднимать окно веб-браузера. Посмотреть пример
  • Поддержка корпоративного сервиса Evernote Business: подключение к бизнес-блокнотам пользователя (и общим блокнотам в целом) теперь реализовано гораздо удобнее. Ознакомиться с подробностями
  • Поддержка токена разработчика: вместо получения ключа API вы теперь можете создать токен разработчика и приступить к работе с API в своем аккаунте прямо сейчас. Кроме того, для добавления новых функций мы расширили важные классы с объектами-фабриками (factories) и объектами-строителями (builders). Теперь значительно проще переиспользовать и расширять код.
  • Загрузка HTML-кода заметок: с помощью класса NoteRef вы теперь можете проще загружать сохранять заметки. Унифицированный поиск позволит вам найти заметки по нескольким критериям единым запросом. Функция загрузки заметок в виде HTML будет полезна для отображения заметок в браузере или во внешних редакторах. Посмотреть демо
  • Новые интенты (Intents): Даже безо всяких вызовов Evernote API и работы с сетью вы теперь можете создавать, просматривать или искать заметки, используя приложение Evernote для Android. Можно даже отправлять в Evernote HTML-код, которое наше приложение сконвертирует в валидный ENML новой заметки. Открыть библиотеку Evernote Android Intents
  • Обновлено демо-приложение, из которого можно понять приципы работы с Evernote SDK для расширения возможностей вашего приложения. Посмотреть демо-приложение


Публичная версия нового Evernote SDK для Android уже доступна всем желающим. Будем рады услышать об интересных интеграциях. Мы всячески приветствуем пул-реквесты и сообщения об ошибках в нашем репозитории на Гитхабе >>

ссылка на оригинал статьи http://habrahabr.ru/post/259053/

Кризис. Девальвация. Влияние на малый и средний бизнес на реальных примерах

Я – активный интернет-пользователь и, как и многие другие, постоянно просматриваю публикации в различных СМИ на предмет положения в экономике, в том числе, и по той причине, что от этого напрямую зависит и мое благополучие. Как и многие, я интересуюсь причинами кризиса, его развитием, возможными перспективами, ведь если малый и средний бизнес не будет развиваться, моя деятельность также прекратится из-за отсутствия клиентов.


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


Здесь и сейчас я решил систематизировать собственные наблюдения. По роду своей деятельности, как бизнес консультант, я постоянно сталкиваюсь с самыми разными компаниями. Это могут быть потенциальные клиенты, заказчики, с которыми я работал раньше или работаю в данный момент. Ко мне регулярно обращаются новые и старые клиенты: кто-то с вопросом, кто-то с проблемой.

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

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

Итак, исходные данные: мой личный опыт общения с предпринимателями из Москвы и Санкт-Петербурга. К сожалению, относительно регионов мне ничего не известно, так как с бизнесом за пределами перечисленных городов я в последние годы не работал. Я думаю, что отличий и для регионального малого и среднего бизнеса будет не много, но все же, попрошу учитывать этот нюанс.


Что такое кризис?


Сегодня в СМИ и на всевозможных тренингах постоянно слышно о кризисе в экономике. Многие эксперты и тренеры говорят о сложностях текущего периода, о проблемах в экономике, но все это – общие слова. А в чем же выражается кризис на практике для малого и среднего бизнеса и как действовать, чтобы сохранить свое дело и подготовить почву для будущего развития, ни один эксперт не говорит. В статье я постараюсь рассказать об этом явлении на примере одной из сторон кризиса, а именно на примере девальвации.


Как выглядит кризис для бизнеса: девальвационный шок и его последствия


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

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


Компания 1. Импортер косметических средств для профессионалов


Эта компания занимается продажей импортных профессиональных косметических средств: покупает товар за рубежом, доставляет в Россию и здесь продает. Естественно, что бизнес, связанный с перепродажей импортных товаров, очень сильно пострадал в условиях кризиса. Более того, в данном случае товары являются не просто косметическими средствами, рассчитанными на конечного потребителя, но материалами, необходимыми профессионалам для оказания услуг. При этом любое удорожание материала приводит к снижению прибыли мастера салона красоты, так как повышать цену на услуги в условиях кризиса не желательно. В результате многие профессионалы в кризис стремятся использовать более дешевые аналоги.

Каким образом работала эта компания?

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

Например, товар, который еще недавно стоил 800 рублей, уже через неделю мог стоить 900, потом вырасти в цене до 1000 рублей и выше. А когда курс евро превысил отметку 80 руб., стоимость единицы товара в этой компании стала невероятно высокой для такого рода продукции.

Как отреагировали покупатели?

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

Что сделала компания, чтобы справиться с проблемами?

Первым делом они открыли новый сайт, сделали лендинг-пейдж, занялись активным продвижением своих товаров в сети Интернет. В этот период мне было поставлено много разных задач, я их, конечно, реализовал. Стартовали наши обновления успешно, реклама работала, люди приходили на сайт, проявляли интерес, делали 1-2 покупки и уходили. Уже тогда было понятно, что компании необходимо снизить цену или хотя бы зафиксировать ее на определенном уровне. Любого покупателя будет нервировать постоянное изменение цен, что мы и наблюдали на практике.

На что я получил очень конкретный ответ: «Наша косметика как автомобиль Мерседес. Мерседес, как известно, во все времена будет продаваться. Так и наша косметика будет продаваться в любом случае, независимо от ее стоимости».
При этом цена на товары в прайсе компании была указана в условных единицах, привязанных к евро. В результате покупатель, который заказал товар (при курсе евро 50 рублей) на сумму 1000 рублей, через 2-3 дня мог быть поставлен перед фактом: евро уже стоит 55 рублей, и счет выставляется на тот же перечень товаров, но уже на сумму 1100 руб. Конечно, подобные неожиданности ни одному покупателю не понравятся.

После того разговора прошло 5 месяцев, и сейчас ситуация следующая:

  • Продажи у них упали более чем в 2 раза как в количественном отношении, так и с финансовой точки зрения (оборот и, соответственно, прибыль, также стали ниже).
  • Покупателей пытаются заманивать скидками (до 50%, причем, суммарная стоимость покупки для получения скидки также стала заметно ниже, чем раньше).
  • Руководство начало массовые увольнения менеджеров по продажам. (Через 5 месяцев в отделе остался всего один опытный специалист, остальные – новички).


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

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

Подход этой компании выглядел так:

Повышаем цены – продолжаем вкладывать в товар и надеяться на успешные продажи – верим в свою непогрешимость.


Как оказалось, рынок устроен несколько иначе, и подобный подход себя не оправдывает. В этой компании упали объемы продаж, снизилось качество обслуживания. Основные покупатели ушли.

В чем проблема этой компании:


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


Очень важно помнить, что сегодня – не 1998 и даже не 2008 год. Сейчас очень развита интернет-торговля. А потому, если вашего покупателя не устраивает любой из возможных аспектов сотрудничества, он просто наберет в поисковой системе название нужного товара и сможет выбрать любого поставщика из обширного перечня. При этом он будет в режиме онлайн сравнивать цены, условия сотрудничества и обратится туда, где стоимость товара и сопутствующие услуги окажутся самыми лучшими.

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


Компания 2. Торговля отделочными материалами


Процесс девальвации застал эту компанию в период перехода на новую учетную систему. И первое, что они сделали, это зафиксировали цену. Т.е. переоценка в компании происходит не чаще одного раза в неделю. Исключением мог быть только случай очень сильного скачка курса, о чем клиенты заранее были поставлены в известность. Если никаких форс-мажорных обстоятельств не возникает, то в течении 2 недель цена не меняется независимо от курсов валют.

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

Каким образом была решена проблема поставки импортных товаров покупателю?

  • Счет выставляется на сумму в рублях, зафиксированную в момент заказа. Цена на товар в связи с изменением курса не меняется.
  • Срок отгрузки товара – 2 дня. Если за этот промежуток времени товар не был оплачен, он снимается с резерва, а счет перестает быть действительным.
  • Никаких дополнительных скидок компания не стала предоставлять, руководство выбрало в качестве преимуществ – надежность в работе и фиксацию цены.


В чем для этой компании заключался кризис?

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

В компании значительно снизились продажи импортных товаров. Особенно сильно пострадала продажа отделочных материалов класса люкс. Покупатели, которые прежде покупали материалы люкс-класса, переключили свое внимание на среднюю ценовую категорию материалов, которые из-за роста цен стали такими же дорогими, как еще недавно элитные категории товаров, а покупатели товаров из средней ценовой категории стали выбирать дешевые материалы. В результате общий оборот компании снизился.

Что происходит сейчас:

  • Компания работает стабильно, хоть и сохраняется некоторая нервозность и неуверенность в завтрашнем дне.
  • Руководство компании пересмотрело заметную часть затрат и перевело рабочий процесс на режим экономии.


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

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


Компания 3. Производитель продуктов питания из импортного сырья


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

Вторая составляющая кризиса, которую почувствовала на себе эта компания, связана с российскими контр санкциями. Из-за запрета на закупку продовольствия в Европе, возникла срочная необходимость в новых поставщиках. Товары пришлось заказывать в Пуэрто-Рико, в Латинской Америке и т.д. В результате компанию лихорадило очень сильно, ведь надо было найти нужные для производства аналоги, причем, по выгодной цене, проверить качество на соответствие требованиям, заключить новые контракты. Такие перемены, еще и в срочном порядке, всегда вызывают на предприятии повышенную нервозность.

Последствия, которые ощутила на себе эта компания:

  • Уменьшился объем продаж, причем, очень заметно(в 2.5 раза в пиковый момент).
  • Одномоментно от сотрудничества отказались пять из семи крупных покупателей (торговые сети).


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

  • Провели сокращение персонала. Так, из 4 бухгалтеров остался работать только один главный бухгалтер.
  • Провели автоматизацию. В результате удалось сократить заметное число учетчиков и другого персонала на производстве и складе.
  • Перешли на использование более дешевых информационных систем. Например, если раньше для документооборота с торговой сетью применялась информационная система одной компании, то теперь была найдена и внедрена более дешевая аналогичная разработка.


Если раньше в компании не задумывались о многих, казалось бы, незначительных расходах, то теперь оптимизируются все процессы. Откуда я об этом знаю? Именно мне заказывали автоматизацию и внедрение новых информационных систем.

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

Что получилось в результате:

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

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


Компания 4. Телекоммуникационное оборудование


Для этой компании девальвационный шок был очень болезненным. Они потерпели убытки из-за колебаний курсов валют. Так как в компании не было строгой системы учета, а товар закупался в основном под заказ, несколько раз происходило следующее: покупатели сознательно оплачивали заказанный товар на условиях 100% предоплаты в самые сжатые сроки в рублях по текущему курсу. После чего из-за девальвации этот товар закупался у иностранного поставщика иногда даже дороже, чем был уже заранее продан покупателю.

Кроме того, объемы продаж очень заметно упали. Экономить при выборе техники в связи с кризисом начали и небольшие компании, и частные лица. Но самое главное, государственные компании и крупные корпорации также заметно урезали бюджет на закупку высококачественного оборудования. Кто-то отказался от уже практически подписанных контрактов, кто-то отложил инвестиционные проекты, связанные с закупкой оборудования, до лучших времен, а кто-то решил перейти на другие технологии, позволяющие сэкономить средства, например, на работу «в облаке» и т.д.

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


Что нужно и что не нужно делать в кризис?


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

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

Итак, что не нужно делать в кризис:

  • Ни в коем случае не нервничайте. Эмоциональные решения, принятые в стрессе, чаще всего оказываются неудачными. Отнеситесь с максимальным спокойствием к тому, что какие-то потери неизбежны. И уже спокойно подумайте, что вы реально можете сделать.
  • Если ваш бизнес связан с импортом, и, как следствие, стоимость товаров зависит от курсов валют, необходимо максимально снизить сроки выполнения контрактных обязательств. Т.е. между оформлением заказа и его оплатой должно проходить минимально возможное время, лучше всего, если это будет не более 2-3 дней. После того, как указанный вами срок оканчивается, товар может быть снят с резерва или предложен тому же покупателю, но уже по новой цене. Таким образом, вы сможете зафиксировать цену в рублях, но избежать потерь из-за возможных колебаний курсов валют.
  • Ни в коем случае не привязывайте цену к иностранным валютам, не нужно указывать ценники в «у.е.». При таком подходе ваш покупатель рискует потерять средства на, так называемой, курсовой разнице, если будет оформлять заказ при одном курсе доллара или евро, а оплачивать – при другом. А это вызывает недовольство и снижает лояльность покупателей. Кроме того, если вы привязываете цену товара к курсу доллара или евро, вы начинаете продавать не столько товар, сколько – валюту. Ваши покупатели смотрят не на товар, а на табло с курсами валют. Это неправильно, ведь вы продаете – товар, и ваш покупатель должен видеть товар, его характеристики и цену, а не колебания курсов валют.
  • Не принимайте непродуманных кадровых решений. От того, что вы уволите весь отдел продаж или из-за своей нервозности создадите людям невыносимые условия труда, объем продаж не увеличится, скорее – наоборот. Хорошие специалисты по продажам, несмотря на кризис, очень востребованы. И если по причине вашей непродуманной кадровой политики уволятся опытные продажники, достойную замену им найти будет сложно.
  • Если вы работаете в сфере B2B (бизнес для бизнеса), ни в коем случае не пытайтесь привлекать клиентов «антикризисными» скидками. Как это ни парадоксально звучит, но в бизнесе компанию, которая начинает в условиях кризиса активно использовать скидки для привлечения клиентов, рассматривают как слабого игрока на рынке. В результате все отношения с такой компанией строятся на краткосрочной основе. А это – большой минус.


Что нужно делать в кризис, какие меры помогут его успешно пережить:

  • По возможности выбирайте российских поставщиков. Просмотрите свой список закупок и откажитесь от импорта везде, где только можно. Таким образом, вы снизите свою зависимость от курсов валют, что очень выгодно в условиях кризиса.
  • Открывайте свое производство. Если вы не находите отечественных поставщиков нужных вам товаров, подумайте, возможно именно вы сможете стать производителем. Открывайте швейное производство, производство продуктов питания, мебельное или любое другое производство. Конечно, это решение – не для всех отраслей. Но там, где возможно, собственное производство поможет вам увеличить прибыль и снизить зависимость от курсов валют при перепродаже импортных товаров. Хлопотно? Сложно? Страшно? Конечно. Но еще Эйнштейн сказал, что только сумасшедший ждет каких-то перемен, продолжая делать то же самое.
  • Повышайте уровень обслуживания. В кризис клиенты становятся очень разборчивыми. Если раньше клиент привычно работал с вами 3-5 лет, то сейчас в кризис он может сменить поставщика буквально в течение месяца просто потому, что кто-то предложил ему лучшие условия или лучший сервис. В кризис люди, готовые покупать, понимают свою силу и становятся более требовательными ко всем аспектам сотрудничества.
  • Улучшайте логистику, оптимизируйте грамотно складские остатки. Я лично видел две компании, которые посчитали, что сумеют переждать кризис при помощи торговли товарным запасом на складах. Все свои надежды они связали со стоимостью товаров на складе, закупленного по докризисным ценам. Но, как показала практика, эти остатки им не помогли. Большая часть остатков, как и следовало ожидать, потому и залежалась на складе, что относилась к неходовым товарам. Другие товары, которые можно было бы продать, оказались в не самом лучшем состоянии: где-то была испорчена упаковка, где-то – отсутствовали комплектующие и т.д. В результате при значительном объеме складских остатков торговать им оказалось нечем. А причина такого расхождения в отсутствии продуманной логистики.


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

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

Еще совсем недавно отечественный бизнес был на подъеме, компании развивались, прибыльность бизнеса росла, и надежность привычного и удобного партнера ценилась выше, чем более выгодная цена. Многие соглашались немного переплатить просто для того, чтобы продолжать сотрудничество с удобным партнером.

Сегодня из-за кризиса доходы заметно снизились, в том числе, у крупных корпораций. Большие компании также могут обанкротиться, если не умели оперативно перестроиться под изменившиеся рыночные условия. А потому цена закупки товара стала очень важным фактором. Как итог — небольшие компании теперь могут выйти на рынок в новом качестве бизнес-партнеров для крупных корпораций. И те, кто сумеет в сложный период наладить деловые связи, после кризиса сохранит новые контракты и получит возможность активно развивать свое дело. Я считаю, что этой возможностью необходимо обязательно воспользоваться.

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

Но даже такими сложными обстоятельствами можно и нужно пользоваться. Одну возможность я описал выше — небольшая компания получает шанс стать партнерами и поставщиками крупной корпорации. Еще одна возможность — это возможность стать производителем.

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

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

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

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

Зачем я об этом пишу? Я очень хочу, чтобы вы так же, как и я, понимали, что кризис — это не только проблемы, но и новые возможности. В нем много минусов, но есть и плюсы. И надо стремиться извлекать пользу из любой ситуации, а на жизнь и свои перспективы смотреть позитивно!

С пожеланиями успехов в бизнесе,
Рамиль Кинзябулатов.

ссылка на оригинал статьи http://megamozg.ru/post/15928/

OWASP TOP-10: практический взгляд на безопасность веб-приложений: №1 — инъекции

Все сложные, и не очень, системы хранят большое количество данных и различных объектов. Например объектов бизнес-логики, таких как учетные записи пользователей, счета в системе, транзакции, записи журналов операций, и т.д.

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

Все эти объекты, и не только эти, хранятся в таблицах, где каждая строка – 1 объект.

Например, объект «Клиент» может иметь следующий набор полей: id, имя, фамилия, e-mail, мобильный телефон, и храниться в таблице вида:

Таблица clients (Клиенты)

id
(идентификатор)
cl_name
(имя)
cl_sur_name (фамилия) e-mail cell
(мобильный)
other
(и т.п.)
1 Ivan Ivanov ivan@mail +70000000000 42

Суть взаимодействия пользователя с Web-приложением заключается в обмене запросами между браузером и сервером, где браузер отправляет серверу различные параметры и получает от сервера ответ.

Чтобы получить или изменить объекты (например, получить выписку по счету или обновить свою анкету) необходимо запросить ту или иную страницу на сервере (далее по тексту – скрипт). Web-приложения с этой целью используют формы или вызовы непосредственно URL скрипта .

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

Для передачи данных из браузера пользователя на сервер по HTTP-протоколу в основном используются два метода — GET и POST (существуют еще методы PUT и DELETE, но они используются преимущественно в API).

При передаче данных методом GET, все параметры запроса передаются в URL страницы в заголовке HTTP-запроса, например:

http://simplethreats.ru/get_order?order=150


В случае использования метода POST, сервер будет получать данные уже в теле HTTP-запроса, а в URL параметры перечислены не будут. Таким образом, к примеру, отправляется большинство форм, и всегда критичные аутентификационные данные (передача данных в URL небезопасна, ведь записи об URL и заголовки HTTP-запросов остаются в множестве журналов).

Обращения через GET или POST могут производиться к любым объектам, будь то записи в базе данных или же чтение файла (скажем, картинки или скрипта с диска). А так как объектов бизнес-логики в системе может быть очень много и они могут иметь самые различные типы, то и обращений по идентификаторам в рамках одного, даже простого Web-приложения может происходить множество.

С тем, каким образом данные попадают в Web-приложение мы определились, а что же происходит внутри?


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


В нашей первой статье мы уже рассказали о том, что, все данные, как правило, хранятся в специальных базах в виде таблиц, обращения к которым строятся в форме текстовых запросов, чаще всего написанных на специальном языке запросов SQL (Structured Query Language – структурированный язык запросов). 

Web-приложения, как правило, строят SQL запросы, сочетающие код написанный разработчиком приложения, с параметрами переданными пользователем. Рассмотрим пример:

SELECT  title, text FROM news WHERE id=$id


В нашем примере, $id – параметр передаваемый пользователем (переменная часть запроса), в то время как остальная часть запроса статическая и была заложена разработчиком приложения. Наличие переменных пользовательских данных в статическом SQL запросе, делает весь запрос динамическим.


В чем суть инъекции?


В случае с SQL, вся суть инъекции в том, чтобы модифицировать параметры HTTP-запроса таким образом, чтобы исказить SQL запрос к базе данных и «подсунуть» его серверу под видом нормального. Это позволит злоумышленнику получить несанкционированный доступ к данным.

Предположим, у нас в базе данных есть таблица «transactions» с данными о транзакциях пользователей. Она содержит следующие поля:

  • «user_id» — Уникальный идентификатор пользователя
  • «date» — Дата
  • «amount» — Сумма
  • «description» — Назначение


Таблица transactions

user_id date amount description
10 2015-05-26 1000
11 2015-05-26 1500
12 2015-05-26 1300
n 2015-05-26 x

Предположим что наш аккаунт, под которым мы находимся в приложении, имеет идентификатор 10 (user_id=10) и эти данные хранятся в сессии приложения (были записаны туда при авторизации пользователя).

В общем виде, если мы не привилегированный пользователь, мы можем обратиться к базе данных для получения информации по своим транзакциям, т.е. по транзакциям user_id=10.

Для того чтобы нам получить данные о своих транзакциях за 26 мая 2015г. в кабинете пользователя может использоваться страница со следующим адресом:

http://mybank.simplethreats.ru/transactions.jsp?date=2015-05-26


При вызове которого дата «2015-05-26» будет получена из GET-параметра в URL, а значение user_id будет получено из сессии приложения. На основе этих данных, для получения информации о транзакциях пользователя, приложение сформирует SQL-запрос:

SELECT * FROM transactions WHERE date = "2015-05-26" AND user_id = 10


Для тех, кто не знаком с синтаксисом SQL для лучшего понимания, разберем этот запрос.


Что в запросе


Запрос состоит из оператора SELECT (дословно с англ. – «ВЫБРАТЬ»), который используется для выбора данных из таблицы. Существуют еще операторы UPDATE, INSERT, DELETE, которые, как нетрудно догадаться из их названий, выполняют операции обновления, вставки и удаления строк соответственно.

Символ «*» означает, что мы выбираем все столбцы таблицы. Далее следует ключевое слово FROM (дословно – «ИЗ») с указанием имени таблицы, из которой производится выборка.

Далее идет ключевое слово WHERE (дословно с англ. «ГДЕ»), за которым следует часть, определяющая непосредственно условия выборки из таблицы.

После этого идут условия вида «название_поля = значение» разделенные ключевыми словами AND или OR, означающими «И» и «ИЛИ» соответственно.

Таким образом, переводя запрос с SQL на русский мы получим:

ВЫБРАТЬ все поля ИЗ таблицы transactions, ГДЕ поле date = "2015-05-26" И поле user_id = 10

При недостаточной проверке данных от пользователя, злоумышленник может внедрить в форму web-интерфейса приложения специальный код, содержащий кусок запроса к базе данных.  Эта опаснейшая уязвимость, позволит злоумышленнику читать/изменять/удалять информацию, которая для него не предназначена.


Эксплуатация


Как это работает? В рассмотренном примере, значение даты "2015-05-26" попадает в SQL-запрос из URL скрипта, и в целях рассматриваемого примера, никак не фильтруется приложением.

Если передать в параметр date вместе с датой 2015-05-26 еще немного символов:

2015-05-26" AND user_id=11 --


То вместо корректного:

SELECT * FROM transactions WHERE date ="2015-05-26" AND user_id = 10


Указанный запрос сформирует следующий SQL:

SELECT * FROM transactions WHERE date = "2015-05-26" AND user_id = 11 -- " AND user_id = 10 


Два минуса «—» в синтаксисе SQL означают начало комментария, поэтому все символы после «—» интерпретатором восприниматься не будут, и часть запроса, в которой осуществлялась проверка идентификатора пользователя будет отсечена сервером базы данных.

Фактически будет выполнен запрос:

SELECT * FROM transactions WHERE date = "2015-05-26" AND user_id = 11


В результате которого, мы получим информацию о транзакциях другого пользователя. А перебирая id – любого другого пользователя.


Какие бывают техники атак при SQL-инъекциях


Сообществом OWASP были описаны пять основных методов (техник) атак при SQL-инъекциях.

  • Оператор Union: подход может быть использован при наличии уязвимости в запросе SELECT, позволяющей объединить два запроса в один результат или набор результатов.


  • Логический метод: предполагает использование логического условия, либо условий, позволяющих достоверно определить истинность или ложность некоего предположения.


  • На основании ошибок: этот метод предполагает намеренную передачу различных некорректных запросов, с целью вынудить web-приложение выдать информацию об ошибке, на основании которой, злоумышленник может составить и передать корректный инжектированный запрос.


  • Метод с альтернативным каналом передачи данных: метод предполагает использование альтернативного канала передачи извлеченных данных (например через исходящее HTTP соединение с web-сервером)


  • Time delay: метод использует команды базы данных, например sleep для того чтобы определить задержу по условным запросам. Метод эффективен, когда нет возможности получить ответ от web-приложения (результат, ошибка)


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

По способу извлечения данных выделяют три типа атак:

  • Связанный: данные в результате инжектированного SQL запроса извлекаются тем же путем, которым был передан сам инжектированный запрос. Это самый прямолинейный вид атаки, в результате которого, запрошенные модифицированным запросом данные, отображаются непосредственно на странице web-приложения.


  • Не связанный: данные в результате инжектированного SQL запроса извлекаются путем, отличным от способа передачи модифицированного запроса. (например данные передаются злоумышленнику в сообщении на электронную почту)


  • Дедуктивный или слепой: В результате SQL инъекции фактического извлечения данных не происходит, но злоумышленник может получить информацию, наблюдая за поведением web-сервера, в результате отправки серии специфических инжектированных SQL запросов.




Как защититься?


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

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

Как перейти к имплементации данной рекомендации, если у вас уже есть большое web-приложение, имеющее много различных точек входа?

Мы приведем некоторый системный подход к реализации защиты от инъекций баз данных. Чтобы свести к минимуму потенциальную угрозу от данного типа атак, нужно последовательно выполнить следующие шаги:

  • Определить все точки получения данных web-приложением извне, выписать все точки входа (URL), названия передаваемых параметров, протокол (HTTP/HTTPS) и метод их передачи – GET, POST или PUT/DELETE.

  • Определить тип данных для каждого параметра, ответив на вопрос — значение какого типа мы должны получить?

  • Реализовать проверку каждого параметра на соответствие типу.

  • Реализовать экранирование кавычек и других спецсимволов при помощи символа обратного слеша “\”. При этом если параметр в запросе заключен в одинарные кавычки, то именно одинарные кавычки должны быть экранированы и заменены на «\’», аналогично с двойными кавычками. При этом экранировать одинарные кавычки внутри двойных не надо и наоборот. Это в теории, на практике же, почти во всех популярных фреймворках и скриптовых языках есть встроенные функции для экранирования спецсимволов, как например mysqli_real_escape_string в php.


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

Следует также помнить, что для успешной атаки  посредством SQL инъекции злоумышленнику требуется передать синтаксически правильный SQL запрос. Однако, если web-приложение возвращает информацию об ошибке в результате неправильного инжектированного запроса, это может помочь злоумышленнику восстановить логику исходного запроса и дать ему возможность понять, как правильно выполнить инъекцию.

Поэтому, нужно внимательно следить за тем, какая информация об ошибках отдается приложением. Тем не менее, если web-приложение скрывает сведения об ошибках, у разработчика в любом случае должна быть возможность восстановить логику исходного запроса (в самом простом случае – вести лог ошибок, но не выводить их на экран).


Какие еще бывают инъекции?


Помимо инъекций баз данных, атаке типа «инъекция» может быть подвержена любая другая среда, которая получает необработанные данные извне. Еще один распространенный случай – это инъекция командного интерпретатора операционной системы, так называемые «OS injections».

Рассмотрим такой пример из описания «Command injections» OWASP.

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

 <?php     $file=$_GET['filename'];     system("rm /var/www/user_photos/$file"); ?> 


 Типичный его вызов выглядит так:

http://mysocnet.simplethreats.ru/user_file_delete.php?filename=1246.jpg


И влечет за собой исполнение команды:

rm /var/www/user_photos/1246.jpg


Очень легко очистить всю директорию с приложением, передав такой запрос:

user_file_delete.php?filename=../ -rf


(на самом деле пробелы и некие символы закодируются при передаче в URL в нечто вида user_file_delete.php?filename=..%2F+-rf — но для наглядности, мы будем писать с пробелами и другими символами, не заворачивая их)

что вызовет исполнение:

rm /var/www/user_photos/.. –rf


и будет равносильно

rm /var/www/–rf


то есть удалит (команда rf) все содержимое директории www, где хранятся файлы приложения, без подтверждения (параметр –f) и рекурсивно (параметр -r), т.е. со всеми вложенными директориями и их файлами. Участь — врагу не пожелаешь.

А можно не удалять файловую систему, и передав запрос вида:

user_file_delete.php?filename=12346.jpg && adduser ghost && echo ghostpass | passwd ghost –stdin


Злоумышленник выполнит команду:

rm /var/www/user_photos/12346.jpg && adduser ghost && echo ghostpass <strong>|</strong> passwd ghost –stdin 



И создаст для себя учетную запись для доступа на сервер.

Нужно отметить, что на практике создать пользователя таким образом почти невозможно, так как Web-сервер в 99% систем запущен от непривилегированного пользователя, который не может создавать другие учетные записи.

Выполнение указанной цепочки команд возможно благодаря двум особенностям UNIX-систем и их командных интерпретаторов.

Первая особенность — это конвейеры (pipelines, pipes, «пайпы»). Суть конвейеров заключается в возможности передачи вывода одной команды на ввод другой, если они разделены оператором «|».

Вторая особенность – возможность запускать комбинацию команд через логические операторы «&&» и «||». Оператор «&&» выполнит следующую указанную команду, в случае если предыдущая исполнена успешно и является неким аналогом логического «И» — выполнить команду один И команду два. Оператор «||» является аналогом логического «ИЛИ» и выполнит вторую команду только в случае если не была выполнена первая — выполнить команду один ИЛИ команду два.


Что дальше?


Разумеется, нами была рассмотрена лишь малая толика того, что можно отнести к разряду инъекций. Огромный пласт занимают так называемые DOM- или HTML-инъекции, благодаря которым становится возможным проведение такого вида атак как XSS.

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

Проблеме XSS, а также методам эксплуатации и защиты от этого вида атак мы посвятим одну из наших следующих статей, которая выйдет уже в июне.

Будьте бдительны!

Немного о SimplePay и авторах
Мы — Иван Притула и Дмитрий Агапитов, занимаемся разработкой решений, которые делают жизнь людей проще и комфортнее. Сегодня мы хотим представить один из наших новых сервисов – это платежный агрегатор SimplePay. Все что мы делаем продиктовано мучительной невозможностью мириться с несовершенством в целом, и несовершенством конкретных программных решений в частности. Именно в погоне за совершенством и рождаются наши продукты.

SimplePay — это современный высокотехнологичный агрегатор платежей. Компания создана в 2014г., зарегистрирована в г. Москве и ведет свою деятельность в соответствии с законодательством Российской Федерации. Наша основная задача, это обеспечение простой, удобной возможности организации приема платежей на интернет-сайтах компаний, вне зависимости от сферы деятельности, масштаба бизнеса и наличия подготовленного технического персонала.

Мы предлагаем следующие услуги:

  • Организацию приема платежей на Вашем сайте
  • Возврат средств покупателю
  • Выставление произвольного счета покупателю
  • Уведомления о платежах как на URL, так и по e-mail
  • Рекуррентные платежи
  • Псевдорекуррентные платежи во всех популярных платежных системах с кошельками


Короткая справка:

  • Банк эквайер: Промсвязьбанк
  • Платежи в пользу третьих лиц: РНКО РИБ
  • Юрисдикция: РФ, 161-ФЗ
  • Работа с нерезидентами: Нет
  • Собственный API: Да
  • Совместимые API: Да
  • CMS-модули: Да
  • Встроенные модули в сторонних системах: BG Billing, WP-shop
  • Переадресация сразу на ПС без промежуточной страницы: Да
  • API на возвраты: Да


ссылка на оригинал статьи http://habrahabr.ru/post/259047/