Pull to refresh

Comments 55

Пожалуй первый убедительный ответ на гипотетическое повсеместное внедрение вредоносного пакета.
А что мешает вредоносному коду просто поменять адрес у iframe в аттрибуте src и загрузить свой собственный фрейм который отправит данные злоумышленникам?
UFO just landed and posted this here
Можно проксировать оригинальный фрейм через свой сервер добавляя в него вредонос
UFO just landed and posted this here
Нет никакой необходимости притворяться оригиналом, т.к. пользователь не увидит ни домен, ни url, ни зеленый замочек, для проксирования подойдет любой домен+сертификат letsencrypt
UFO just landed and posted this here
Недавно мы опубликовали перевод истории программиста, придумавшего способ распространения вредоносного кода, который собирает данные банковских карт и пароли с тысяч сайтов, оставаясь при этом незамеченным.

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


Первая статья сама по себе была довольно ужасна, а вторая часть это просто жесть какая-то. Поэтому у неё и рейтинг на hackernoon 7к против 160к первой. Отсутствие внятных комментарий к ней на hackernoon я могу объяснить только тем, что каждый достаточно погруженный в тему разработчик просто выкидывает свой ноутбук в окно после прочтения.


Предлагать использовать iframe для секьюрных данных… Почему не Flash, не Silverlight, не Java апплеты? Тоже же "отличные" решения. И столь же современные.


Из очевидных проблем, с которыми вы столкнётесь (простите, все не скажу, я бэкендер):


  • блокирование iframe в браузере и всяких адблокерах
  • невозможность использования родительских компонентов, стилей, библиотек, валидации карточных данных, обработки ошибок, предложений по партнёрским программам… Всего.
  • рассинхрон загрузки на два сайта. Сама возможность того, что у вас может загрузиться сайт и не загрузиться платёжная форма — это редкостная жесть.
  • если пользователь случайно заметит, что он вводит данные в iframe (который к тому же грузится с левого сайта), то он убежит в панике.

Ну и в целом можно просто забить в google вопрос "should i use iframes" и наслаждаться.
Никак не ожидал увидеть такую жесть в 2018 году.


Если вам кажется, что с этими двумя статьями что-то не так, и вам интересно, как такие проблемы решаются на самом деле, то рекомендую почитать две статьи — раз (почему это ложь) и два (что делать на самом деле).


P.S. Тем не менее, за перевод спасибо, конечно.

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

Не использовать iframe в приложениях и не использовать iframe когда это нужно (для защиты) это не совсем одно и то же. Переводить на страницу банка — это наиболее защищенный вариант т.к. пользователь может посмотреть на url, сертификат и т.п. ИТак работали все лет 5 назад. Сейчас параллельно к таким способам экваеры предлагают полагинны на iframe который по сути защищены так же как и отдельная страница.

Никакой контроль за «чистотой» библиотек не спасет от скриптов которые загружаются с других хостов (реклама, упомянутые GTM, fb ...). С учетом того что сейчас в тренде SPA приложения переход на оитдельную «чистую» страницу будет в большей степени ломать прилоджение чем асинхронность загрузки iframe.

С моей точки зрения процесс выглядит наоборот — раньше предлагали iframe, сейчас предлагают чистый переход. Пример с ТКС, киви и пейпалом я уже привёл — интересно, а кто делает наоборот?


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

PayPal например для Pro açcounts
Я пока что могу предположить всего одну уязвимость у iframe в сравнении с отдельной страницей: если в тексте страницы подменить адрес то на отдельной странице клиент имеет маленькую вероятность визуально заметить подмену а в iframe даже такой возможности нет.
Но на деле часто приходится долго и упорно доказывать что можно iframe, можно отдельную страницу — но только не открытые поля которые могут читать все. Первая реакция обычно такая: больной рвётся кого-то спасать, какие-то украденные cvv…

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


Full redirect is used (excluding in-context integration) — PayPal checkout pages are not embedded, framed, or loaded within a popup or new window

А по поводу


Первая реакция обычно такая: больной рвётся кого-то спасать, какие-то украденные cvv…

Так я и не говорил, что iframe обладает какими-то уязвимостями. Это примерно как отрезать себе руки и хранить их в отдельном сейфе — всё вроде бы безопасно, но есть нюанс.

Если вы можете обойтись формой оплаты на стороннем интеграторе — то всё отлично)
Но что если вам нужна форма у себя? Мы пока держим её на отдельном поддомене (первый вариант в статье), но очень хотим переехать на ифрейм (второй/третий варианты), а всё почему: можно не уводить юзера далеко от страницы с кнопкой оплаты (1) И не нужно расширять скоуп pci dss на эту страницу (2).
Буду только рад, если предложите мне альтернативу iframe в 2018 году =)

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

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


Насчёт конверсии хочется пруфов.

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

Если iframe ваш (что предлагает автор этой статьи), то ещё как отвечаете. За другой сервер, за его аптайм и безопасность, за скрипты, которые там лежат, за внешний вид всего этого добра, и так далее.

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

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


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

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


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

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

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

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

А с точки зрения владельца бизнеса iframe выглядит более привлекательно. Тут важно чтобы было адекватное представление об угрозе. Чисто для инетерса можно поклацать по формам сайтов кде есть карточки и убедиться что на странице есть и открытые поля (то есть не в iframe) и скриты GTM и fb. Я просто не хочу приводить тут ссылки т.к. потом типа обвинят во взломе оно мне надо?

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

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

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

Point taken. Сервер действительно порядком проще оградить от кражи данных.


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

Не совсем в тему, но близко: использовались скрипты GTM, маркетолог навнедрял туда что-то и когда провайдеры стали блокировать один из ресурсов, которые он подключил, то у части пользователей сайт перестал по факту работать. При том сложно было воспроизвести, поскольку только некоторые провайдеры просто отправляли запросы в /dev/null, а у остальных, возвращавших ошибки разных уровней, всё работало, кроме отправки данных на заблокированный сервис, и то ошибки скрывались. Мне и в голову прийти не могло, что у клиента исполняется код, которого нет в репозитории или в vendor/node-modules. И что провайдеры могут так блокировать.

Я не вникал в детальные причины такого поведения после диагностики, но по факту пока из внутренностей GTM шло обращение к заблокированному ресурсу, блокировалось исполнение "родного" JS страницы. Может криво сам GTM подключили, может скрипт этой метрики в него криво вставили, может комбинация "ответа на запрос соединения нет, а метрика работает под GTM" оказалось такой "удачной" — я не разбирался.

Предлагать использовать iframe для секьюрных данных…

iframe банки/платежные системы используют. Обозначенных Вами проблем скорее нет, чем они есть. Плюс iframe позволяет выдержать некоторые требования. Могу ошибиться, но на память iframe помогает, например, выдержать PCI DSS в той части, что данные не проходят через ваши сервера, а идут через сервера банка. Для SPA iframe хороший вариант. iframe в 2018 также хорош для определенных задач, как и в прошлом году.
Проблема не совсем в этом. В том что можно подменить iframe который надежный от процессинга на свой который отправляет данные куда угодно. При этом данные тоде не прозодят через нашии сервера но прозодят через сервера злоумышленника.
Согласен, iframe подменить можно. Думаю поэтому в цикле этих статей оговорено, что речь больше идет об универсальной, а не целенаправленной атаке. При подмене iframe в первом случае Вас быстро обнаружат. Тема второго случая в статьях не раскрывается.
Если атакующий успешно внедрил куда-либо какой-либо код, то, в общем и целом, говорить уже не о чем.
JS лучший язык для веб разработки (с) любой девелопер со смузи в руке

Отдать в браузер страницу сформированную на бэкэнде без посторонних скриптов, с обычной загрузкой страницы и нативной отправкой данных на сервер. Ой, постойте, это ведь уже было, а мы нынче в 2018 году и без npm жизнь не жизнь :)
Ну и как вы будете формировать страницу на бэкэнде «без посторонних скриптов»?
Ну, формально, отдать голый хтмл код наверное любой серверный язык ещё может без всяких там фреймворков =)
UFO just landed and posted this here
А вот сделать это безопасно — уже не любой. Как минимум, нужен слой который будет автоматически экранировать все выводимые выражения (шаблонизатор, причем не любой). Потому что атаку через HTML-инъекцию провести на порядок проще чем внедриться через npm-пакет.
Ну от формы конечно зависит, но в простейшем виде это 3-4 поля с карточными данными, 3 из которых достаточно привести к числам и только одно (холдера) надо бы почистить? Без шаблонизатора точно не обойтись?)
И этот сервер написан на nodejs с npm :)
iframe — это как бы обязательное условие (если не отдельная страница). Лучше если такой iframe поставляет эквайер. Вы храните у себя идентификатор например заказа который передаете экваеру а за все остальное отвечает только экваер.

Но вот этот код
 var payload = {
        type: 'bananas',
        formData: {
          a: form.ccname.value,
          b: form.cardnumber.value,
          c: form.cvc.value,
          d: form['cc-exp'].value,
        },
      };
      window.parent.postMessage(payload, 'https://mysite.com');

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

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

Что касается всех СЕО-админок (GTM и т.п.) то там простол в интерфейсе можно настроить логировать поля Х и У с такой-то формы. Не нужно и взлома никакого.

Если загружена скажем библиотека facebook для лайков или еще для чего то там просто можно видеть что на каждый submit идет отправка событий на fb. Конечно fb не будет мелочь по карманам тырить(ТМ) но там тоже люби работают.

В статье для ввода платежных данных предлагается рисовать отдельную форму в iframe, с упрощенным внешним видом и функциональностью.


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

Ну, обычно не с совсем другим, а поддоменом. И в любом случае сертификаты обоих на одно лицо.

Хорошо, опустим момент про домены.


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

Ну на счёт дизайна и функциональности — тут да. Если уж делать свой iframe, то выделяться на общем фоне сайта он не должен. С другой стороны, пробежался сейчас ещё раз по статье и не вижу рекомендации "портить" дизайн и функциональность. Разве что отнести к ней пример валидации формы чисто на HTML+CSS, но я его воспринял просто как пример, что можно даже так.


Основной же поинт, по-моему, в том, что HTML+CSS+JS код такой формы не должен содержать сторонних зависимостей или быть собран инструментами, которым не доверяешь абсолютно. То есть в условиях нормальной для разработчика, имеющего дело с особо (в рамках проекта) чувствительными данными, паранойи должен быть написан полностью вручную, без фреймворков типа ангуляра, библиотек типа редакса, реакта или даже джиквери с лодашем, а также без сборщиков типа вебпака и даже без минификаторов, по крайней мере без ручной проверки сгенерированного кода.

P.S. Заметная деградация в дизайне/функциональности при выборе такого решения (фрейм или отдельная страница без зависимостей) может быть в паре случаев:


  • разработчик недостаточно компетентен, чтобы реализовать нужный дизайн/функциональность без этих зависимостей, то есть не HTML+CSS+JS разработчик, а {framework/lib name}-разработчик.
  • бизнес не готов на пару таких страничек тратить ресурсы сравнимые с ресурсами нужными на нескольких десятков обычных.

Возникает вопрос: если получается сделать важную форму оплаты на ванильном JS без фреймворков, то зачем их тащить на остальные части сайта?


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

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

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


Можно, конечно, вынести данные оплаты на отдельную страницу и оформить отдельным шагом. Но в этом случае iframe не нужен совсем. Главное очистить эту страницу от лишних скриптов.

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


Хотя, по большому счёту iframe или страница — это прежде UX/UI-решение. Технически и административно главное отделить работу с особо чувствительными данными от остальных, вплоть до полностью изолированного контура разработки и эксплуатации, куда не имеют доступа рядовые разработчики и админы.

Форма оплаты и форма с проверкой карты это совсем не одно и то же. Как правило перед тем как отправлять пользователя на действия с картой нужно уже иметь в базе данных идентификатор заказа и его сумму. После чего заказ будет принятым но не оплаченным. После того как Вы отправите пользователя на процессинг с заведомо уже сохраненным идентификатором заказа, то он пройдет все возможные варианты проверки (включая смс, звонок на сотовый и т.п.) после чего процессинг пришлет Вам ответ в iframe и Вы сможете сгенерировать событие в родительское окно как указано в этой статье (но конечно без реквизитов карты). Для интерактива с пользователем этого достаточно. После чего заказ все еще не считается оплаченным т.к. нужно будет забирать с процессинга статусы транзакции и в зависимости от бизнеса считать заявку оплаченной или не оплаченной. Если это например покупка билетов в кинотеатр то скорее всего бизнес проиграет если ожидаться окончательных статусов которые могут прийти в срок вполть до недели (типа «транзакция находится на проверке и т.п.»). Если это продажа Cadillac Escalade то логично было бы дождаться поступления средст на счет магазина.
Большую опасность несут не Фрей верки а скрипты которые на сайт приходят из других хостов. Например реклама, GTM, fb.
Да.это так. Но ещё лучше если такой кустом Изотова оный iframe предоставит процессинг. Конечно это будут дополнительные затраты.
Sign up to leave a comment.