پرش به محتوای اصلی
آسیب‌پذیری‌های سایت

امنیت بازیابی رمز عبور؛ چگونه Reset Password سایت را امن طراحی کنیم؟

امنیت بازیابی رمز عبور به طراحی فرایندی اشاره دارد که فقط مالک واقعی حساب بتواند از طریق آن Password جدید تعیین کند. Token قابل حدس، User Enumeration، لینک بازیابی ناامن و باقی ماندن Sessionهای قبلی می‌توانند Reset Password را به مسیر Account Takeover تبدیل کنند. استفاده از Token تصادفی، یک‌بارمصرف و محدود به زمان، Rate Limiting، HTTPS، مدیریت Session و Notification امنیتی از مهم‌ترین اصول امنیت بازیابی رمز عبور هستند.

تیم امنیت رخنه‌کاو ۳۹ دقیقه مطالعه انتشار:

پاسخ کوتاه: امنیت بازیابی رمز عبور یعنی فرایند Reset Password به شکلی طراحی شود که فقط مالک واقعی حساب بتواند رمز جدید تعیین کند. استفاده از Token تصادفی، یک‌بارمصرف و محدود به زمان، پاسخ یکسان برای حساب موجود و ناموجود، Rate Limiting، ارسال لینک فقط از طریق HTTPS، جلوگیری از Host Header Injection، مدیریت امن Session و اطلاع‌رسانی پس از تغییر رمز از مهم‌ترین اصول این فرایند هستند.

گزینه «رمز عبورم را فراموش کرده‌ام» در ظاهر یکی از ساده‌ترین بخش‌های یک وب‌سایت است. کاربر Email خود را وارد می‌کند، یک لینک دریافت می‌کند و Password جدیدی تعیین می‌کند. اما از دید امنیتی، همین چند مرحله می‌توانند یکی از حساس‌ترین مسیرهای Authentication باشند.

دلیل آن روشن است: اگر کاربر Password خود را فراموش کرده باشد، سیستم دیگر نمی‌تواند برای اثبات هویت او به همان Password اعتماد کند. بنابراین باید یک مسیر جایگزین برای اثبات مالکیت Account ایجاد شود.

این مسیر جایگزین در عمل قدرت زیادی دارد.

هر کسی که بتواند Recovery Flow را با موفقیت طی کند، می‌تواند Password حساب را تغییر دهد و در بسیاری از سیستم‌ها کنترل کامل Account را به دست بگیرد.

به همین دلیل می‌توان گفت:

امنیت Reset Password باید حداقل به اندازه Login اصلی جدی گرفته شود.

اگر سایتی برای ورود Administrator از Password قوی، MFA، Rate Limiting و Bot Protection استفاده کند اما بازیابی رمز آن تنها به یک لینک ضعیف یا سؤال امنیتی قابل حدس وابسته باشد، مهاجم احتمالاً Login اصلی را هدف نمی‌گیرد. او مسیر آسان‌تر یعنی Account Recovery را انتخاب می‌کند.

OWASP نیز قابلیت Forgot Password را یکی از نقاط رایج ایجاد آسیب‌پذیری‌هایی مانند User Enumeration معرفی می‌کند و توصیه می‌کند Tokenهای بازیابی به‌صورت تصادفی امن تولید شوند، طول کافی داشته باشند، امن ذخیره شوند، یک‌بارمصرف باشند و پس از مدت مناسب منقضی شوند.

امنیت بازیابی رمز عبور فقط درباره Token نیست. طراحی صحیح باید کل چرخه را پوشش دهد:

درخواست Reset، شناسایی Account، جلوگیری از Enumeration، تولید Token، ذخیره Token، ارسال Email یا پیام، باز شدن لینک، اعتبارسنجی Token، انتخاب Password جدید، ذخیره امن Password، مدیریت Sessionهای قبلی، ارسال Notification و ثبت رویداد امنیتی.

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

چرا Reset Password یک بخش امنیتی بسیار حساس است؟

در Login معمولی معمولاً User باید یک Authenticator معتبر ارائه کند.

برای مثال:

Email + Password

یا در سیستم قوی‌تر:

Password + MFA

اما در Forgot Password کاربر اعلام می‌کند Authenticator اصلی خود یعنی Password را در اختیار ندارد.

بنابراین Application مجبور است یک روش دیگر برای اثبات هویت ایجاد کند.

معمولاً این روش مالکیت Email است:

User
↓
Forgot Password
↓
Email
↓
Reset Link
↓
New Password

در ظاهر این فرایند منطقی است.

اما از دید امنیتی Reset Link اکنون برای مدت کوتاهی تقریباً قدرت Password را دارد.

کسی که Reset Token معتبر را در اختیار داشته باشد، ممکن است بتواند Password جدیدی برای Account تعیین کند.

بنابراین Reset Token را باید یک Secret حساس در نظر گرفت، نه یک شناسه ساده.

اگر Token قابل حدس باشد، Leak شود، چندبار قابل استفاده باشد یا هرگز Expire نشود، مهاجم می‌تواند از Recovery Flow برای Account Takeover استفاده کند.

Reset Password در واقع یک Authentication جایگزین است

یکی از مهم‌ترین اشتباهات معماری این است که تیم توسعه Forgot Password را تنها یک Feature جانبی رابط کاربری تلقی کند.

از دید امنیتی بهتر است چنین مدل کنیم:

Normal Authentication:
Password / Passkey / MFA
        ↓
Identity verified

Recovery Authentication:
Recovery Channel / Reset Token
        ↓
Identity recovered

در هر دو مسیر نتیجه یکسان است:

سیستم به User اجازه دسترسی یا تعیین Authenticator جدید می‌دهد.

به همین دلیل اگر Recovery Flow بسیار ضعیف‌تر از Authentication اصلی باشد، کل Authentication System عملاً به اندازه ضعیف‌ترین Recovery Mechanism امنیت دارد.

NIST SP 800-63B-4 نیز Account Recovery را بخشی مستقل از چرخه مدیریت Authenticator می‌داند و برای بازیابی حساب روش‌هایی مانند Recovery Code، Recovery Contact و تکرار Identity Proofing را تعریف می‌کند. NIST همچنین تأکید می‌کند رویداد Account Recovery باید با Notification همراه باشد تا سوءاستفاده احتمالی قابل تشخیص باشد. چرخه استاندارد یک Reset Password امن

چرخه استاندارد یک Reset Password امن

یک معماری معمول و نسبتاً امن می‌تواند چنین باشد:

User
↓
Forgot Password
↓
Email / Username
↓
Generic Response
↓
Rate Limit
↓
Generate Secure Random Token
↓
Store Token Securely + Expiration
↓
Send HTTPS Reset URL
↓
User Opens Link
↓
Validate Token
↓
Create Restricted Reset Context
↓
Choose New Password
↓
Validate Password
↓
Store Secure Password Hash
↓
Invalidate Token
↓
Revoke / Review Existing Sessions
↓
Security Notification

نکته مهم این است که هیچ‌کدام از این مراحل به تنهایی کافی نیستند.

Token بسیار قوی اگر در Log ذخیره شود، باز هم خطرناک است.

Rate Limiting اگر Token دائمی باشد، مشکل را حل نمی‌کند.

HTTPS اگر Reset URL براساس Host Header کنترل‌شده توسط مهاجم ساخته شود، باز هم کافی نیست.

امنیت واقعی از ترکیب کنترل‌ها حاصل می‌شود.

اولین مرحله؛ درخواست بازیابی رمز عبور

معمولاً User وارد صفحه‌ای مانند زیر می‌شود:

/forgot-password

و Email یا Username خود را وارد می‌کند.

برنامه باید این Input را مانند هر داده غیرقابل‌اعتماد دیگری Validate کند.

اما مسئله مهم‌تر پاسخ Application است.

فرض کنید User این Email را وارد کند:

[email protected]

اگر حساب وجود داشته باشد، سایت بگوید:

لینک بازیابی برای شما ارسال شد.

و اگر وجود نداشته باشد:

هیچ حسابی با این ایمیل وجود ندارد.

در این حالت Forgot Password تبدیل به ابزار تشخیص کاربران سایت شده است.

به این مشکل User Enumeration گفته می‌شود. User Enumeration در Reset Password چیست؟

User Enumeration در Reset Password چیست؟

User Enumeration یعنی مهاجم بتواند از تفاوت رفتار Application تشخیص دهد یک Username، Email یا Account در سیستم وجود دارد یا خیر.

این اطلاعات ممکن است در نگاه اول کم‌اهمیت به نظر برسند.

اما فهرست Userهای معتبر می‌تواند در حملاتی مانند:

Credential Stuffing،

Password Spraying،

Phishing هدفمند،

Brute Force،

Social Engineering

و حملات Account Takeover استفاده شود.

OWASP توصیه می‌کند در Login، Password Recovery و Reset Password، Application برای Account موجود و ناموجود پاسخ عمومی یکسان ارائه کند.

یک پاسخ مناسب می‌تواند چنین باشد:

اگر حسابی با این مشخصات وجود داشته باشد،
راهنمای بازیابی رمز عبور برای آن ارسال خواهد شد.

این Message چیزی درباره وجود Account افشا نمی‌کند.

فقط متن Response کافی نیست

فرض کنید ظاهر Message یکسان است اما زمان پاسخ متفاوت باشد.

Account موجود:

Email lookup
Token generation
Email queue
Response
= 450 ms

Account ناموجود:

Database lookup
Response
= 20 ms

Attacker ممکن است با اندازه‌گیری Timing تفاوت میان Account واقعی و ناموجود را تشخیص دهد.

OWASP مشخصاً توصیه می‌کند پاسخ Forgot Password برای حساب موجود و ناموجود تا حد ممکن زمان پردازش مشابهی داشته باشد و از Early Returnهایی که Timing تفاوت زیادی ایجاد می‌کنند اجتناب شود.

یکی از راهکارهای مناسب، Queue کردن عملیات Email به‌صورت Asynchronous است.

Flow می‌تواند چنین باشد:

Request
↓
Basic Validation
↓
Generic Workflow
↓
Queue Recovery Job if Account Exists
↓
Generic Response

Client لازم نیست منتظر ارسال واقعی Email بماند.

HTTP Status Code نیز می‌تواند Account را افشا کند

فرض کنید Message یکسان باشد، اما:

Account exists → HTTP 200
Account missing → HTTP 404

این نیز Enumeration ایجاد می‌کند.

همین مسئله درباره:

Response Size،

JSON Structure،

Headerها،

Redirectها

و Error Codeهای API وجود دارد.

API نباید چیزی شبیه این برگرداند:

{
    "account_exists": false
}

حتی اگر Frontend آن را نمایش ندهد.

Security باید در Backend enforce شود.

Rate Limiting در Forgot Password

اگر Endpoint بازیابی هیچ Rate Limit نداشته باشد، مهاجم می‌تواند هزاران درخواست Reset برای یک User ارسال کند.

نتیجه ممکن است:

Email Flooding،

SMS Flooding،

هزینه مالی،

مزاحمت برای User،

فشار روی Email Provider

و ایجاد Noise امنیتی

باشد.

OWASP توصیه می‌کند Forgot Password Request در برابر ارسال خودکار بیش از حد محافظت شود؛ برای مثال Rate Limit براساس Account و در صورت نیاز CAPTCHA یا کنترل‌های مشابه اعمال شود.

اما Rate Limit نباید فقط IP-Based باشد.

مهاجم می‌تواند از چند IP استفاده کند.

بهتر است Signalهایی مانند:

Requests per IP
Requests per Account
Requests per Device
Requests per subnet
Requests per time window

ترکیب شوند.

در عین حال پاسخ Rate Limit نیز نباید وجود Account را افشا کند.

آیا با درخواست Reset باید حساب Lock شود؟

خیر.

یکی از طراحی‌های بد این است که به محض درخواست Forgot Password، Account Lock شود تا فرایند تکمیل شود.

مهاجم می‌تواند Email قربانی را وارد کند و بدون داشتن هیچ Secret دیگری باعث Lock شدن حساب شود.

این رفتار می‌تواند به Denial of Service تبدیل شود.

OWASP مشخصاً توصیه می‌کند صرف درخواست Forgotten Password باعث تغییر وضعیت Account یا Lock شدن آن نشود؛ تغییرات باید پس از ارائه Token معتبر انجام شوند.

Reset Token چیست؟

پس از شناسایی Account، Server معمولاً یک Secret تصادفی تولید می‌کند.

مثلاً به‌صورت مفهومی:

3f8c...random...9ab1

سپس لینک زیر برای User ارسال می‌شود:

https://example.com/reset-password?token=...

Token باید به یک User و یک Recovery Request مشخص مرتبط باشد.

هدف این است که فقط کسی که به Recovery Channel دسترسی دارد بتواند Token را دریافت کند. ویژگی‌های یک Reset Token امن

ویژگی‌های یک Reset Token امن

Reset Token باید غیرقابل پیش‌بینی باشد.

نباید براساس مواردی مانند:

User ID،

Timestamp ساده،

Email،

Username،

شماره حساب

یا ترکیب قابل حدس این موارد

تولید شود.

الگوی ناامن:

token = userId + currentTimestamp

Attacker ممکن است بتواند مقادیر را حدس بزند یا Search Space را بسیار محدود کند.

Token باید با Cryptographically Secure Random Number Generator یا CSPRNG ساخته شود.

OWASP توصیه می‌کند Token یا Code بازیابی به‌صورت Cryptographically Secure تولید شود، طول کافی برای مقابله با Brute Force داشته باشد، به User مشخص متصل باشد، امن ذخیره شود، محدودیت زمانی داشته باشد و پس از استفاده Invalid شود.

نمونه مفهومی تولید Token امن

در Node.js می‌توان از API رمزنگاری‌شده سیستم استفاده کرد:

import crypto from "node:crypto";

const token = crypto.randomBytes(32).toString("hex");

در این مثال Token از منبع Random رمزنگاری‌شده تولید می‌شود.

هدف این نمونه نشان دادن اصل طراحی است:

Secure Random
→
Unpredictable Token

نه استفاده از Random معمولی مانند:

Math.random()

برای Secret امنیتی.

آیا Reset Token را Plaintext در Database ذخیره کنیم؟

ترجیحاً خیر.

اگر Database Leak شود و Reset Tokenهای فعال به‌صورت Plaintext داخل آن باشند، Attacker ممکن است بدون دانستن Password از آن‌ها استفاده کند.

الگوی امن‌تر شبیه Password Reset Token Hashing است:

Generate Token
↓
Send Original Token to User
↓
Hash Token
↓
Store Hash in Database

هنگام استفاده:

Received Token
↓
Hash
↓
Compare with stored hash

Database در این حالت فقط Verifier را نگه می‌دارد.

WordPress Core نیز در get_password_reset_key() یک Reset Key تولید می‌کند و مقدار ذخیره‌شده در user_activation_key را به شکل timestamp به‌همراه Hash نگه می‌دارد، نه اینکه Key خام را مستقیماً در آن فیلد ذخیره کند.

Reset Token باید Expire شود

Token بازیابی نباید برای همیشه معتبر باشد.

هرچه Lifetime طولانی‌تر باشد، Window زمانی سوءاستفاده بیشتر می‌شود.

اما Lifetime بسیار کوتاه نیز User Experience را خراب می‌کند.

مقدار دقیق باید براساس Risk سیستم انتخاب شود.

برای سرویس حساس ممکن است مدت کوتاه‌تری مناسب باشد.

برای سرویس کم‌ریسک می‌توان Window بزرگ‌تری داشت.

مهم این است که Expiration صریح وجود داشته باشد.

Server باید خودش Expiration را enforce کند.

مخفی کردن لینک از UI هیچ ارزشی ندارد.

Reset Token باید Single Use باشد

پس از Reset موفق Password، Token باید فوراً باطل شود.

Flow صحیح:

Token valid
↓
Password changed
↓
Token invalidated

نه:

Token valid
↓
Password changed
↓
Token remains valid

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

OWASP Single Use بودن Reset Identifierها را یکی از الزامات مهم Recovery Flow می‌داند.

درخواست Reset جدید با Token قبلی چه کند؟

یک Policy مناسب این است که ایجاد درخواست بازیابی جدید، Token قبلی همان Recovery Flow را باطل کند.

برای مثال:

Request 1 → Token A
Request 2 → Token B

پس از Request 2:

Token A = Invalid
Token B = Valid

این مدل State Management را ساده‌تر می‌کند و تعداد Secretهای فعال را کاهش می‌دهد.

در برخی معماری‌ها امکان چند Token فعال وجود دارد، اما باید Threat Model مشخصی برای آن وجود داشته باشد.

برای بیشتر وب‌سایت‌ها، فقط آخرین Token فعال طراحی ساده‌تر و قابل دفاع‌تری است. ساخت لینک Reset؛ خطر Host Header Injection

ساخت لینک Reset؛ خطر Host Header Injection

Application معمولاً باید URL بازیابی ایجاد کند:

https://example.com/reset-password?token=...

یکی از اشتباهات خطرناک این است که Domain لینک از HTTP Host Header درخواست کاربر ساخته شود.

مثلاً:

Host: attacker-controlled.example

و Application به‌صورت خودکار لینک را چنین بسازد:

https://attacker-controlled.example/reset?token=SECRET

اگر این لینک برای User Email شود و User روی آن کلیک کند، Token ممکن است برای Domain مهاجم ارسال شود.

OWASP صراحتاً توصیه می‌کند برای ساخت Reset URL به Host Header اعتماد نشود؛ Domain باید Hard-Coded یا براساس Allowlist معتبر تعیین شود.

بهتر است Configuration داخلی داشته باشیم:

PUBLIC_APP_ORIGIN=https://example.com

و لینک تنها از این مقدار ساخته شود.

Recovery Token یک Secret حساس است.

ارسال آن روی HTTP می‌تواند امکان شنود یا دستکاری Traffic را فراهم کند.

تمام Reset URLها باید:

https://

باشند.

در سایت‌هایی که HTTP هنوز فعال است، Redirect به HTTPS باید قبل از پردازش Token انجام شود.

بهتر است HSTS نیز براساس معماری سایت فعال شود تا Browser مجبور به استفاده از HTTPS باشد.

Token در URL و خطر Leak شدن

URL Token ساده‌ترین و رایج‌ترین روش Forgot Password است.

اما Query String ممکن است در محیط‌های مختلف دیده شود:

Browser History،

Proxy Log،

Analytics،

APM،

Error Monitoring

و Referrer.

به همین دلیل Reset Page باید حداقل داده‌های Third-Party غیرضروری را بارگذاری کند.

OWASP توصیه می‌کند Reset Page از Referrer Policy مناسب مانند:

Referrer-Policy: no-referrer

استفاده کند تا Token از طریق Referer Header به سایت‌های دیگر Leak نشود.

این نکته به‌خصوص مهم است اگر Reset Page شامل:

Analytics،

Advertisement،

External Image،

Font Provider

یا Third-Party Script

باشد.

بهتر است صفحه Reset تا حد ممکن Minimal و First-Party باشد.

Token را در Access Log ذخیره نکنید

اگر Web Server کل Query String را Log کند:

GET /reset?token=SECRET

Reset Token وارد Log می‌شود.

افرادی که به Logging Platform دسترسی دارند ممکن است Secret را ببینند.

همچنین Log ممکن است برای مدت طولانی ذخیره شود.

برای Endpointهای حساس باید:

Query Parameter Redaction،

Sensitive Parameter Masking

یا Logging Policy مخصوص

داشته باشید.

نباید به علت Convenience عملیاتی Secretهای Authentication را در Log ذخیره کرد.

Email بازیابی باید چگونه طراحی شود؟

Recovery Email بهتر است ساده و واضح باشد.

User باید بداند:

درخواستی برای Reset Password ثبت شده است.

اگر درخواست متعلق به اوست چه کاری انجام دهد.

اگر درخواست متعلق به او نیست چه کاری انجام دهد.

زمان تقریبی اعتبار لینک در صورت مناسب بودن.

Domain سایت باید واضح باشد.

اما Email نباید Password جدید را ارسال کند.

OWASP توصیه می‌کند پس از Reset نیز User از طریق Email مطلع شود، اما Password هیچ‌گاه در Notification ارسال نشود.

آیا باید Username را داخل Email نمایش دهیم؟

این مسئله به Threat Model و UX بستگی دارد.

در بسیاری از سرویس‌ها بهتر است فقط اطلاعات لازم نمایش داده شود.

اصل Data Minimization را رعایت کنید.

اگر Email Account مشترک است، نمایش اطلاعات بیش از حد می‌تواند Privacy Risk ایجاد کند.

امنیت حساب Email بخشی از Reset Password است

وقتی Recovery براساس Email انجام می‌شود، امنیت حساب عملاً تا حدی به امنیت Email User وابسته است.

اگر مهاجم Email User را کنترل کند، احتمالاً می‌تواند Reset Link را نیز دریافت کند.

برای حساب‌های حساس بهتر است Recovery تنها به Email محدود نشود.

امکان استفاده از:

Passkey،

Recovery Code،

Authenticator موجود،

Support Verification،

یا چند Factor

باید براساس Risk بررسی شود.

NIST SP 800-63B-4 برای Account Recovery روش‌های مختلفی مانند Saved Recovery Code، Issued Recovery Code، Recovery Contact و Repeated Identity Proofing را به رسمیت می‌شناسد.

امنیت SMS Reset Code

بعضی سرویس‌ها به‌جای لینک Email از Code پیامکی استفاده می‌کنند.

مثلاً:

123456

مزیت:

ورود Code برای User آسان است.

اما فضای Codeهای کوتاه کوچک‌تر از Tokenهای طولانی است.

بنابراین Rate Limiting اهمیت بسیار بیشتری پیدا می‌کند.

برای Code باید:

Expiration کوتاه،

Attempt Limit،

Single Use،

Binding به User،

و Rate Limit

وجود داشته باشد.

اگر 6-digit Code بدون محدودیت Attempt باشد، Search Space تنها یک میلیون مقدار است.

هیچ Reset Code کوتاهی نباید بدون Anti-Brute-Force استفاده شود.

Reset Code باید به Account متصل باشد

نباید یک Code بتواند برای هر Account استفاده شود.

Backend باید Context را بداند:

Code
+
User
+
Recovery Request
+
Expiration

اگر Code متعلق به User A باشد، نباید برای User B معتبر شود.

همچنین Verify Endpoint نباید اجازه دهد Attacker فقط با Codeهای مختلف کل User Space را Scan کند.

Security Question گزینه مناسبی است؟

سؤال‌های امنیتی مانند:

نام مدرسه ابتدایی شما چیست؟
نام اولین حیوان خانگی شما؟
شهر تولد شما؟

مشکلات زیادی دارند.

پاسخ ممکن است:

قابل حدس،

در شبکه اجتماعی موجود،

قابل تحقیق،

یا توسط افراد نزدیک شناخته‌شده

باشد.

OWASP توصیه می‌کند Security Question به‌عنوان تنها روش Reset Password استفاده نشود؛ در صورت استفاده، تنها یک لایه اضافی کنار روش‌های قوی‌تر باشد.

در معماری جدید معمولاً Passkey، Recovery Code یا Recovery Channel امن‌تر انتخاب‌های بهتری هستند.

Recovery Code چیست؟

Recovery Code یک Secret است که User از قبل دریافت می‌کند و برای شرایط از دست رفتن Authenticator نگهداری می‌کند.

NIST SP 800-63B-4 برای Saved Recovery Code حداقل 64 بیت Randomness از مولد تصادفی تأییدشده را مشخص می‌کند.

Recovery Code باید:

در مکان امن ذخیره شود.

پس از استفاده Invalid شود.

قابل Rotation باشد.

در Log نمایش داده نشود.

مانند Password Hash یا Secret حساس محافظت شود.

Password Manager محل مناسبی برای ذخیره Recovery Code می‌تواند باشد.

MFA و Reset Password

فرض کنید Account دارای MFA است:

Password + Authenticator App

User Password را فراموش می‌کند اما MFA Device هنوز در اختیار اوست.

این وضعیت با از دست رفتن کامل Account متفاوت است.

می‌توان از Authenticator موجود برای افزایش اطمینان Reset استفاده کرد.

از طرف دیگر اگر User هم Password و هم MFA را از دست داده باشد، وارد Account Recovery واقعی می‌شویم که باید Stronger Recovery Process داشته باشد.

بزرگ‌ترین اشتباه این است که MFA قوی با یک Forgot Password ساده قابل دور زدن باشد.

مثلاً:

Normal login:
Password + Security Key

Recovery:
Email link only → Full account access

در این صورت Recovery Channel عملاً Weakest Link سیستم است.

Reset Password نباید MFA را بی‌دلیل حذف کند

تغییر Password و Reset MFA دو عملیات متفاوت هستند.

اگر User Password را Reset می‌کند، نباید بدون دلیل تمام MFA Config او نیز حذف شود.

Attacker اگر Email User را کنترل کرده باشد ممکن است Password را Reset کند؛ اگر MFA همچنان فعال باشد، یک Defense اضافی باقی می‌ماند.

بنابراین:

Reset Password ≠ Reset MFA

MFA Recovery باید Flow امنیتی جداگانه داشته باشد.

صفحه تعیین Password جدید

پس از Verify شدن Token، User وارد صفحه تعیین Password می‌شود.

بهتر است Application از Token یک Context محدود ایجاد کند.

این Context فقط باید اجازه عملیات:

Set New Password

را بدهد.

نباید Token بازیابی به یک Full Authenticated Session تبدیل شود که User بتواند با آن Profile، Billing یا داده‌های دیگر را مشاهده کند.

اصل Least Privilege در Recovery Session نیز کاربرد دارد.

آیا Token بعد از باز شدن لینک باید همچنان در URL باقی بماند؟

یک طراحی مناسب می‌تواند Token را پس از Validate اولیه به Restricted Server-Side State تبدیل کند و Browser را به URL تمیز Redirect کند.

برای مثال:

/reset?token=SECRET
↓
Validate
↓
Create restricted recovery session
↓
Redirect
/reset-password

در این حالت Secret دیگر در Address Bar، Copy/Paste یا Refererهای بعدی وجود ندارد.

این طراحی نیازمند Session Security مناسب است.

Password جدید چه شرایطی داشته باشد؟

Password Policy باید با Login اصلی یکسان باشد.

Reset Password نباید مسیر دور زدن Password Policy باشد.

اگر Registration Password حداقل استاندارد مشخصی دارد، Reset نیز باید همان Policy را اجرا کند.

در نسخه نهایی NIST SP 800-63B-4 منتشرشده در ژوئیه ۲۰۲۵، Passwordهایی که تنها Factor ورود هستند باید حداقل 15 Character باشند؛ برای Passwordهایی که در Authentication چندعاملی استفاده می‌شوند، حداقل 8 Character الزام شده است. NIST همچنین توصیه می‌کند Password انتخابی با Blocklist مقادیر رایج یا Compromised مقایسه شود.

برای وب‌سایت عمومی لازم نیست NIST الزام قانونی شما باشد، اما این سند Benchmark مناسبی برای طراحی مدرن Authentication است.

Password جدید را با Password افشاشده مقایسه کنید

Reset Password یکی از بهترین زمان‌ها برای جلوگیری از Credential Stuffing آینده است.

User Password جدید وارد می‌کند.

قبل از ذخیره می‌توان بررسی کرد آیا این Password در مجموعه Passwordهای شناخته‌شده افشاشده قرار دارد یا خیر.

اگر وجود داشت:

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

User نباید مجبور باشد دلیل فنی پیچیده‌ای بفهمد، اما باید بداند Password مناسب نیست.

Password را Plaintext ذخیره نکنید

پس از دریافت Password جدید:

Password
↓
Validation
↓
Password Hashing Algorithm
↓
Stored Hash

Password خام نباید در:

Database،

Log،

Email،

Analytics،

Exception

یا Event Tracking

ذخیره شود.

Hash سریع عمومی به تنهایی برای Password Storage کافی نیست.

باید از Password Hashing Function مناسب مانند Argon2id یا گزینه مناسب Framework استفاده شود.

Password را برای User Email نکنید

الگوی قدیمی:

رمز جدید شما: XXXXXX

طراحی مناسبی نیست.

Email Secret دائمی Authentication نیست.

User باید Password را خودش در صفحه HTTPS تعیین کند.

Notification بعد از Reset نیز نباید Password را شامل شود.

Auto Login بعد از Reset خوب است؟

در بعضی Applicationها پس از Password Reset User به‌صورت خودکار Login می‌شود.

OWASP توصیه می‌کند پس از تعیین Password جدید، User از مسیر Authentication عادی وارد حساب شود و Auto Login انجام نشود، زیرا این کار پیچیدگی Session Management و احتمال Bug را افزایش می‌دهد.

Flow مناسب:

Password successfully reset
↓
Token invalidated
↓
Go to normal login
↓
Authenticate normally

این مرحله به‌خصوص زمانی مهم است که Login اصلی MFA دارد.

User باید پس از Reset Password همچنان MFA را طی کند. بعد از Reset با Sessionهای قبلی چه کنیم؟

بعد از Reset با Sessionهای قبلی چه کنیم؟

این یکی از مهم‌ترین تصمیم‌هاست.

فرض کنید User Password را تغییر داده چون فکر می‌کند Account هک شده است.

اگر Session مهاجم همچنان فعال باقی بماند:

Password changed
but
Attacker session still valid

User تصور می‌کند مشکل حل شده، در حالی که مهاجم همچنان Login است.

OWASP توصیه می‌کند پس از Reset Password امکان Invalid کردن Sessionهای موجود به User داده شود یا Application آن‌ها را به‌صورت خودکار باطل کند.

برای سرویس‌های حساس، Automatic Revocation معمولاً انتخاب قابل دفاع‌تری است.

آیا تمام Sessionها را باطل کنیم؟

Policy به نوع سرویس بستگی دارد.

یک روش:

Invalidate all sessions

User باید دوباره روی تمام Deviceها Login کند.

روش دیگر:

Keep current trusted recovery session
Revoke others

اما این روش نیازمند اطمینان بیشتر از Recovery Context است.

برای Incident یا Reset ناشی از Compromise، Revoke کردن همه Sessionها امن‌تر است.

Refresh Tokenها را فراموش نکنید

در معماری JWT یا OAuth، Logout یا حذف Browser Session ممکن است کافی نباشد.

ممکن است:

Refresh Token،

API Token،

Remember Me Token،

Mobile Session

همچنان معتبر باشد.

Password Reset Policy باید مشخص کند کدام Credentialهای بلندمدت Revoke می‌شوند.

در سرویس‌های حساس بهتر است Password Reset امنیتی باعث Rotation یا Invalid شدن Session Secretهای مرتبط شود.

Remember Me

اگر سایت گزینه «مرا به خاطر بسپار» دارد، Token مربوط به آن نیز یک Session Credential است.

Password Reset در سناریوی Compromise باید آن را هم در Threat Model قرار دهد.

نباید Attacker بتواند از Remember-Me Cookie قدیمی دوباره وارد حساب شود.

Notification پس از Reset

بعد از تغییر موفق Password، User باید Notification دریافت کند.

مثلاً:

رمز عبور حساب شما تغییر کرد.

اگر این تغییر توسط شما انجام نشده است،
فوراً مراحل امنیت حساب را دنبال کنید.

Notification نباید لینک خطرناک یا اطلاعات حساس اضافه داشته باشد.

در سرویس حساس می‌توان اطلاعاتی مانند:

زمان،

Device،

Location تقریبی

را نیز نمایش داد.

NIST در Account Recovery بر ارسال Notification برای کمک به شناسایی Recovery جعلی تأکید می‌کند.

Email قبلی را نیز در تغییرات حساس درگیر کنید

اگر مهاجم ابتدا Email Account را تغییر دهد و سپس Password Reset کند، Notification فقط به Email جدید کافی نیست.

Change Email خود یک Identity-Sensitive Operation است.

OWASP توصیه می‌کند تغییر Email با Re-authentication انجام شود و Email قبلی از تغییر مطلع شود؛ برای سیستم‌های پرریسک حتی تأیید هر دو Address قابل بررسی است.

CSRF در Reset Password

مرحله Request Forgot Password معمولاً تغییر مستقیمی در Account ایجاد نمی‌کند، اما مرحله نهایی Set New Password یک State-Changing Operation است.

اگر Restricted Reset Session استفاده می‌شود، باید CSRF Protection متناسب با معماری نیز بررسی شود.

Token Reset به تنهایی نباید به این معنی باشد که تمام CSRF Considerationها بی‌اهمیت هستند.

به‌خصوص اگر Token به Session تبدیل شده است، فرم تعیین Password باید مانند سایر عملیات حساس محافظت شود.

Clickjacking در Reset Page

صفحه تعیین Password جدید یکی از صفحات حساس است.

مناسب است از Policyهایی مانند:

Content-Security-Policy: frame-ancestors 'none'

یا Policy متناسب با Application استفاده شود تا صفحه بدون نیاز داخل Frame سایت غیرمجاز Embed نشود.

این کنترل جلوی Reset Token Theft را مستقیماً نمی‌گیرد، اما بخشی از Hardening صفحه حساس است.

CSP در Reset Password

صفحه Reset بهتر است JavaScript Third-Party بسیار کمی داشته باشد.

CSP محدود می‌تواند:

Script Loading،

Frame،

External Connection

و Resourceها را کنترل کند.

هرچه صفحه Recovery ساده‌تر باشد، Attack Surface نیز کمتر است.

بهتر است چنین صفحه‌ای به ده‌ها Tag Manager، Advertising Script و Widget خارجی وابسته نباشد.

Cache Control

صفحات حساس بازیابی Password بهتر است Cache نشوند.

بسته به معماری می‌توان Headerهایی مانند:

Cache-Control: no-store

را برای جلوگیری از ذخیره اطلاعات حساس در Cache بررسی کرد.

به‌خصوص اگر Response شامل Recovery State یا اطلاعات Account باشد.

Error Message در مرحله Token Validation

اگر Token:

نامعتبر،

منقضی،

استفاده‌شده

یا Unknown

باشد، Message بهتر است اطلاعات غیرضروری افشا نکند.

مثلاً:

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

بهتر از Errorهای داخلی مانند:

Token for user ID 1287 expired at ...

است.

جزئیات باید در Server Log بمانند.

Reset Token Brute Force

حتی Token Random باید در Endpoint Verify Rate Limit داشته باشد.

هیچ Security Tokenای نباید صرفاً به بزرگی Search Space وابسته باشد.

Defense in Depth:

High-entropy token
+
Expiration
+
Single use
+
Rate limit
+
Monitoring

مقاومت بسیار بهتری نسبت به تنها یکی از این کنترل‌ها دارد.

Logging در Password Reset

رویدادهای مهم باید ثبت شوند، اما Secretها نباید Log شوند.

رویدادهای مفید عبارت‌اند از:

password_reset_requested
password_reset_email_queued
password_reset_token_invalid
password_reset_token_expired
password_reset_completed
sessions_revoked
recovery_rate_limited

برای هر Event می‌توان Context غیرحساس مانند:

User ID داخلی،

Timestamp،

IP،

Device Context،

Request ID

را ثبت کرد.

اما موارد زیر نباید Log شوند:

Password،

Full Reset Token،

OTP،

Session Secret.

Alertهای امنیتی Reset Password

رفتارهای غیرعادی می‌توانند Alert ایجاد کنند.

برای مثال:

تعداد زیاد درخواست Reset برای Userهای مختلف از یک IP.

تعداد زیاد درخواست روی یک Account.

تلاش‌های متعدد Token نامعتبر.

Reset Password بلافاصله پس از Login از Geography غیرمعمول.

Reset چند Account مدیریتی در زمان کوتاه.

Reset و سپس تغییر Email یا MFA.

این Eventها در SIEM یا Monitoring Platform می‌توانند ارزش بالایی داشته باشند.

Admin Accountها باید Recovery Policy قوی‌تری داشته باشند

یک Account Administrator ارزش بسیار بیشتری از Subscriber معمولی دارد.

بنابراین Recovery Policy می‌تواند Role-Based باشد.

مثلاً:

User عادی:

Email Reset + MFA Login

Administrator:

Verified Recovery
+
Existing MFA / Recovery Code
+
Additional Verification

در محیط Enterprise حتی Support یا Identity Proofing دستی نیز ممکن است لازم باشد.

یک Recovery Flow یکسان برای همه Roleها همیشه بهترین انتخاب نیست.

Reset Password در WordPress

WordPress دارای سیستم داخلی بازیابی Password است و توابع مشخصی برای این چرخه دارد.

تابع retrieve_password() درخواست ارسال Email بازیابی را مدیریت می‌کند. تابع get_password_reset_key() Reset Key را ایجاد و مقدار Hashشده به‌همراه Timestamp را در user_activation_key ذخیره می‌کند. در نهایت reset_password() رمز جدید User را تنظیم می‌کند.

برای مدیر سایت WordPress نکته مهم این است که نباید فقط به وجود Feature داخلی اکتفا کند.

محیط واقعی شامل:

Theme،

Plugin،

Custom Login Page،

WooCommerce،

Membership Plugin،

Security Plugin،

Reverse Proxy،

CDN

و Custom Code

است.

ممکن است یکی از این اجزا رفتار Reset را تغییر دهد.

Pluginهای WordPress چه خطرهایی ایجاد می‌کنند؟

افزونه ممکن است:

Reset Endpoint اختصاصی بسازد.

Token ضعیف تولید کند.

Token را در Database Plaintext ذخیره کند.

Expiration را بسیار طولانی کند.

User Enumeration ایجاد کند.

Reset URL را براساس Host Header بسازد.

Password Reset را بدون Invalid کردن Session انجام دهد.

یا Errorهای حساس نمایش دهد.

به همین دلیل Pluginهای Authentication و Membership باید جداگانه Audit شوند.

WooCommerce و Reset Password

در فروشگاه، Account می‌تواند شامل:

اطلاعات سفارش،

Address،

Store Credit،

Reward Point،

اطلاعات شخصی

و سایر داده‌های ارزشمند باشد.

Reset Password ناامن می‌تواند Account Takeover با پیامد مالی ایجاد کند.

فروشگاه باید Reset Endpoint را مانند Login Endpoint بخشی از Authentication Surface بداند.

Rate Limiting، WAF و Monitoring نباید فقط روی /wp-login.php تنظیم شوند اگر WooCommerce یا Plugin دیگری مسیر جداگانه دارد.

Headless WordPress

اگر WordPress فقط Backend است و Frontend جداگانه دارید، ممکن است Reset Flow اختصاصی ساخته شده باشد.

در این معماری باید مشخص شود:

Token کجا تولید می‌شود؟

کدام Domain Reset Link را می‌سازد؟

Token کجا Validate می‌شود؟

Frontend چه داده‌ای دریافت می‌کند؟

آیا API User Enumeration دارد؟

آیا CORS و CSRF Policy درست است؟

آیا Frontend Token را داخل Analytics ثبت می‌کند؟

Headless بودن WordPress مسئولیت امنیت Recovery Flow را کاهش نمی‌دهد. معماری پیشنهادی Reset Password امن

معماری پیشنهادی Reset Password امن

یک معماری چندلایه می‌تواند چنین باشد:

Client
↓
CDN / WAF
↓
Rate Limiting
↓
Forgot Password API
↓
Generic Response
↓
Account Lookup
↓
Secure Token Generator
↓
Hashed Token Storage
↓
Asynchronous Email Service
↓
HTTPS Reset Link
↓
Token Validation
↓
Restricted Recovery Session
↓
Password Policy + Breach Check
↓
Secure Password Hashing
↓
Token Invalidation
↓
Session Revocation
↓
Security Notification
↓
Audit Logging

در این معماری اگر یک Control شکست بخورد، Control دیگری هنوز وجود دارد.

این همان Defense in Depth است.

اشتباهات رایج در طراحی Reset Password

نمایش «این ایمیل ثبت نشده است»

باعث User Enumeration می‌شود.

Token قابل پیش‌بینی

استفاده از User ID، Timestamp یا Random ضعیف مناسب نیست.

Token بدون Expiration

Window حمله را بسیار طولانی می‌کند.

Token قابل استفاده چندباره

پس از تغییر Password باید Invalid شود.

ذخیره Token خام در Database

Database Leak می‌تواند Tokenهای فعال را در اختیار مهاجم قرار دهد.

اعتماد به Host Header

می‌تواند Reset URL را به Domain اشتباه هدایت کند.

استفاده از HTTP

Recovery Token باید روی HTTPS منتقل شود.

ذخیره Token در Log

Logging System نباید تبدیل به Secret Store شود.

استفاده از Security Question به‌عنوان تنها Factor

پاسخ Security Question ممکن است قابل حدس یا قابل تحقیق باشد.

Reset Password همراه با حذف MFA

مهاجم ممکن است با کنترل Email تمام Authentication Layerها را حذف کند.

Auto Login بعد از Reset

Flow Authentication و Session را پیچیده‌تر می‌کند.

نگه داشتن تمام Sessionهای قبلی

ممکن است Session مهاجم همچنان فعال بماند.

Email کردن Password

Password جدید نباید از طریق Email ارسال شود.

نداشتن Rate Limiting

باعث Spam، Token Brute Force یا Abuse می‌شود.

Third-Party Script زیاد روی Reset Page

ریسک Token Leakage و Supply Chain را افزایش می‌دهد.

چک‌لیست امنیت Reset Password

  1. برای Account موجود و ناموجود Response یکسان نمایش دهید.
  2. Timing قابل تشخیص میان دو حالت را کاهش دهید.
  3. Forgot Password Endpoint را Rate Limit کنید.
  4. Rate Limit را فقط بر اساس IP طراحی نکنید.
  5. درخواست Reset نباید Account را Lock کند.
  6. Input Email و Username را Validate کنید.
  7. Token را با CSPRNG تولید کنید.
  8. Token باید Entropy و طول کافی داشته باشد.
  9. Token را به User و Recovery Request متصل کنید.
  10. Token را ترجیحاً Hashشده ذخیره کنید.
  11. Reset Token باید Expiration داشته باشد.
  12. Token باید Single Use باشد.
  13. Token قدیمی را پس از صدور Token جدید Invalid کنید.
  14. لینک Reset فقط HTTPS باشد.
  15. Domain لینک را از Host Header غیرقابل‌اعتماد نسازید.
  16. Domainهای Reset را Allowlist کنید.
  17. Full Token را در Access Log ذخیره نکنید.
  18. Query Stringهای حساس را Redact کنید.
  19. برای Reset Page از Referrer Policy مناسب استفاده کنید.
  20. Third-Party Scriptهای غیرضروری را حذف کنید.
  21. Cache صفحه حساس را محدود کنید.
  22. Token Validation را نیز Rate Limit کنید.
  23. Error Token نامعتبر را عمومی نگه دارید.
  24. پس از Verify Token فقط Recovery Session محدود بسازید.
  25. Recovery Session نباید دسترسی کامل Account بدهد.
  26. فرم تعیین Password را در برابر CSRF متناسب با معماری محافظت کنید.
  27. Password Policy با Registration یکسان باشد.
  28. Passwordهای افشاشده را Block کنید.
  29. Password را با Password Hashing Function امن ذخیره کنید.
  30. Password را در Log ذخیره نکنید.
  31. Password جدید را Email نکنید.
  32. User را مجبور کنید Password را دوبار وارد کند.
  33. پس از Reset، Token را فوراً Invalid کنید.
  34. Auto Login بعد از Reset را حذف کنید.
  35. Login عادی و MFA را پس از Reset حفظ کنید.
  36. Reset Password نباید MFA را خودکار حذف کند.
  37. Sessionهای قدیمی را Revoke یا حداقل به User امکان Revocation بدهید.
  38. Remember-Me Token و Refresh Token را در Threat Model قرار دهید.
  39. بعد از Reset Notification ارسال کنید.
  40. Notification نباید Secret داشته باشد.
  41. تغییر Email را جداگانه با Re-authentication محافظت کنید.
  42. Security Question را تنها Recovery Factor قرار ندهید.
  43. Recovery Code را مانند Secret حساس مدیریت کنید.
  44. برای Adminها Recovery Policy سخت‌گیرانه‌تر داشته باشید.
  45. رویدادهای Reset را Audit Log کنید.
  46. Token و OTP را هیچ‌گاه Log نکنید.
  47. Reset Abuse را مانیتور کنید.
  48. تمام APIهای Legacy بازیابی Password را Inventory کنید.
  49. Mobile و Web Recovery Policy را هماهنگ کنید.
  50. Recovery Flow را در Security Testing و Code Review جداگانه بررسی کنید.

تست امنیت Reset Password چگونه انجام شود؟

تست باید صرفاً روی سامانه‌ای انجام شود که برای ارزیابی آن مجوز دارید.

در تست دفاعی ابتدا رفتار Forgot Password برای Account موجود و ناموجود مقایسه می‌شود.

Response Body، Status Code، Timing، Redirect و Headerها باید بررسی شوند.

سپس Token Lifecycle بررسی می‌شود:

آیا Token Random است؟

آیا Expire می‌شود؟

آیا دوبار قابل استفاده است؟

آیا Token قدیمی بعد از درخواست جدید هنوز معتبر است؟

آیا Token بعد از تغییر Password Invalid می‌شود؟

آیا URL در Log ظاهر می‌شود؟

مرحله بعد Session Management است.

پس از Password Reset باید مشخص شود Sessionهای قبلی چه وضعیتی دارند.

Recovery Flow باید با MFA، Remember-Me و Refresh Token نیز تست شود.

در نهایت Email و URL Generation بررسی می‌شوند تا Host Header یا Untrusted Origin نتواند Domain لینک را تغییر دهد.

Code Review Reset Password

در Code Review دنبال چند نقطه مهم باشید.

Token Generation باید از Secure Random استفاده کند.

Token Storage نباید Plaintext غیرضروری باشد.

Expiration باید Server-Side enforce شود.

Database Query باید User Binding را بررسی کند.

مثلاً Verify صرفاً براساس Token نباشد اگر Context دیگری لازم است.

Session Revocation باید پس از Password Change قابل مشاهده باشد.

همچنین بررسی کنید:

Email Template از Configuration معتبر Domain استفاده می‌کند.

Error Handling Secret را Leak نمی‌کند.

Logging Middleware Query Parameter حساس را ثبت نمی‌کند.

Reset Route تحت Analytics یا Tracking غیرضروری نیست.

Reset Password و Race Condition

یکی از موضوعات کمتر دیده‌شده، Race Condition است.

فرض کنید Token تقریباً همزمان در دو Request استفاده شود.

اگر Backend ابتدا Validity را بخواند و سپس بعداً Token را Invalid کند، ممکن است هر دو Request قبل از Invalid شدن موفق شوند.

برای عملیات حساس بهتر است Token Consumption Atomic باشد.

از نظر مفهومی:

Validate + Mark Used

باید یک عملیات امن و Atomic باشد.

نه:

Check valid
...
do work
...
mark used

در سیستم‌های توزیع‌شده این مسئله اهمیت بیشتری دارد.

Fail Closed

اگر Database یا Token Store در دسترس نیست، Application نباید فرض کند Token معتبر است.

اگر Validation Service Error دهد:

Unknown

باید معادل:

Not authorized

در نظر گرفته شود.

Recovery Operation حساس باید Fail Closed باشد.

Password Reset برای حساب Disabled

اگر Account:

Disabled،

Suspended،

Deleted

یا Security Locked

است، Reset Password نباید لزوماً آن را دوباره فعال کند.

Password Reset و Account Status دو State مستقل هستند.

به‌خصوص در سیستم سازمانی، User اخراج‌شده نباید با Reset Password Account خود را دوباره فعال کند.

Reset Password در Multi-Tenant Application

در SaaS چندمستاجری باید Tenant Context نیز درست مدیریت شود.

User ممکن است یک Email مشابه در Tenantهای مختلف داشته باشد.

Reset Link باید Account صحیح را Target کند.

Tenant ID نباید از Parameter قابل تغییر بدون Validation گرفته شود.

Backend باید Tenant Binding را از Server-Side State یا Token معتبر استخراج کند.

OAuth و SSO Accountها

اگر User از:

Google,

Microsoft,

GitHub,

SAML,

OIDC

وارد می‌شود و Password محلی ندارد، نمایش Forgot Password محلی می‌تواند گیج‌کننده یا خطرناک باشد.

Application باید Authenticator Type Account را بشناسد.

ممکن است User نیاز داشته باشد Password را در Identity Provider خود Reset کند.

نباید به‌صورت ناخواسته یک Password-Based Authentication ضعیف‌تر برای Account SSO ایجاد شود.

Passkey و Account Recovery

با افزایش استفاده از Passkey، Recovery Design اهمیت بیشتری پیدا می‌کند.

Passkey در برابر Phishing مقاومت بالاتری دارد، اما User ممکن است Device خود را از دست بدهد.

اگر Recovery Passkey تنها به Email Link بسیار ساده وابسته باشد، مزیت Authentication قوی کاهش می‌یابد.

برای Account حساس می‌توان:

Multiple Passkeys،

Recovery Code،

Trusted Device،

یا Identity Recovery

را بررسی کرد.

اصل همچنان ثابت است:

Recovery نباید Weakest Link سیستم باشد.

سؤالات متداول درباره امنیت بازیابی رمز عبور

Reset Password امن چیست؟

Reset Password امن فرایندی است که تنها مالک واقعی حساب بتواند از طریق Token یا Recovery Mechanism قابل اعتماد Password جدید تعیین کند. Token باید تصادفی، محدود به زمان، یک‌بارمصرف و امن ذخیره شود و پس از Reset نیز Session و Notification به‌درستی مدیریت شوند.

مهم‌ترین آسیب‌پذیری Forgot Password چیست؟

یک آسیب‌پذیری واحد وجود ندارد. User Enumeration، Token قابل حدس، Token بدون Expiration، Reset Link ناامن، Token Leakage، Host Header Injection و Session Management ضعیف از مهم‌ترین مشکلات هستند.

آیا باید بگوییم Email کاربر در سایت وجود ندارد؟

برای Forgot Password بهتر است پاسخ عمومی ارائه شود تا Attacker نتواند Accountهای ثبت‌شده را شناسایی کند.

Reset Token چقدر باید معتبر باشد؟

عدد ثابت جهانی وجود ندارد. Lifetime باید متناسب با حساسیت سرویس و User Experience انتخاب شود، اما Token نباید بدون Expiration باشد.

آیا Reset Token باید یک‌بارمصرف باشد؟

بله. پس از Reset موفق Password، Token باید فوراً Invalid شود.

آیا Token را می‌توان در Database Plaintext ذخیره کرد؟

بهتر است Token خام تنها برای User ارسال شود و Server Hash یا Verifier آن را ذخیره کند تا Database Leak مستقیماً Token فعال را افشا نکند.

آیا لینک بازیابی باید HTTPS باشد؟

بله. Recovery Token یک Secret حساس است و باید از طریق HTTPS منتقل شود.

Host Header Injection چه ارتباطی با Reset Password دارد؟

اگر Application Domain لینک بازیابی را مستقیماً از Host Header Request بسازد، مهاجم ممکن است باعث شود Reset Link با Domain غیرمجاز برای User ارسال شود و Token افشا شود.

آیا Reset Password باید Account را Lock کند؟

صرف درخواست Reset نباید Account را Lock کند، زیرا مهاجم می‌تواند با دانستن Email قربانی باعث Denial of Service شود.

آیا Security Question برای Reset Password کافی است؟

خیر. Security Question نباید تنها Recovery Mechanism باشد؛ پاسخ‌ها اغلب قابل حدس یا قابل تحقیق هستند.

آیا بعد از Reset باید User خودکار Login شود؟

OWASP توصیه می‌کند User پس از تغییر Password از مسیر Login عادی وارد شود تا Authentication و Session Flow پیچیده نشود.

آیا Sessionهای قبلی باید بسته شوند؟

در بسیاری از سیستم‌ها بله، به‌خصوص اگر Reset به علت احتمال Compromise انجام شده باشد. حداقل باید امکان Sign Out All Sessions فراهم شود.

آیا Reset Password باید MFA را حذف کند؟

خیر. Reset Password و Reset MFA باید Flowهای مستقل باشند. حذف خودکار MFA می‌تواند یک Defense مهم را از بین ببرد.

آیا Token باید داخل URL باشد؟

URL Token روش رایج و قابل قبولی است، مشروط بر اینکه Token امن، محدود به زمان و یک‌بارمصرف باشد و Referrer، Logging و HTTPS به‌درستی مدیریت شوند.

آیا Password جدید را می‌توان در Email ارسال کرد؟

خیر. User باید Password را خودش در صفحه امن تعیین کند و Password نباید در Email ارسال شود.

WordPress بازیابی Password داخلی دارد؟

بله. WordPress توابع داخلی برای ارسال Recovery Email، تولید Password Reset Key و تنظیم Password جدید دارد. با این حال Pluginها و Custom Login Flowها نیز باید جداگانه از نظر امنیت بررسی شوند.

بهترین معماری Reset Password چیست؟

معماری مناسب شامل Generic Response، Rate Limiting، Secure Random Token، Token Hashing، Expiration، Single Use، HTTPS، Restricted Recovery Session، Password Policy، Session Revocation، Notification و Monitoring است.

جمع‌بندی

امنیت بازیابی رمز عبور یکی از مهم‌ترین بخش‌های Authentication است، زیرا Forgot Password در عمل یک مسیر جایگزین برای اثبات مالکیت Account ایجاد می‌کند.

اگر این مسیر از Login اصلی ضعیف‌تر باشد، مهاجم نیازی به شکستن Password، MFA یا سایر کنترل‌های ورود ندارد؛ کافی است Recovery Flow را هدف قرار دهد.

اولین اصل، جلوگیری از User Enumeration است.

Application نباید از طریق متن Response، Status Code، Timing یا JSON Structure مشخص کند Email یا Username در سیستم ثبت شده است.

پاسخ مناسب باید عمومی باشد:

اگر حسابی با این مشخصات وجود داشته باشد،
راهنمای بازیابی برای آن ارسال خواهد شد.

مرحله بعد Token Security است.

Reset Token باید با مولد تصادفی رمزنگاری‌شده ایجاد شود، طول و Entropy کافی داشته باشد، به User مشخص متصل شود، امن ذخیره شود، Expiration داشته باشد و تنها یک بار قابل استفاده باشد.

بهتر است Server به جای Token خام، Hash آن را ذخیره کند.

لینک بازیابی باید فقط روی HTTPS ارسال شود و Domain آن نباید از Host Header غیرقابل‌اعتماد ساخته شود.

Reset Page نیز باید تا حد امکان ساده باشد و از Third-Party Resourceهای غیرضروری، Referrer Leakage و Logging Token جلوگیری کند.

پس از Verify Token، User باید تنها به یک Recovery Context محدود دسترسی داشته باشد، نه Session کامل Account.

Password جدید باید براساس Policy اصلی Application بررسی شود و Passwordهای شناخته‌شده افشاشده نیز بهتر است Block شوند.

Password باید با Password Hashing Function مناسب ذخیره شود و هرگز در Email یا Log قرار نگیرد.

پس از Reset موفق، Token فوراً Invalid می‌شود.

در سرویس‌های حساس Sessionهای قدیمی نیز باید Revoke شوند تا Attacker نتواند با Session قبلی داخل Account باقی بماند.

User نیز باید از تغییر Password مطلع شود تا Reset غیرمجاز سریع‌تر تشخیص داده شود.

در حساب‌های دارای MFA، Reset Password نباید به معنی حذف MFA باشد.

Recovery مربوط به MFA باید Process جداگانه‌ای داشته باشد.

برای Administratorها، حساب‌های مالی و کاربران پرریسک نیز Recovery Policy قوی‌تری قابل توجیه است.

در نهایت یک Reset Password امن فقط یک لینک Email نیست.

این Feature یک Authentication System کوچک و موقت است که Token Generation، Identity Verification، Session Management، Password Security، Notification، Rate Limiting و Monitoring را همزمان درگیر می‌کند.

اگر مهاجم بتواند Recovery را دور بزند، قدرت Authentication اصلی دیگر اهمیت چندانی ندارد؛ بنابراین امنیت Account همیشه باید شامل امنیت مسیر بازیابی آن نیز باشد.

مطالب مرتبط