امنیت و پیاده‌سازی · ۲۵ مرداد ۱۴۰۵

امنیت ورود پیامکی؛ انقضا، ارسال مجدد و سقف تلاش

پاسخ کوتاه: امنیت یک ورود پیامکی را ظاهر فرم تعیین نمی‌کند، چهار عدد تعیین می‌کند: کد چند دقیقه زنده می‌ماند، ارسال مجدد چقدر فاصله دارد، چند بار می‌شود کد را اشتباه زد، و آیا کد پس از یک‌بار مصرف باطل می‌شود. در نبض این چهار مقدار به‌ترتیب ۵ دقیقه، ۳۰ ثانیه، ۵ تلاش و مصرف یک‌باره است و همه‌شان در سرور اعمال می‌شوند، نه در مرورگر.

معماری

چرا کد یکبارمصرف در وردپرس تولید نمی‌شود؟

در نبض وردپرس کد را نه می‌سازد، نه ذخیره می‌کند و نه خودش تأیید می‌کند. افزونه فقط سه مسیر لایسنس‌محور را صدا می‌زند و تأیید در نشست امن سرویس مرکزی OTP انجام می‌شود. نتیجه این است که دسترسی به دیتابیس یا فایل‌های سایت، کد فعال هیچ‌کسی را آشکار نمی‌کند.

۱

ساخت نشست

درخواست ارسال، یک نشست تازه می‌سازد و سرویس مرکزی پیامک را می‌فرستد. سایت مقدار کد را هرگز نمی‌بیند.

۲

ارسال مجدد

ارسال دوباره روی همان نشست قبلی انجام می‌شود، نه یک نشست جدید؛ بنابراین سقف تلاش و انقضا دور زده نمی‌شود.

۳

تأیید

کد در سمت سرویس مرکزی سنجیده می‌شود و پاسخ آن مبنای ورود است؛ نه یک مقایسه رشته‌ای در PHP سایت.

یک نکته مهم: شناسه نشست (challenge_id) امضاشده است و هم‌زمان به سایت، لایسنس و شماره نرمال‌شده گره می‌خورد. یعنی نشستی که برای یک فروشگاه و یک شماره ساخته شده، در فروشگاه دیگر یا برای شماره دیگر قابل استفاده نیست. کد ثابت توسعه یا مسیر تأیید محلی هم وجود ندارد.
چهار کنترل عددی

هر عدد جلوی کدام حمله را می‌گیرد؟

کنترلچه چیزی را می‌بندد
انقضای نشست — ۵ دقیقهاستفاده از پیامک قدیمی که روی گوشی مانده یا بعداً دیده شده
فاصله ارسال مجدد — ۳۰ ثانیهخالی‌کردن اعتبار پیامک فروشگاه و پیامک‌باران شماره دیگران
سقف تلاش تأیید — ۵ بارحدس‌زدن پیاپی کد روی یک نشست زنده
مصرف یک‌باره کداستفاده دوباره از کدی که یک‌بار موفق تأیید شده
محدودسازی جست‌وجوی شمارهفهرست‌کردن اینکه چه شماره‌هایی در فروشگاه حساب دارند

نبود هر کدام از این پنج مورد یک ضعف واقعی است، نه یک ریزه‌کاری. ورود پیامکی‌ای که فقط انقضا دارد ولی سقف تلاش ندارد، در برابر حدس‌زدن خودکار عملاً باز است.

پنل واقعی محصول

مدیر فروشگاه چه چیزی را تنظیم می‌کند؟

در پنل نبض می‌توان فعال‌بودن ورود پیامکی، روش احراز، حالت نمایش، فیلدهای ثبت‌نام و ظاهر فرم را انتخاب کرد. زمان انقضا، فاصله ارسال مجدد و سقف تلاش، تنظیم نمایشی مرورگر نیستند و سرویس مرکزی آن‌ها را سمت سرور اعمال می‌کند.

  • انتخاب OTP، رمز عبور یا نمایش هر دو روش
  • نمایش به‌صورت مودال، شورت‌کد یا صفحه اختصاصی
  • فیلدهای ثبت‌نام و برندینگ فرم
  • کنترل‌های امنیتی ثابت و غیرقابل دورزدن از مرورگر
برای دیدن جزئیات: تصویر، صفحه کامل تنظیمات واقعی افزونه است. روی آن بزنید تا نسخه کامل در تب تازه باز شود.
تصویر واقعی صفحه تنظیمات ورود با موبایل و OTP در افزونه نبض

تنظیمات ورود پیامکی نبض

وضعیت سرویس، روش ورود، فرم ثبت‌نام و ظاهر ورود در یک صفحه مدیریت می‌شوند؛ کنترل‌های عددی امنیت در سرویس مرکزی اجرا می‌شوند.

enumeration

محدودسازی جست‌وجوی شماره چرا لازم است؟

فرم‌های ورود پیامکی معمولاً پیش از ارسال کد بررسی می‌کنند که آیا این شماره حساب دارد یا نه، تا متن و مسیر درست را نشان دهند. همین بررسی بی‌محدودیت، به یک ابزار فهرست‌برداری تبدیل می‌شود: کسی می‌تواند هزاران شماره را امتحان کند و بفهمد کدام‌ها مشتری شما هستند.

  • در نبض این بررسی به ۱۵ بار در هر ۵ دقیقه به‌ازای هر IP محدود است.
  • پس از عبور از سقف، پاسخ با وضعیت ۴۲۹ و پیام عمومی فارسی برگردانده می‌شود.
  • پیام خطا جزئیاتی که به فهرست‌برداری کمک کند فاش نمی‌کند.
  • اندپوینت‌های AJAX فرم OTP با nonce ضد-CSRF محافظت می‌شوند؛ callbackهای OAuth به‌جای nonce وردپرس از state استفاده می‌کنند.
مرز واقع‌بینانه: محدودسازی بر پایه IP جلوی فهرست‌برداری ساده را می‌گیرد، اما مهاجمی که از صدها IP استفاده کند با آن به‌تنهایی متوقف نمی‌شود. nonce هم ابزار ضدبات نیست؛ این کنترل‌ها چند لایه‌اند، نه تضمین کامل.
آنچه تأیید باید بسنجد

یک verify درست، شش چیز را با هم چک می‌کند

بررسی‌کردن فقط «کد درست است؟» کافی نیست. تأیید امن باید هم‌زمان این موارد را کنار هم بسنجد و اگر هرکدام نخواند، درخواست را رد کند.

تطابق نشست و شماره

کد باید متعلق به همان نشستی باشد که برای همان شماره نرمال‌شده ساخته شده است.

تعلق به همان سایت

نشستی که برای فروشگاه دیگری صادر شده، حتی با کد درست، باید رد شود.

انقضا

نشست منقضی حتی با کد درست پذیرفته نمی‌شود؛ مقایسه زمان در سرور انجام می‌شود.

شمار تلاش

اگر سقف تلاش پر شده باشد، نشست باطل است و تلاش ششم اصلاً سنجیده نمی‌شود.

وضعیت مصرف

نشستی که یک‌بار موفق تأیید شده، علامت مصرف‌شده می‌گیرد و دوباره قابل استفاده نیست.

یکنواختی پیام خطا

پیام‌ها عمومی و فارسی‌اند تا تفاوت پاسخ‌ها، اطلاعات اضافه‌ای به مهاجم ندهد.

مرز قابلیت

ورود پیامکی چه چیزی را اثبات نمی‌کند

OTP اثبات می‌کند کاربر در همان لحظه به پیامک آن شماره دسترسی دارد. همین و بس. این با «هویت این شخص تأیید شد» یکی نیست و نباید در ارتباط با مشتری یا در تصمیم‌های داخلی این‌طور معرفی شود.

  • جای احراز هویت رسمی و بررسی هویت حقوقی را نمی‌گیرد.
  • جای کنترل ضدتقلب پرداخت و بررسی ریسک سفارش را نمی‌گیرد.
  • در برابر شماره‌ای که خود مشتری در اختیار دیگری گذاشته، محافظتی ندارد.
  • اگر سیم‌کارت منتقل یا بازیابی شود، دسترسی هم منتقل می‌شود.
پیشنهاد عملی: برای عملیات پرریسک مثل تغییر شماره حساب یا مبالغ بالا، OTP را تنها لایه قرار ندهید و یک تأیید انسانی یا کنترل دوم اضافه کنید.
چک‌لیست آزمون

پیش از فعال‌سازی روی فروشگاه اصلی

۱

کد منقضی

یک کد بگیرید، بیش از پنج دقیقه صبر کنید و همان را وارد کنید. باید رد شود، نه اینکه وارد شوید.

۲

ارسال مجدد سریع

بلافاصله بعد از ارسال، دوباره درخواست بدهید. باید تا پایان ۳۰ ثانیه منتظر بمانید.

۳

کد غلط پیاپی

پنج بار کد اشتباه بزنید. تلاش ششم باید روی نشست باطل بخورد، نه اینکه بی‌نهایت ادامه پیدا کند.

۴

کد تکراری

پس از ورود موفق، همان کد را دوباره امتحان کنید. باید به‌عنوان مصرف‌شده رد شود.

۵

دور زدن مرورگر

محدودیت‌ها را با ابزار خط فرمان بیازمایید، نه فقط با کلیک روی دکمه. کنترلی که فقط در جاوااسکریپت باشد، کنترل نیست.

۶

اعتبار پیامک

حواستان باشد هر ارسال مجدد یک پیامک واقعی و هزینه واقعی است؛ آزمون را با شماره‌های خودتان انجام دهید.

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

پرسش درباره امنیت ورود پیامکی

کد یکبارمصرف چند دقیقه اعتبار دارد؟

در نبض عمر نشست OTP پنج دقیقه است. پس از این مدت کد رد می‌شود و مشتری باید درخواست تازه بدهد. عمر کوتاه، فرصت سوءاستفاده از پیامک لو رفته را کم می‌کند و در عمل برای خواندن پیامک و تایپ کد کافی است.

چرا دکمه ارسال مجدد بلافاصله فعال نمی‌شود؟

فاصله ارسال مجدد ۳۰ ثانیه است. بدون این فاصله، هر بازدیدکننده می‌تواند با فشردن پیاپی دکمه، اعتبار پیامک فروشگاه را خرج کند و شماره یک نفر دیگر را با پیامک پیاپی آزار دهد. ارسال مجدد هم همان نشست قبلی را تکرار می‌کند، نه یک نشست تازه.

اگر کسی کدها را پشت سر هم حدس بزند چه می‌شود؟

سقف تلاش تأیید در هر نشست پنج بار است. پس از آن نشست بی‌اعتبار می‌شود و حدس‌زدن ادامه پیدا نمی‌کند. چون کد پس از تأیید موفق هم مصرف‌شده علامت می‌خورد، همان کد بار دوم پذیرفته نمی‌شود.

آیا کد تأیید در دیتابیس وردپرس ذخیره می‌شود؟

خیر. وردپرس کد یکبارمصرف را نه تولید می‌کند و نه ذخیره. افزونه فقط یک challenge_id امضاشده را نگه می‌دارد و تأیید در نشست امن سرویس مرکزی OTP انجام می‌شود. بنابراین دسترسی به دیتابیس سایت، کد فعال کسی را لو نمی‌دهد.

آیا ورود پیامکی جای احراز هویت رسمی را می‌گیرد؟

خیر. OTP فقط ثابت می‌کند کاربر در همان لحظه به پیامک آن شماره دسترسی دارد. جای احراز هویت رسمی، کنترل ضدتقلب پرداخت یا بررسی هویت حقوقی را نمی‌گیرد و نباید به‌عنوان تنها لایه برای عملیات پرریسک استفاده شود.

مطالعه بعدی

راهنماهای مرتبط

ورود پیامکی را با کنترل‌های واقعی راه بیندازید

نشست پنج‌دقیقه‌ای، ارسال مجدد کنترل‌شده و سقف تلاش، همگی سمت سرور اعمال می‌شوند.

مشاهده ورود OTP نبض