امنیت کیف پول

هر popup کیف پول یک «امضا» نیست؛ اول نوع اختیار را تشخیص دهید

هر popup کیف پول یک «امضا» نیست؛ اول نوع اختیار را تشخیص دهید

روی وب‌سایت شاید فقط «Continue» یا «Verify» ببینید، اما کیف پول ممکن است login message، allowance توکن، اختیار operator برای NFT یا انتقال مستقیم دارایی بخواهد. تصمیم را بر اساس network، method، contract، spender، amount و message در خود popup بگیرید، نه رنگ button یا محبوبیت پروژه.

نوع wallet request را چطور سریع تشخیص دهیم؟

وجود gas، readable message، spender، asset change یا contract call را بررسی کنید. اتصال ساده آدرس معمولاً gas ندارد. Message signature خودش وارد block نمی‌شود. Approve و transfer روی chain هستند. Permit شاید هنگام امضا gas نداشته باشد، اما شخص دیگری می‌تواند آن را submit و allowance را فعال کند.

Requestنمایش معمولروی chain؟خطر اصلی
ConnectAccount/address accessخیرارتباط address و profile سایت
personal_signText یا hex messageخود signature خیرLogin یا off-chain consent
EIP-712Domain و structured fieldsخود signature خیرOrder، permit یا delegation
approveAllow spenderبلهمصرف token تا سقف allowance
permitOwner، spender، value، deadlineبعداً قابل submitAllowance از طریق signature
TransactionTo، value، gas، dataبلهانتقال asset یا تغییر state

واژه‌های کیف پول‌ها متفاوت‌اند. بخش Details، Data، Permission یا Advanced را باز کنید. اگر field مهم نمایش داده نمی‌شود، جمله «safe» در همان سایت دلیل مستقل نیست. رد کردن request دارایی معتبر را حذف نمی‌کند؛ flow رسمی را دوباره می‌توان شروع کرد.

یک request در wallet آمده — آیا می‌شود امضایش کرد؟

بر اساس چیزی که واقعاً در popup نوشته شده تصمیم بگیرید، نه برچسب دکمه وب‌سایت. در جدول زیر هر جا «می‌شود» آمده، دو شرط دارد: دامنه نوار آدرس مرورگر را خودتان از وب‌سایت یا docs رسمی باز کرده‌اید، و این مرحله واقعاً برای کاری که الان انجام می‌دهید لازم است. اگر حتی یکی از این دو برقرار نبود، آن را reject حساب کنید.

آنچه در popup می‌بینیدامضا کنیم؟چه چیزی را تطبیق دهیم
Connect / Connect to this site — فقط account، بدون مبلغ یا gasاگر دامنه درست است، می‌شودفقط account همین کار را انتخاب کنید، نه account دارایی اصلی.
Sign message — متن خوانا مثل «Sign in to یک دامنه» همراه Nonce و Issued Atمی‌شوددامنه داخل message باید دقیقاً با نوار آدرس یکی باشد؛ اگر در متن transfer، approve یا withdraw آمده، reject کنید.
Sign message — hex طولانی که با 0x شروع می‌شود، یا wallet می‌گوید محتوا قابل نمایش نیستRejectوقتی نمی‌فهمید، نمی‌دانید با چه چیزی موافقت می‌کنید. MetaMask طبق پیشنهاد MIP-3 که در 2024 پذیرفته شد، متد eth_sign را که امکان blind sign هر داده‌ای را می‌داد کنار گذاشته است؛ صفحه‌ای که هنوز چنین امضایی می‌خواهد خودش مشکوک است.
Signature request با Permit، PermitSingle، PermitBatch یا fieldهای spender، value و deadlineآن را token approval حساب کنید؛ بیشتر وقت‌ها rejectفقط هنگام swap یا stake در صفحه رسمی بررسی کنید؛ spender باید با contract اعلام‌شده در official docs یکی باشد، value نباید عدد حداکثری طولانی‌ای باشد که با 115792… شروع می‌شود، و deadline نباید چند دهه بعد باشد.
Spending cap request، Approve، Allow … to spend your tokenفقط وقتی مرحله فعلی لازمش داردToken و spender را تطبیق دهید؛ به‌جای unlimited پیش‌فرض، مقدار لازم همین بار را بنویسید.
setApprovalForAll، یا نوشته شده به همه NFTهای یک collection دسترسی یا امکان انتقال داردجز برای listing در NFT marketplace رسمی، همیشه rejectبرای «verify ownership» یا «claim badge» لازم نیست اختیار کل collection را بدهید.
Transaction confirm — در asset changes سکه یا NFT شما خارج می‌شوداگر قصد پرداخت آن را ندارید، rejectصفحه Claim، Mint یا Verify نوشته اما wallet خروج دارایی نشان می‌دهد؛ یعنی حرف صفحه با call واقعی نمی‌خواند.

زدن Reject یا Cancel هیچ دارایی‌ای را از بین نمی‌برد و پروژه معتبر به‌خاطرش eligibility شما را لغو نمی‌کند؛ بعداً از لینک رسمی صفحه را دوباره باز کنید. اگر مطمئن نیستید، اسکرین‌شات popup را (با پوشاندن موجودی) در کانال پشتیبانی عمومی که در docs پروژه آمده بپرسید؛ به کسی که در پیام خصوصی پیشنهاد «کمک» می‌دهد جواب ندهید.

Connect Wallet چه اطلاعاتی به وب‌سایت می‌دهد؟

Connect معمولاً public address انتخاب‌شده، active chain و قابلیت‌های کیف پول را در اختیار سایت می‌گذارد؛ spending approval نیست. با این حال privacy cost دارد. تاریخچه آدرس عمومی است و سایت می‌تواند آن را به browser session، social login یا campaign profile مرتبط کند.

کیف پول جداگانه برای testnet، exposure آدرس نگهداری اصلی را کم می‌کند. تفاوت account دیگر روی همان seed با walletی دارای seed کاملاً تازه را بفهمید. رابطه accountهای یک seed همیشه مستقیم روی chain مشخص نیست، اما transfer و الگوی استفاده می‌تواند آن‌ها را مرتبط کند. High-value wallet را به task page ناشناس وصل نکنید.

هر popup بعد از connect یک request تازه است. الگوی phishing می‌تواند با اتصال بی‌خطر شروع شود و سپس approve یا permit نمایش دهد، وقتی کاربر به confirm عادت کرده است. کم‌خطر بودن popup اول، دومی را امن نمی‌کند. درخواست‌های متوالی را cancel و مراحل مورد انتظار را در docs بخوانید.

Disconnect در Connected sites فقط session front end را تمام می‌کند، نه on-chain approval را. پاک کردن history، lock کردن wallet یا reinstall extension نیز allowance را حذف نمی‌کند. Privacy connection و blockchain permission دو record جدا هستند.

personal_sign برای login چه زمانی ریسک کمتری دارد؟

Message قابل‌خواندن با domain درست، هدف روشن و nonce معمولاً برای login محدود استفاده می‌شود، اما نباید blind sign شود. EIP-191 برای جدا کردن signed data از transaction معمولی prefix تعریف می‌کند؛ درباره صداقت هدف message تضمین نمی‌دهد.

Login message مناسب چه چیزهایی دارد؟

Service domain، wallet address، statement ورود، random nonce، issued time و در صورت نیاز expiry باید دیده شوند. Domain مرورگر و message را تطبیق دهید. «Sign in to example.org» قابل فهم است؛ domain متفاوت، terms باز یا عبارت نامرتبط با asset دلیل رد است.

Zero gas یعنی zero risk نیست

Message به‌صورت local امضا می‌شود و gas ندارد. Service می‌تواند از signature برای اثبات پذیرش یک statement استفاده کند. سایت بدخواه شاید آن را login token، marketplace order یا authorization دیگری به‌کار ببرد. Gas فقط fee را توضیح می‌دهد، نه ارزش permission را.

با hex message چه کنیم؟

اگر payload قابل خواندن نیست، امضا نکنید و method دقیق را در docs پروژه پیدا کنید. اگر hardware wallet اطلاعات کمی نشان می‌دهد، full data را در interface دسکتاپ کیف پول ببینید. «فقط برای verification» که خود سایت نوشته، توضیح مستقل نیست چون همان سایت request را ساخته است.

برای login signature نباید seed phrase، password یا OTP را در form وارد کنید. Wallet خودش signature را می‌سازد. صفحه‌ای که secret جداگانه می‌خواهد باید بسته شود.

چرا EIP-712 خوانا هنوز می‌تواند خطرناک باشد؟

EIP-712 داده را به domain، type و field تقسیم می‌کند تا wallet آن را بهتر نشان دهد؛ خوانایی permission را بی‌خطر نمی‌کند. Marketplace order، governance vote، permit، smart-account action و delegation از آن استفاده می‌کنند. هر دو بخش domain و message را بخوانید.

Domain fields

Name، version، chainId و verifyingContract را ببینید. اگر صفحه testnet می‌گوید ولی chainId mainnet است، توقف کنید. Contract را با official docs یا verified explorer تطبیق دهید. Name فقط text و قابل copy است؛ address و chain context اهمیت بیشتری دارند.

Message fields

Owner آدرس شماست؟ Spender یا operator چه کسی است؟ Value چقدر است؟ Deadline و nonce چیست؟ اگر عدد بزرگ با scientific notation نشان داده می‌شود، details را باز و token decimals را درک کنید. Allowance کوچک test با unlimited value برای unknown spender یکسان نیست.

Deadline و replay

Deadline باز یا بسیار دور اجازه استفاده دیرهنگام می‌دهد. Nonce معمولاً replay را متوقف می‌کند، ولی به implementation وابسته است. کاربر از روی popup نمی‌تواند همه code را audit کند؛ به همین دلیل official contract و documented flow لازم‌اند.

حتی اگر نام field «Login» باشد، type ممکن است permit یا order باشد. Method کیف پول و verifying contract را بخوانید، نه caption شبکه اجتماعی را.

Approve، permit و setApprovalForAll چه تفاوتی دارند؟

هر سه می‌توانند به آدرس دیگری اختیار بدهند، اما نوع asset، محدوده و روش submit فرق می‌کند. ERC-20 approve به spender allowance می‌دهد. EIP-2612 permit همان مفهوم را با signature بیان می‌کند که relayer می‌تواند submit کند. NFT setApprovalForAll ممکن است کل collection را پوشش دهد.

سه field اصلی approve

Token contract، spender و amount را تطبیق دهید. Approve transaction on-chain و دارای gas است. Unlimited allowance interaction بعدی را ساده می‌کند اما exposure در زمان compromise یا upgrade contract را بیشتر می‌کند. درخواست mainnet stablecoin در task آزمایشی با هدف سازگار نیست.

Permit بدون gas هم permission واقعی است

کیف پول شاید فقط «signature request» بنویسد، اما owner، spender، value، deadline و verifyingContract می‌توانند spending allowance بسازند. مهاجم signature را خودش submit می‌کند. Disconnect آن را cancel نمی‌کند. پس از permit مشکوک، استفاده on-chain را بررسی، راه revoke مخصوص token را پیدا و در صورت خطر دارایی مهم را منتقل کنید.

NFT operator ممکن است کل collection را بگیرد

setApprovalForAll تنها یک NFT را پوشش نمی‌دهد. اگر صفحه برای «verify ownership» یا «mint pass» اختیار کامل collection mainnet می‌خواهد، دلیل رسمی را پیدا کنید. چنین محدوده‌ای برای test badge معمولاً متناسب نیست.

Approval با بسته شدن سایت، حذف app یا disconnect session باقی می‌ماند. مصرف کامل allowance، صفر کردن، revoke operator یا rule خاص contract وضعیت را عوض می‌کند. بعد از high-permission action و هنگام خروج از project review کنید.

کدام fieldهای transaction popup را نباید رد کرد؟

Network، From، To، value، token changes، contract method و نتیجه مورد انتظار را تطبیق دهید. Button ممکن است Claim، Mint یا Verify باشد، ولی data عمل on-chain را تعیین می‌کند. transferFrom، multicall یا unknown method فقط به‌خاطر label خوب امن نیست.

  1. Chain ID همان testnet مورد انتظار است؟ اگر mainnet gas symbol آمد cancel کنید.
  2. From address همان test wallet است، نه holding wallet؟
  3. To address با official contract یا recipient هماهنگ است؟
  4. اگر native value صفر نیست، علت ارسال asset را می‌فهمید؟
  5. در token/NFT changes خروجی نامنتظره دیده می‌شود؟
  6. Method و parameters به task فعلی مربوط‌اند؟
  7. Simulation را بخوانید، ولی guarantee فرض نکنید.

Gas کم، transaction بدخواه را امن نمی‌کند. Gas هزینه اجراست نه امتیاز امنیت. Failed simulation نیز به‌تنهایی scam را ثابت نمی‌کند؛ RPC یا decoder ممکن است مشکل داشته باشد. در تعارض page و wallet، confirm نکنید و از support فنی رسمی بپرسید.

Logic یک upgradeable proxy ممکن است بعداً تغییر کند. Simulation state فعلی و decoder موجود را می‌بیند؛ delayed execution، reused signature یا upgrade بعدی شاید دیده نشود. Limited permission و verified source همچنان مهم‌اند.

پیش از هر امضا چه بررسی شش‌مرحله‌ای داشته باشیم؟

Domain—network—request type—target—scope—exit path را همیشه با همین ترتیب طی کنید. این روال از follower count، endorsement یا interface زیبا قابل اعتمادتر است.

  1. Domain: از official website یا docs وارد شوید؛ spelling و subdomain را ببینید.
  2. Network: Chain ID و selected account را بررسی و test wallet را جدا کنید.
  3. Type: Connect، message، typed data، allowance یا transaction؟
  4. Target: Contract، spender، operator، recipient و token را تطبیق دهید.
  5. Scope: Amount، unlimited flag، NFT collection، deadline و replay را بفهمید.
  6. Exit: راه disconnect، revoke، cancel یا انتقال asset را بدانید.

اگر field مهم روشن نیست، details را باز کنید. اگر هنوز توضیح‌پذیر نیست، cancel کنید. دادن permission کیف پول اصلی برای airdrop نامطمئن risk-reward ضعیفی دارد. پروژه معتبر زمان مطالعه می‌دهد؛ countdown و فشار ادمین خصوصی هشدارند.

در موبایل address کوتاه‌شده است. آن را copy و با آدرس official کامل مقایسه کنید، اما در chat عمومی paste نکنید. WalletConnect QR را در screen share نشان ندهید. Seed را در device مشترک import نکنید.

اگر approve، permit یا setApprovalForAll را اشتباهی امضا کردید، حالا چه کنید؟

اول بفهمید چه نوعی را امضا کرده‌اید، بعد قدم متناسب را بردارید. اگر فقط به سایت مشکوک connect شده‌اید و چیزی امضا نکرده‌اید، disconnect از Connected sites کیف پول کافی است و دارایی در خطر نیست. اگر یادتان نیست چه امضا کرده‌اید، آدرس خودتان را در block explorer باز کنید و در رکوردهای اخیر دنبال Approve، Set Approval For All یا Transfer ناشناس بگردید. هیچ‌کدام از قدم‌های زیر به seed phrase نیاز ندارد؛ هر «ابزار تعمیری» که seed phrase بخواهد کلاهبرداری است.

approve یا setApprovalForAll داده‌اید: در صفحه revoke مجوز را صفر کنید

  1. نشانی را خودتان در نوار آدرس تایپ کنید و ابزار revoke را باز کنید، مثل revoke.cash یا Token Approval Checker در Etherscan (etherscan.io/tokenapprovalchecker؛ برای BNB Chain صفحه هم‌نام در BscScan). روی «لینک revoke» که در پیام خصوصی یا گروه فرستاده شده کلیک نکنید.
  2. کیف پول را connect کنید یا اول فقط آدرس را جای‌گذاری و بررسی کنید؛ network را روی همان chain بگذارید که approval را در آن داده‌اید، چون approval در هر chain جدا ثبت می‌شود.
  3. بر اساس زمان مرتب کنید، spender یا operator ناشناس را پیدا کنید و Revoke را بزنید.
  4. کیف پول یک تراکنش نشان می‌دهد؛ مطمئن شوید کارش revoke است (مقدار approve صفر، یا setApprovalForAll برابر false) و برای gas کمی native coin لازم است. اگر gas ندارید، اول مقدار کمی واریز کنید.
  5. بعد از موفق شدن تراکنش، فهرست را refresh کنید و ببینید آن ردیف حذف شده است. جزئیات بیشتر در راهنمای revoke کردن approval آمده است.

Revoke فقط جلوی انتقال‌های بعدی را می‌گیرد؛ آنچه رفته برنمی‌گردد. اگر موجودی در حال کم شدن است، اول باقی سکه‌ها و NFTها را به کیف پول جدید ببرید و بعد revoke کنید.

permit یا امضای Permit2 داده‌اید: اول ببینید روی chain ثبت شده یا نه

Permit خودش فقط یک امضاست و وقتی اثر می‌کند که طرف مقابل آن را روی chain ثبت کند. آدرس خودتان را در block explorer باز کنید و ببینید spender آن‌ها در رکورد approval یا eventهای اخیر آن توکن ظاهر شده است یا نه:

  • ظاهر شده: مانند بخش قبل revoke کنید و بررسی کنید موجودی توکن رفته است یا نه.
  • هنوز ظاهر نشده: امن‌ترین کار این است که همین حالا آن توکن را به کیف پول دیگری منتقل کنید تا allowance امضا چیزی برای برداشتن نداشته باشد. در صفحه Signatures سایت Revoke.cash می‌شود برای لغو امضای مشکوک تلاش کرد، اما خودشان نوشته‌اند کلاهبرداران معمولاً به‌محض گرفتن امضا آن را ثبت می‌کنند و اغلب فرصتی نمی‌ماند.

فقط پیام ورود personal_sign را امضا کرده‌اید: معمولاً سکه‌ای از دست نمی‌رود، اما سه کار انجام دهید

امضای پیام معمولی با پیشوند EIP-191 را نمی‌توان به‌عنوان تراکنش انتقال استفاده کرد و این همان داده ساختاریافته EIP-712 که permit لازم دارد هم نیست؛ پس به‌تنهایی معمولاً نمی‌تواند توکن‌های شما را جابه‌جا کند. این کارها را بکنید:

  1. متن امضاشده را به یاد بیاورید یا در اسکرین‌شات ببینید. اگر متن فقط ورود نبود و در آن authorize، order، key یا trading آمده بود، به وب‌سایت رسمی همان platform بروید و دستگاه‌های واردشده، sessionها و API keyها را بررسی و یکی‌یکی حذف کنید.
  2. آن سایت را از کیف پول disconnect کنید و هر approve یا permit بعدی از آنجا را reject کنید.
  3. اگر در سایت جعلی امضا کرده‌اید، آدرس شما دست آن‌هاست؛ ممکن است توکن airdrop جعلی و «لینک claim» برسد، روی آن کلیک نکنید. فقط به‌خاطر پیام ورود لازم نیست کیف پول را عوض کنید.

سکه به‌محض واریز ناپدید می‌شود: مشکل approval نیست، private key یا seed phrase لو رفته است

اگر native coin به کیف پول می‌فرستید و چند ثانیه بعد به آدرس ناشناسی می‌رود، کس دیگری private key شما را دارد. در این حالت revoke فایده ندارد و gas ارسالی هم برداشته می‌شود. دیگر به آن آدرس چیزی نفرستید؛ با seed phrase تازه کیف پول جدید بسازید، هرچه قابل انتقال است را سریع منتقل کنید و آدرس قدیمی را کاملاً کنار بگذارید.

دارایی رفته است: شواهد را نگه دارید و فقط از مسیر رسمی پیش بروید

انتقال on-chain برگشت‌پذیر نیست. Transaction hash (TxID)، آدرس خودتان، آدرس گیرنده، دامنه سایت فیشینگ و اسکرین‌شات popup را مرتب نگه دارید. اگر دارایی به آدرس واریز یک صرافی رفته، با این مدارک به پشتیبانی رسمی همان صرافی مراجعه کنید؛ بخشی که هنوز برداشت نشده ممکن است مسدود شود. دامنه فیشینگ را به پشتیبانی رسمی کیف پول و کانال رسمی پروژه‌ای که از آن تقلید شده گزارش دهید، و اگر در کشور شما مرجع رسیدگی به جرایم اینترنتی وجود دارد، با همین مدارک شکایت ثبت کنید. هر کسی که در ازای پول وعده «بازیابی» یا «رفع مسدودی» می‌دهد، کلاهبرداری دوم است؛ نهاد معتبر پیش از رسیدگی از شما پول نمی‌گیرد.

سه سناریوی کوتاه

Login message

Statement خوانا، domain هماهنگ، nonce و issued time و بدون asset field. ریسک محدودتر است اما privacy cost اتصال address به profile باقی می‌ماند. Activity wallet از holding wallet مناسب‌تر است.

Testnet swap approval

Chain واقعاً testnet، token آزمایشی و spender همان router رسمی است. Approval می‌تواند طبیعی باشد، ولی امکان custom amount در برابر unlimited را ببینید و بعد از task review کنید.

Mainnet permit با عنوان verification

Page از reward حرف می‌زند اما typed data شامل mainnet chainId، stablecoin و unknown spender است. نبود gas نشانه امنیت نیست. Reject، report و history امضاهای قبلی را بررسی کنید.

پرسش‌های رایج

آیا صرفاً connect کردن کیف پول می‌تواند دارایی را منتقل کند؟

Connect معمولاً فقط آدرس عمومی انتخاب‌شده و شبکه را به وب‌سایت نشان می‌دهد و خودش transfer نیست. با این حال صفحه می‌تواند بعداً message signature، approval یا transaction جداگانه بخواهد؛ هر popup را دوباره بخوانید.

آیا personal_sign همیشه امن است؟

خیر. Login message روشن معمولاً فوراً دارایی را جابه‌جا نمی‌کند، اما signature می‌تواند برای ورود یا authorization خارج از chain استفاده شود. اگر domain، هدف، nonce یا expiry نامشخص است، رد کنید.

خطر مشترک approve و permit چیست؟

هر دو می‌توانند به spender اجازه استفاده از token بدهند. Approve یک transaction روی chain است؛ permit را ممکن است فرد دیگری بعداً submit کند. Token، spender، مقدار، chain و deadline را بررسی کنید.

اگر wallet simulation وضعیت امن نشان دهد می‌توان confirm کرد؟

Simulation کمک می‌کند اما تضمین نیست. Upgradeable contract، ارسال با تأخیر، decoding ناقص یا call بعدی ممکن است دیده نشود. Domain، contract و permission را مستقل بررسی کنید.

آیا بعد از approve می‌شود آن را پس گرفت؟

می‌شود revoke کرد، اما فقط برای انتقال‌های بعدی اثر دارد. نشانی revoke.cash یا Token Approval Checker در block explorer را خودتان تایپ کنید، chainی را که approval در آن داده‌اید انتخاب کنید، روی spender مربوط Revoke بزنید و یک تراکنش با کمی gas را در کیف پول تأیید کنید. دارایی‌ای که پیش از revoke رفته برنمی‌گردد.

فقط پیام ورود personal_sign را امضا کرده‌ام؛ کیف پولم امن است؟

معمولاً بله. امضای پیام معمولی را نمی‌توان به‌جای انتقال یا permit approval به کار برد. اگر مطمئن شدید متن فقط ورود بوده، سایت را disconnect کنید و درخواست‌های approval بعدی آن را reject کنید؛ اگر در متن به trading authorization یا API key اشاره شده بود، sessionها و keyهای همان platform را حذف کنید.

منابع فنی اصلی