Thursday, July 8, 2010

Дизайн и юзабилити приложений. (Часть 1: Интернет магазины)

Интернет магазин, это витрина, фасад здания, персонал, освещение… думаете я ошибся и описываю обычный магазин. Нет, интернет магазин не сильно отличается от своего реального аналога. Главная страничка – это фасад, вывеска, оформление магазина. Поиск – это продавцы-консультанты… и так далее…

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

image

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

минус Название магазина и телефон в верхнем левом углу, чтобы никто не заметил. Название есть смысл скрывать только недобросовестному продавцу.
минус Почему нет контактов магазина на главной? Потенциальный покупатель зайдя на этот сайт с первого взгляда и скажешь даже в какой стране и городе он находится. Только +7 (495) Говорит нам о Москве. Я лично этот телефон не сразу увидел.
минус Корзина, зачем она? Я только зашел, мне показывают что в моей корзине 0 товаров на 0 сумму… зачем тогда мне ее показывать? видимо чтобы стимулировать покупки=)
image
минус
Ссылки на непонятные интерфейсы (о нас, карта сайта, гарантия, правила, обзоры). Карта сайта – карта нужна только там, где без нее не обойтись, мы же не в лесу, и не в пустыне, и уж в магазине попытаемся найти необходимое без карты. Хороший продуманный интерфейс – вот то нужно. Гарантия, правила – гарантия чего, какие правила? Мы не должны пугать раньше времени, пусть человек выберет хоть что-то.
минус 
Поля “логин” и “пароль” в шапке магазина примерно тоже самое, что вышибала около клуба, настораживает и пугает. Это ведь не секретный объект, и не социальная сеть – это сервис, минутный сервис. При виде логина сразу мысли о неполной информации для анонимов или недоступности некоторых функций. Идентификация пользователя должна происходить не навязчиво – прозрачно для него. В магазине же вас не просят показать паспорт на входе, чтобы выяснить, бывали вы уже у них, или нет.

image
минус
Кнопка “В корзину”. Почему бы не написать я хочу это купить после нажатия на которую нам предлагают либо перейти к оформлению, либо продолжить покупки. Это удобно, и это работает в реальных магазинах: вы берете товар с полки, смотрите, читаете, пробуете на зуб… говорите “я его беру!”. К вам подходит человек, забирает товар, и говорит: “товар будет на кассе – он не спрашивает вашего имени, не говорит вам 9-ти значный номер вашего заказа и тд. он просто невидимый слуга, если же ничего больше не будете брать, идемте за мной”. Ведь большинство людей за один раз берут 1 товар.

image 
минус Описание товара в одну строку. Товар стоит за 30k, я считаю что покупатель в праве получить исчерпывающее описание товара + ссылки на ixbt обзоры и тд.
минус Отсутствие артикула, или он слишком длинный/сложный. Покупатель хочет заказать товар по телефону, как ему сказать, какой товар ему нужен, не диктовать же заводской артикул из непонятных символов, или полное название модели. Почему бы не упростить восприятие артикула от 345786v к 3.45.78.6.2. Не все знаю латинских букв, зачем вообще буквы в артикуле.
минус Сложное оформление покупки. Покупатель дошел до кассы, и тут кассир заставляет покупателя оформить какую-то карточку, заполнить анкетные данные, ответить на пару-тройку вопросов. Я бы ушел после такого. Не нужно пользователя вашего магазина заставлять регистрироваться на вашем сайте. Никому это не нужно. Спросите его (телефон, имя) или (адрес почты, скайпа и тд.), и скажите что свяжитесь с ним как можно скорее. Окончательное подтверждение товара, времени заказа, вариантов доставки, вариантов оплаты обговорить лично с менеджером. Личное общение располагает, и позволяет человеку максимально удобно для него получить товар. Не нужно человека просить заполнить адрес доставки, он может не знать: на работе лучше получить, или дома, все зависит от возможностей вашей службы логистики, расположенности точек выдачи товара и тд.
image

минус Трудности поиска товара. Покупатель может точно знать что ему нужно, а может только догадываться. Создайте гибкий поиск для разных степеней подготовленности пользователей. Кому-то хватит розового ноутбука, а кому-то нужен 15,6” с разрешением обязательно 1920x1080 и не меньше. В начале нужно понять степень осведомленности в вопросе, и в зависимости от вариантов ответов такой поиск и предоставлять.
минус Отсутствие мотивации дальнейших покупок. Система скидок на повторные покупки в магазине по прозрачной для пользователя идентификации (имя, средства связи, просто вопрос менеджера о наличие предыдущих покупок и тд.) Человек должен удивляться, что его помнят, дают какие-то бонусы…
image
минус Пожелания/жалобы. Как бы плохо не писали пользователи о работе вашего интернет-магазина, прятать такие сообщения не в коем случае нельзя – с ними нужно вести диалог, отсутствие оценки магазина встроенной системой оценок + сторонней (например Яндекс.Маркет) тоже вызовет недоверие. Пользователи будут набирать в поисковой системе “%название магазина% отзывы” . Прятать гниль нельзя, ее нужно срезать правильными выводами и делами.

Запомните. Главное правило торговли: Клиент всегда прав.

Saturday, April 17, 2010

Привязка модели данных к представлению на javascript

Я думаю многие пользуются DataBinding`ом в .NET, она же привязка данных. Она позволяет, при выделенной модели данных и независимом визуальном представлении, забыть о синхронизации данных с формой. Привязав один раз properties модели к элементам представления, мы избавляемся от десятков обработчиков onChange и подобных для изменения полей модели, а в случае изменения поля вне gui-интерфейса (например синхронизация модели с базой), мы не будем мешать уровни абстрации, чтобы обновить textBox.text. Давайте данные будут отдельно, gui отдельно. Плюс мы получаем наглядный, легко переносимый код на asp.net или даже на другой язык/платформу.

databinding

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

С развитием уровня web-ориентированных приложений, появилась возможность реализации подобного решения и на JavaScript. Ну думаю преимущества разделения данных от представления уже много где рассматривались и не раз приводили к холивару, так что упустим этот момент. Примеры буду рассматривать на jQuery Например, при классическом хранении данных в DOM структуре, сохранение сотки галочек в какой-то анкете (formBody) можно реализовать таким способом:

$('table#formBody input[name="available"][change=true]')
Флаг "change" используем для оптимизации выборки, т.е выбираем только измененные элементы А каждая галочка содержит теги idRef - id элемента, доступность которого она отражает Теперь, выбрав все элементы, перебираем их и переносим в хеш-массив
var find = {skills: []};
$j('table#formBody input[name="available"][change=true]').each(
 function(index, el){
  find.skills.push({ id: $j(el).attr('idRef'), val: ($j(el).attr('checked') ? 1 : 0) });
}
);

На родном функционале Javascript код будет достаточно громоздок, приводить его не буду, но суть не меняется.

Минусы очевидны, данные очень размазаны по всему DOM, редактирование логики модели или формы представления зачастую могут привезти к ошибкам, т.к. сложно все упомнить, за всем уследить, тем более если готовый html приходит из php, придется править два файла, что также может привезти к ошибкам. В поисках какого-то готового решения привязки данных на JavaScript, я обнаружил, что решений много, например только среди plug-in`ов jQuery я нашел jPop, JQBinder, Databind plug-in, jBind, JSRepeater, Chain.

Рассмотрим по порядку.

jPop

Особенности:

  • поддержка массивов.
  • однонаправленная синхронизация от представления к модели.
  • нельзя выбрать поле тега, к которому мы хотели бы привязать поле объекта, это либо value, либо innerHTML.
  • в качестве источника данных используется локальная модель.
  • нет документации

Принцип работы достаточно прост, Имя ключа (key) модели сопоставляется в id тега в DOM структуре и заполняется значением, вот небольшой пример, показывающий функционал плагина:

<h1 id="greeting" class="jpop_class"></h1>
<p id="greetingProp.greeting" class="jpop_class"></p>
<p>And,
<span id="greetingProp2:greetingArray" class="jpop_class">
<br><span id="greetingArray.greeting" class="jpop_class"></span>
</span>


$j(function() {
 var jso= {
  greeting: "Hello, World!",
  greetingProp: {
   greeting: "Hello again, World!"
  },
  greetingProp2: {
   greetingArray: [
    { greeting: "Hello, Nick!" },   
    { greeting: "Hello, Sri!" },
    { greeting: "Hello, Jody!" },
    { greeting: "Hello, Andrew!" },
    { greeting: "Hello, Heather!" },
    { greeting: "Hello, Ben!" }
   ]
  }
};
$j('.jpop_class').jpop(jso);
});

JQBinder

Особенности:

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

Пример:

<div id="#target">
<img src='$(.profile_image_url)' />
<div>$(.text)</div>
</div>

//Then, simply call
$("#stage").dataBindTo( { urlToJSONP, options } );

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

Databind plug-in

Особенности:

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

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

Пример:

  <form action="#" id="form1">
    <label for="txtName">Name</label><input type="text" id="txtName"><br>
    <label for="txtAge">Age</label><input type="text" id="txtAge"><br>
    <label for="drpGender">Gender</label><select id="drpGender"><option value="0">Female</option><option value="1">Male</option></select>
  </form>
var map = { name: '#txtName', age: '#txtAge', gender: '#drpGender', genders: '#drpGender' };
var data = { name: 'Jane Doe', age: 27, genders: [[0, 'Female'], [1, 'Male']], gender: 0 };

$('#form1').binddata(data, map); //Bind with a map

jBind

Особенности:

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

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

Пример:

  <div id='template2' style="display:none;">
   <div class="content">
    <!--data-->
     <div class="viewBlockLeft" id='{id}'>
      #{id}<br/>
      <b>{name} {family}</b>,<br/>
      <i>{education}</i>,<br/>
     </div>
    <!--data-->
    <div class="clear"></div>
   </div>
  </div>
var template = $('#template2').html();
var data = [
{
  id:41,
  name:'Scott',
  family:'Adams',
  education:'Economics'
},
{
  id:59,
  name:'Jack',
  family:'Welch',
  education:'Chemical Engineering'
}
];
alert($(template).bindTo(data));

JSRepeater

Особенности:

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

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

Пример использования:

var myData = {"Name" : "Google", "Type" : "Search Engine", "URL" : "www.google.com"};
$('#template1').fillTemplate(myData);


<div id='template1'>${Name} is a ${Type} found at <a href='${URL}'>${URL}</a></div>

Chain


Особенности:

  • хорошая документация.
  • возможность синхронизации с моделью через события, плюс возможность управлять процессом синхронизации.
  • поиск данных по модели.
  • возможность форматирования данных.
  • реализации drag&drop представления
  • очень много примеров

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

Пример:

$('<div><div class="name"><span class="first">First</span> <span class="last">Last</span></div></div>')
.item({first:'Steve', last:'Jobs'})
.chain({
  '.name .first': {
   style: 'color: blue;',
   content: 'First Name: {first}'
  },
  '.name .last': 'Family Name: {last}'
})
.appendTo(document.body);

Вот несколько примеров генерации таблиц http://javascriptly.com/2008/08/a-better-javascript-template-engine/

Еще пример:

  <div id="contact">
   <div class="name">My Name</div>
   <div class="address">My Address</div>
   <div class="country">Unknown Country</div>
  </div>
$('#contact').item({
  name: "Rizqi Ahmad",
  address: "Somestrasse 50, Hamburg",
  country: "Germany"
}).chain({
  '.name': 'Hello, My Name is {name}',
  '.address': 'My address is {address}',
  '.country': 'It is in {country}'
});
В результате имеем:
  <div id="contact">
   <div class="name">Hello, My Name is Rizqi Ahmad</div>
   <div class="address">My address is Somestrasse 50, Hamburg</div>
   <div class="country">It is in Germany</div>
  </div>

Подведем итоги, если нам нужна просто привязка с синхронизацией, стоит обратить внимание на jPop и немного его доработать. Если представление не ограничивается просто input`ами, а предполагает работу с динамическими табличками, списками, деревьями, с возможностями сортировки, drag&drop`а, то тут стоит всерьез изучить возможности библиотек от raid-ox. jQuery + Chain + Interaction очень может упростить жизнь JavaScript программисту для проектирования компактным и легкочитаемых web-приложений.

Удачного программирования!

Monday, April 12, 2010

Собираетесь в отпуск?

Going on Vacation?  

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

Перелет

Воспользуемся онлайн сервисом momondo.com, заполняем поля откуда летим и куда, выставляем примерные даты – смотрим на результаты поиска и подбираем самые дешевые билеты. После этого идем на tutu.ru и смотрим на эти же даты чартерные рейсы и спец. предложения, обычно разница в цене порядка 30%. Единственное неудобство: неизвестно до последнего момента на каком самолете летим, дата вылета может изменится на пару дней, да и цена может изменится.

Например я выбрал Анталию (Турция), самый дешевый билет (Москва-Анталия) на одного туда-обратно я нашел за 11,500 руб, спец. предложение же за 8,300 руб.

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

Проживании

Идем на booking.com и ищем по нужным критериям (город и дату вылета мы уже примерно знаем) наиболее подходящий отель. Плюс отзывы помогут отсеять плохие варианты. Есть даже варианты с трансфером от аэропорта.

3*** отель с завтраками, бесплатным wifi интернетом, недалеко от центра Анталии, почти на берегу моря (вторая линия), за одноместный номер просят – 135$/неделя. Бронируем!

Экскурсии и питание

 IMG_0600

Лично я не люблю пользоваться услугами экскурсоводов, ездить на туристическом автобусе, и вообще от кого-то зависеть. В google maps выбираем себе интересные места, которые стоит посетить, находим маршрут, еще лучше ставим google maps mobile и едем на общественном транспорте, любуемся пейзажами. Экономия на каждой экскурсии около 30-50$.

UPD: Плюс много интересной информация здесь Полезные ссылки бронирование отелей, аренду авто, авиа и т.д

Приятного отдыха!

Tuesday, April 6, 2010

Английский язык. Проблемы изучения

S7300002

Я думаю ни для кого не секрет, что существующая система преподавания не нацелена на быстрое и успешное изучение английского языка. Причина этой проблемы кроется за множеством факторов: репетиторы получающие большие деньги за час “помощи” вам, частные школы “делающие деньги”, устаревшие методы преподавания в учебных заведениях, авторы сотен книг очередных революционных методик “английский за 30 мин”, “железный занавес”, при котором родились большинство преподавателей. Обсуждение этой проблемы периодически всплывает на различных конференциях, но как говорится “а воз и ныне там”. Эта статья призвана помочь наверстать упущенные годы изучения языка.

Вспомнить

Самое главное не рассматривать изучение языка как цель, мы учим язык чтобы читать журналы, разговаривать с людьми, смотреть фильмы, воспринимать речь. Для начала вспомним основные правила английского языка, которых по правде сказать не очень много, а правильнее сказать очень не много. Но сразу акцентирую внимание на слово “вспомним”, не нужно учить правила, закреплять упражнениями. Пусть правила будут шпаргалкой, которая поможет понять “почему же тут on the end, а не at the end”. Т.е. не нужно искать правила в незнакомом английском тексте, нужно просто читать текст, а не понятные предложения, или их части, выписывать (ctrl+c, ctrl+v не подойдет) в блокнот. Книга Александра Драгункина “Быстрый английский” может помочь вам быстро вспомнить, или понять, какие-то правила, или особенности языка, которые в школе преподавались весьма изощренных способом. Но сразу скажу, читать его книги тяжело, много лишней информации, поэтому увлекаться его “новым русским” методом не советую. И давайте все-таки заведем блокнот, в котором структурируем правила из его книги, для простоты использования. Создадим себе шпаргалку.

Например мой вариант шпаргалки (который понятен и полезен, думаю, будет только мне)

Обязательный определитель Когда глаголы не меняются Глагол Be

Что скрывается под тремя стикерами:

употребление слова NO употребления слова ANY

Начать

Самый сложный шаг, неверный выбор которого может отбить всякое желание дальнейшего изучения. Сервис BBC Learning English вам в помощь, начнем с раздела How to… (http://www.bbc.co.uk/worldservice/learningenglish/language/howto/) Там есть разделы “Как … дискутировать”, “Как … вести беседу”, “Как … пояснить, спросить, посоветовать”, “Как … попросить, предложить, пригласить”, “Как … сообщить или отреагировать на новость”, “Как … пожаловать, извиниться или простить”.

Сейчас немного подготовимся к дальнейшей работе и постараемся сделать ее более продуктивной. Для начала будет сложно читать из-за небогатого словарного запаса, в помощь себе установим программку TranslateIt! или подобную для контекстного перевода слов с транскрипцией и произношением. Плюсы TranslateIt! в том, что она умеет захватывать текст почти с любых источников (web browser, pdf reader, notepad) что есть хорошо.

Давайте начнем с “How to ... Discussing” лекция “Making suggestions”.

Открываем лекцию по ссылке Script (pdf - 21k) на странице лекции, бегло читаем, т.е. особо не вдумываемся в смысл незнакомых предложений, просто “что поняли – то поняли”, выписываем в блокнотик незнакомые слова с переводом (как оптимизация процесса – создаем excel копируем незнакомые слова в столбик, после натравливаем google translate на весь столбик, и перевод уже копируем обратно, в соседний столбец, но после окончания работы с лекцией все-таки следует переписать эти слова в блокнот). Теперь скачиваем эту же лекцию в mp3 Download - mp3 (1.8mb) и на слух (закрываем pdf чтобы не отвлекаться) пытаемся понять смысл лекции, или хотя бы вспомнить те предложения, которые вы бегло прочитали. Да будет очень сложно понять эту речь, дикторы читают особо не выделяя отдельных слов паузами, местами проглатывая окончания. Но это первое время, уверяю вас. Прослушали. Теперь открываем pdf и начинаем работать абзацами. Читаем вслух первый абзац, четко выговаривая знакомые слова, незнакомые слушаем (и пытаемся повторить сами) в TranslateIt!, Lingvo, Google translate или любом другом удобном сервисе, главное чтобы не терять надолго текст из вида (отсюда минус словарей в виде книг, пока найдешь слово – забудешь текст). Теперь проигрываем этот абзац в mp3, проверяем правильность своей речи, и приступаем к детальному переводу. Переводим более менее литературным языком, но максимально приближенно к оригиналу. И так до конца лекции.

Теперь возвращаемся к главной странице лекции (http://www.bbc.co.uk/worldservice/learningenglish/radio/specials/1756_how_to_discuss/page2.shtml) Смотрим на таблицу, как на план лекции, в уме вспоминаем про что шла речь, и приступаем к упражнениям. План работы с упражнениями такой же: бегло читаем, слушаем, переводим по абзацам, прослушиваем еще раз абзац – отвечаем на вопросы.

И так 3 – 4 раза в неделю, главное выбрать конкретные дни и часы для изучения языка. Например понедельник, среда, пятница в 20:00. Это научит пунктуальности, один пропущенный урок может превратится в лень… и вы бросите изучение. У нас же цели более радужные.

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

Местом ваших занятий лучше выбрать какую-нибудь кофейню, где спокойно, не отвлекаясь на домашние дела, заниматься лекциями. Ноутбук и 3G модем с трафиком 2 мегабайта на лекцию (либо free wifi) помогут организовать мобильную лекционную аудиторию на двоих.

38f9bcc40db8cc2fe78b84f9bd2995ff_full

 

Войти во вкус

Параллельно с лекциями нам нужно будет учить слова, которые вы выписывали в блокнот. Как лучше учить? Тут однозначного ответа нет, у каждого память работает по-разному, мне проще писать карточки на картонках (визитках) – с одной стороны английское слово, с другой перевод, и повторять вечерами. Есть программы подобные “IT - незаметный преподаватель”, просто создаете свой словарь, и во время работы за компьютером, вы видите всплывающие слова с переводом. Повторюсь – кому как удобно, кто как лучше запоминает.

Помимо незнакомых слов нам нужно будет выучить неправильные глаголы, без них будет сложно. Чтобы облегчить вам эту задачу, советую посмотреть книгу Александра Драгункина "Неправильные глаголы”. Его разбивка глаголов на группы очень упрощает эту задачу.

Для практики советую вечерами смотреть по одной серии любимого мультсериала (Симпсоны, Гриффины, Футурама, Южный Парк и тд.) без перевода и субтитров. Предложения в них построены просто, речь четкая, местами разговорная. Постепенно вы будете понимать все больше предложений, и получать больше удовольствия от мультфильмов… и от себя конечное.

Результат

Пройдя весь курс лекций “How to ... Discussing” (5 лекций) вы, я думаю, заметите, что стали понимать язык гораздо лучше, на одну лекцию стало уходить гораздо меньше времени, речь на слух воспринимается гораздо более легче.

Wednesday, March 17, 2010

Профилактика SQL-инъекций



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

Почему же происходят SQL-инъекции


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

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

• Не использовать динамических запросов к базе.
• Не использовать пользовательских данных в запросах.

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

Что можно сделать для предотвращения SQL-инъекций


Хотя решение во многом зависит от конкретного языка программирования, все же общие принципы предотвращения SQL-инъекций схожи. Вот несколько примеров как это можно сделать:

• Использовать динамические запросы только в случае крайней необходимости.

Динамический запрос почти всегда можно заменить подготовленными выражениями (prepared statements), параметризованными запросами, или хранимыми процедурами. Например, вместо динамического SQL, в Java вы можете использовать PreparedStatement() с привязанными параметрами, в .NET вы можете использовать параметризованные запросы, такие как SqlCommand() или OleDbCommand()с привязанными параметрами, а в PHP вы можете использовать PDO со строгой типизацией параметризованных запросов (используя bindParam()).

В дополнение подготовленным выражениям (prepared statements), вы можете использовать хранимые процедуры. В отличие от подготовленных выражений (prepared statements), хранимые процедуры хранятся в базе, но в обоих случаях вначале определяется SQL-запрос, и в него передаются параметры.

• Проверка введенных данных в запросах.

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

• Не надеяться на волшебные Кавычки (Magic Quotes).

Включение параметра magic_quotes_gpc может предотвратить некоторые (но не все) SQL-инъекции. Magic quotes никак не последняя защита, и что еще хуже, иногда они выключены и вы не знаете об этом, или не имеете возможности его включить. Именно поэтому необходимо использовать код, который будет экранировать кавычки. Здесь кусок кода, предложенный Джоном Ли:

$username = $_POST['username'];
$password = $_POST['password'];
if (!get_magic_quotes_gpc()) {
  $username = addslashes($username);
  $password = addslashes($password);
}


• Регулярная и своевременная установка исправлений.

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

• Удаляйте весь функционал, который вы не используете.

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

• Использование автоматизированных средств нахождения SQL-инъекций.

Даже если разработчики следовали всем вышеописанным правилам, чтобы избежать динамических запросов с подстановкой непроверенных пользовательских данных, вы все равно должны подтвердить это тестами и проверками. Существуют автоматизированные средства тестирования, для выявления SQL-инъекций, и нет оправдания тем, кто не пользуется этими средствами для проверки процедур и запросов.
Один из простых инструментов (и один из более-менее надежных) для выявления SQL-инъекций это расширение для Firefox`а именуемое SQL Inject ME. После установки этого расширения, инструмент доступен по правому клику в контекстном меню, или из меню Tools → Options. Рабочая область SQL Inject ME показана на следующем скриншоте, и вы можете видеть как много видов тестов вы можете провести:





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

Множество параметров которые вы можете устанавливать для расширения SQL Inject ME, которые показаны на следующих двух скриншотах:





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

Saturday, March 13, 2010

Упрощаем восприятие продукта: Практические шаги



Мы две недели проектировали и создавали приложение для iPhone. Я послал письмо маме с названием программы и одной строчкой описания этого приложения. Она ответила одной фразой: "Я не понимаю". Мы выбросили исходники и саму программу и начали сначала.

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

Основная причина успеха программы: Убедитесь, чтобы описание вашей программы было предельно понятно. Если это не так, то упростите.

Когда вы сделаете это, то откроете для себя одно из двух:

1. У меня нет ни одного продукта
2. У меня есть продукт, который нужен людям.

Это как с Microsoft Word. Если бы вы предельно упростили ее, то получили бы блокнот. А блокнот - по прежнему является весьма полезным продуктом. Я могу описать блокнот в одном предложение: он позволяет мне создавать, сохранять и печатать документы.

Если вы не можете описать ваш продукт в одном предложение - вы не сможете его продать. Люди не хотят слушать ваши объяснения, им просто хочется простого и ясного ответа на вопрос: "Что она делает?" Если вам нужно два предложения, чтобы ответить на этот вопрос, то у вас проблемы.

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

Клиенты имеют два вопроса:

- Что она делает?
- Ага! И чем же она лучше той, которой я уже пользуюсь?

Ответьте на эти два вопроса в одном предложении, и вы будете зарабатывать деньги. Например, если бы я хотел продать Microsoft Word пользователям Блокнота, я бы ответил на эти вопросы примерно так:

- Она позволяет создавать, сохранять и печатать документы
- Вы можете сделать текст жирным, курсивным и добавить картинки

* Меры по упрощению *


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

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

3. После того как вы ответили покупателю на вопрос "Что она делает?" в одно предложение, он сказал "Ага!" и приступил к расспросу о ней? Если нет - меняйте пункты 1 и 2 пока этого не случится.

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

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

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