Сразу вспоминается такой пример (сейчас сам удивляюсь, насколько наивным был мой подход при разработке): разрабатывали мы "типовое" приложение для POS терминала (для приёма оплаты по банковским картам), и при разработке пользовательского интерфейса, базируясь на предыдущем опыте, поставили туда максимум защиты. Выполнение операции оплаты выглядело следующим образом:
- терминал находится в заблокированном состоянии (отображает логотип)
- кассир вводит пароль для доступа в меню
- кассир проводит картой
- терминал определяет тип карты и отображает его для подтверждения
- терминал просит кассира ввести вручную последние четыре цифры номера карты для сверки
- кассир выбирает валюту операции и вводит сумму
- терминал отображает финальное окно подтверждения, на котором указаны номер карты, валюта, сумма, наименование операции
- после подтверждения операции терминал выполняет транзакцию, печатает чек покупателя и чек кассира
- терминал возвращается в заблокированное состояние
Мы, помню, очень гордились такой высокой защищённостью нашего приложения. Дали терминал очередному клиенту для ознакомления, а он поставил его для "боевой обкатки" в своей столовой, в которой сотрудники расплачивались корпоративными картами.
Через неделю получаем срочный запрос: поотключать все меню и проверки, и оставить только такую последовательность:
- терминал постоянно готов к проведению оплаты
- кассир проводит картой
- кассир вводит сумму
- терминал проводит транзакцию, печатает короткий чек покупателя
- терминал возвращается в состояние готовности к проведению следующей оплаты
Вы, наверное, уже догадались, что после установки нашего терминала в столовой, в первый же обеденный перерыв начали скапливаться огромные очереди. Помучившись с ним полчаса, кассирша волевым решением просто отключила терминал нафиг и поставила вместо него привычную модель наших конкурентов. А выяснилось это, только когда начальник отдела, с которым мы общались, зашёл в столовую пообедать.