• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Доводы в пользу повышения безопасности криптокошельков

Marcus Aurelius

HDD-drive
Пользователь
Регистрация
02.04.2021
Сообщения
27
Реакции
79
Анатомия современного криптомошенничества

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

Обычно все начинается с твита или сообщения в какой-нибудь группе Telegram или канале Slack, где присылается ссылка, рекламирующая либо новый протокол доходного фермерства, сулящий большие APY, либо новый проект NFT, который только что начал майнинг. Для взаимодействия с сайтом пользователю необходимо подключить свой кошелек и выполнить некоторые шаги по подтверждению или авторизации.

Давайте рассмотрим распространенную аферу с подтверждением (approve) NFT. Пользователь попадает на вредоносный сайт NFT, рекламирующий ограниченную предварительную чеканку новой коллекции NFT. Затем пользователю предлагается подключить свой кошелек и подписать транзакцию, подтверждая создание цифрового актива. Однако по какой-то причине транзакция не проходит. То же самое происходит и при следующей попытке. С каждой неудачной попыткой пользователь все больше расстраивается, полагая, что из-за этой проблемы он упускает создание цифрового актива. Его концентрация и внимание немного смещаются от внимания к транзакциям к упущению прекрасной возможности.

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

(Изображение заимствовано из статьи "Как мошенники манипулируют смарт-контрактами для кражи и как этого избежать")

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

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

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

Доводы в пользу повышения безопасности криптокошельков

Никто не может отрицать, что внедрение технологий на основе блокчейна и Web3 оказало огромное влияние на мир. Многие из них предложили следующий общий набор функций:
  • перевод средств
  • обмен валюты без разрешения
  • децентрализованное управление
  • цифровые предметы коллекционирования
Независимо от технологического стека, используемого для создания этих платформ, в конечном итоге именно пользователи создают платформу. Это означает, что пользователям нужен способ взаимодействия с выбранной ими платформой. Сегодня наиболее удобным способом взаимодействия с платформами на основе блокчейна является использование криптокошелька. Проще говоря, криптокошелек - это часть программного обеспечения, которое упрощает подписание транзакций в блокчейне с помощью приватного ключа пользователя. Существует несколько типов кошельков, включая программные, аппаратные, кастодиальные и некастодиальные. В рамках данной статьи мы сосредоточимся на программных кошельках.

Прежде чем продолжить, давайте сделаем небольшой экскурс в Web2. В этом мире мы можем сказать, что платформы (также называемые сервисами, порталами или серверами) в основном построены с использованием технологий на базе TCP/IP. Для того чтобы пользователи могли взаимодействовать с ними, они используют user-агент, также известный как веб-браузер. Учитывая это, мы можем провести следующую параллель с Web3:
Технология
Протокол связи
User-агент
Web2​
HTTP/TLS​
Веб-браузер​
Web3​
Blockchain JSON RPC​
Криптокошелек​

Веб-браузеры, вероятно, гораздо, гораздо более сложные части программного обеспечения по сравнению с криптокошельками - и на то есть веские причины. По мере развития Интернета люди догадались, как размещать на нем различные мультимедийные данные, а веб-страницы позволили создавать динамический и скриптовый контент. Со временем развитие технологий HTML и CSS изменило то, что и как можно было отобразить на одной странице. Интернет стал местом, где люди общались, находили развлечения и совершали покупки. Браузеры должны были развиваться, чтобы поддерживать новые технологические достижения, что, в свою очередь, увеличивало сложность. Как и в любом другом программном обеспечении, сложность - это враг, и именно в сложности рождаются ошибки и уязвимости. Браузеры должны были внедрять средства контроля для снижения уязвимостей в Интернете, таких как спуфинг, XSS и перепривязывание DNS, и при этом обеспечивать безопасное взаимодействие через зашифрованные TLS-соединения.

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

Текущее состояние дел в мире Web3

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

1. Открыть Dapp

В большинстве случаев пользователь переходит в своем веб-браузере на URL, где размещен Dapp (например, Uniswap). Это приведет к загрузке веб-страницы, содержащей код Dapp. После загрузки Dapp попытается подключиться к кошельку пользователя.
i08_2.png


2. Авторизация Dapp

Некоторые из мер защиты, применяемых криптокошельками, включают в себя требование авторизации перед тем, как получить доступ к счетам пользователя и запросам на подписание транзакций. До появления EIP-1102 этого не было. Однако внедрение этих функций помогло сохранить анонимность пользователей, остановить спам в Dapp и предоставить пользователю возможность управлять доверенными и недоверенными доменами Dapp.
i07_3.png


Если все предыдущие шаги были выполнены успешно, пользователь может начать использовать Dapp.
Когда пользователь решает выполнить какое-либо действие (совершить транзакцию, купить NFT, застэйкать свои токены и т.д.), на кошельке пользователя появляется всплывающее окно с вопросом о том, подтверждает ли пользователь это действие. Параметры транзакции генерируются Dapp и передаются в кошелек. Если транзакция подтверждена, она будет подписана и опубликована в блокчейне, ожидая подтверждения.
i01_capture4.jpg


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

Учитывая это, давайте совершим еще один экскурс в мир Web2 и посмотрим, как выглядит подобное взаимодействие.


Как мир Web2 справляется с подобными ситуациями?

Как и в предыдущем примере, мы рассмотрим, что происходит, когда пользователь хочет использовать приложение Web2. Допустим, пользователь хочет проверить свой почтовый ящик. Он начнет с перехода в браузере на домен электронной почты (например, Gmail). В фоновом режиме браузер выполняет рукопожатие TLS, пытаясь установить безопасное соединение с серверами Gmail. Это позволит создать зашифрованный канал между браузером пользователя и серверами Gmail, исключая возможность подслушивания. Если рукопожатие прошло успешно, устанавливается зашифрованное соединение, о чем пользователю сообщается через пользовательский интерфейс браузера.

i05_5.png


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

Но что происходит, если это не так? Что происходит, когда сертификат по какой-то причине отклоняется браузером? В этом случае появляется массивное красное предупреждение, объясняющее пользователю, что произошло.
i04_6.jpg

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

Что можно сделать?

Криптокошельки должны показывать пользователю как можно больше информации о выполняемом действии. Пользователь должен видеть информацию о домене/приложении, с которым он взаимодействует. Детали о фактическом содержании транзакции, такие как вызываемая функция и ее параметры, должны отображаться в удобочитаемом для пользователя виде.

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

Доказательство владения смарт-контрактом

Важно доказать, что домен имеет право собственности на смарт-контракты, с которыми он взаимодействует. В настоящее время такого механизма, похоже, не существует. Однако мы считаем, что у нас есть хорошее решение. Подобно тому, как Apple осуществляет проверку доменов торговцев, для подтверждения права собственности можно использовать простой JSON-файл или dapp_file. Файл может храниться в корне домена Dapp по пути .well-known/dapp_file. JSON-файл может содержать следующую информацию:
  • адрес смарт-контракта, с которым взаимодействует Dapp
  • временная метка, показывающая, когда был сгенерирован файл
  • подпись содержимого, подтверждающая достоверность файла
На этом этапе читатель может сказать: "Как это показывает право собственности на контракт?". Ключом к этому является подпись. А именно, подпись генерируется с помощью закрытого ключа учетной записи, которая развернула контракт. Прозрачность блокчейна может быть использована для получения адреса развертывателя, который затем может быть использован для проверки подписи (аналогично тому, как смарт-контракты Ethereum проверяют подписи на цепи).

Этот механизм позволяет создать явную ассоциацию между смарт-контрактом и Dapp. В дальнейшем эта ассоциация может быть использована для дополнительной проверки.

Регистрационные записи доменов

Когда новый домен покупается или регистрируется, в публичном регистраторе создается публичная запись, указывающая на то, что домен принадлежит кому-то и больше не доступен для покупки. Доменное имя используется службой доменных имен, или DNS, которая переводит его (например, www.doyensec.com) в удобный для машины IP-адрес (например, 34.210.62.107).

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

Сертификаты TLS

Даты создания и истечения срока действия сертификатов TLS можно просматривать так же, как и записи DNS. Однако из-за короткого срока действия сертификатов, выдаваемых такими службами, как Let's Encrypt, существует большая вероятность того, что посетителям Dapp будет показан относительно новый сертификат.

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

Статус верификации исходного кода смарт-контракта

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

Дата развертывания смарт-контракта

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

Взаимодействие со смарт-контрактами

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

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

Наше предложение

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

В качестве пробного варианта мы реализовали простую веб-службу https://github.com/doyensec/wallet-info. Сервис использует общедоступную информацию, такую как записи регистрации доменов, информация о сертификатах TLS и данные, доступные через API Etherscan. Данные извлекаются, проверяются, анализируются и возвращаются вызывающей стороне.

Сервис предоставляет доступ к следующим конечным точкам:
  • /host?url=<url>
  • /contract?address=<address>
Данные, которые возвращают эти эйндпоинты, могут быть интегрированы в криптокошельки в двух точках взаимодействия с пользователем.

Первоначальный доступ к Dapp

Конечная точка /host может использоваться, когда пользователь первоначально подключается к Dapp. URL-адрес Dapp должен быть передан в качестве параметра конечной точки. Служба будет использовать предоставленный URL для сбора информации о веб-сайте и его конфигурации. Кроме того, сервис проверит наличие файла dapp_file в корне сайта и проверит его подпись. По окончании обработки сервис ответит:
JSON:
{
  "name": "Example Dapp",
  "timestamp": "2000-01-01T00:00:00Z",
  "domain": "app.example.com",
  "tls": true,
  "tls_issued_on": "2022-01-01T00:00:00Z",
  "tls_expires_on": "2022-01-01TT00:00:00Z",
  "dns_record_created": "2012-01-01T00:00:00Z",
  "dns_record_updated": "2022-08-14T00:01:31Z",
  "dns_record_expires": "2023-08-13T00:00:00Z",
  "dapp_file": true,
  "valid_signature": true
}

Эта информация может быть показана пользователю в диалоговом элементе пользовательского интерфейса, например:
i02_capture3.jpg

В качестве конкретного примера рассмотрим поддельный сайт Uniswap, который был активен во время написания этого поста. Если бы пользователь попытался подключить свой кошелек к Dapp, работающему на сайте, пользователю была бы возвращена следующая информация:
JSON:
{
  "name": null,
  "timestamp": null,
  "domain": "apply-uniswap.com",
  "tls": true,
  "tls_issued_on": "2023-02-06T22:37:19Z",
  "tls_expires_on": "2023-05-07T22:37:18Z",
  "dns_record_created": "2023-02-06T23:31:09Z",
  "dns_record_updated": "2023-02-06T23:31:10Z",
  "dns_record_expires": "2024-02-06T23:31:09Z",
  "dapp_file": false,
  "valid_signature": false
}

Отсутствующая информация из ответа отражает, что dapp_file не был найден на этом домене. Эта информация будет отражена в пользовательском интерфейсе, информируя пользователя о потенциальных проблемах с Dapp:
i03_capture2.jpg


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

Совершение транзакции

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

В нашем случае вызовы функций смарт-контракта представляют собой более интересную группу транзакций. Кошелек может получить информацию как о смарт-контракте, на котором будет вызвана функция, так и о параметре функции, представляющем получателя. Например, параметр spender в вызове функции approve(address spender, uint256 amount). Эта информация может быть получена в каждом конкретном случае, в зависимости от выполняемого вызова функции.

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

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

Пример ответа для данного адреса будет выглядеть следующим образом:

JSON:
{
  "is_contract": true,
  "contract_address": "0xF4134146AF2d511Dd5EA8cDB1C4AC88C57D60404",
  "contract_deployer": "0x002362c343061fef2b99d1a8f7c6aeafe54061af",
  "contract_deployed_on": "2023-01-01T00:00:00Z",
  "contract_tx_count": 10,
  "contract_unique_tx": 5,
  "valid_signature": true,
  "verified_source": false
}

В фоновом режиме веб-сервис будет собирать информацию о типе адреса (EOA или смарт-контракт), статусе проверки кода, информации о взаимодействии с адресом и т. д. Все это должно быть показано пользователю в рамках шага подтверждения транзакции.
i04_capture1.jpg

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

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

Заключение

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

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

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

Наша реализация веб-службы wallet-info является лишь примером того, как можно объединить публичную информацию. Эта информация в сочетании с хорошим дизайном UI/UX значительно повысит безопасность криптокошельков и, в свою очередь, безопасность всей экосистемы Web3.

Решит ли верификация Dapp полностью проблему фишинга/мошенничества? К сожалению, ответ отрицательный. Предложенные изменения могут помочь пользователям отличить легитимные проекты от потенциальных мошенников и подсказать им правильное решение. Целеустремленные злоумышленники, имея достаточно времени и средств, всегда смогут создать смарт-контракт, Dapp или веб-сайт, который будет выглядеть безобидно, используя описанные выше индикаторы. Это справедливо как для мира Web2, так и для мира Web3.

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


Переведено для xss.pro: The Case For Improving Crypto Wallet Security
Автор перевода: Marcus Aurelius

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


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх