February 29, 2024

Подписи в MetaMask


камеоандрея | Подписаться


В MetaMask (в остальных EVM-кошельках ± то же самое) есть три способа подписать сообщение. Давайте рассмотрим, чем эти способы отличаются, какие из них относительно безопасны, а какие оставят вас без штанов.

TL; DR

Просто не подписывайте то, чего не запрашивали и/или не понимаете. И eth_sign не включайте. Вообще. Никогда.

🟢Подпись обычного текста

В основном используется для аутентификации кошелька — вы подписываете человекочитаемое текстовое сообщение, оно отправляется на сервер, который проверяет подпись и открывает вам доступ к какому-то контенту. По сути, аналог всяких «Войти через Google» из Web2.

Вообще именно для цели аутентификации есть целый отдельный стандарт Sign-In with Ethereum, который очень красиво и наглядно отображается в MetaMask, но вы всё ещё можете встретить старые реализации того же самого. Просто сравните.

Sign-In with Ethereum
Подпись обычного текста (кстати, скам-сайт)

Для разработчиков

Такие подписи делаются с помощью метода personal_sign в MetaMask. А Sign-In with Ethereum описан в ERC-4361.

И, ради бога, не используйте его так.

Не делайте так

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

🟡Подпись структурированных данных

Как видите, всё отображается в красивом, иерархическом виде; адреса со ссылками на эксплореры.

Запрос подписи структурированных данных

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

Остался без $DAI

А подписав такое, я останусь без NFT.

Остался без MAYC

Такие запросы гораздо опасней предыдущего типа, но в глубине настроек MetaMask нас ждёт самое страшное…

Для разработчиков

Подпись структурированных данных выполняется с помощью метода eth_signTypedData_v4.

🔴Подпись «сырых» данных

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

Что произойдёт?

Хоть MetaMask и выключил этот метод по умолчанию, но он убрал красными буквами предупреждение об опасности такой подписи. И вы никак визуально не отличите этот метод от относительно безопасного первого (если вы, конечно, всё-таки включили eth_sign в настройках). А что скрывается за этим сообщением — известно только dApp или злоумышленнику. Может, с вашего кошелька выведут весь эфир. Может, токены спишутся. Может, NFT. Может, всё вместе. А может, просто сообщение с текстом «жопа» подпишете.

Для разработчиков

У MetaMask есть песочница, в которой можно потестить разные виды подписи и остальной функционал кошелька.

Выводы

А вместо выводов повторю выноску из начала статьи.

TL; DR

Просто не подписывайте то, чего не запрашивали и/или не понимаете. И eth_sign не включайте. Вообще. Никогда.