امنیت بازیابی رمز عبور؛ چگونه 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 امن
یک معماری معمول و نسبتاً امن میتواند چنین باشد:
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 یعنی مهاجم بتواند از تفاوت رفتار 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 باید غیرقابل پیشبینی باشد.
نباید براساس مواردی مانند:
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
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
و لینک تنها از این مقدار ساخته شود.
Reset Link باید HTTPS باشد
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های قبلی چه کنیم؟
این یکی از مهمترین تصمیمهاست.
فرض کنید 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 امن
یک معماری چندلایه میتواند چنین باشد:
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
- برای Account موجود و ناموجود Response یکسان نمایش دهید.
- Timing قابل تشخیص میان دو حالت را کاهش دهید.
- Forgot Password Endpoint را Rate Limit کنید.
- Rate Limit را فقط بر اساس IP طراحی نکنید.
- درخواست Reset نباید Account را Lock کند.
- Input Email و Username را Validate کنید.
- Token را با CSPRNG تولید کنید.
- Token باید Entropy و طول کافی داشته باشد.
- Token را به User و Recovery Request متصل کنید.
- Token را ترجیحاً Hashشده ذخیره کنید.
- Reset Token باید Expiration داشته باشد.
- Token باید Single Use باشد.
- Token قدیمی را پس از صدور Token جدید Invalid کنید.
- لینک Reset فقط HTTPS باشد.
- Domain لینک را از Host Header غیرقابلاعتماد نسازید.
- Domainهای Reset را Allowlist کنید.
- Full Token را در Access Log ذخیره نکنید.
- Query Stringهای حساس را Redact کنید.
- برای Reset Page از Referrer Policy مناسب استفاده کنید.
- Third-Party Scriptهای غیرضروری را حذف کنید.
- Cache صفحه حساس را محدود کنید.
- Token Validation را نیز Rate Limit کنید.
- Error Token نامعتبر را عمومی نگه دارید.
- پس از Verify Token فقط Recovery Session محدود بسازید.
- Recovery Session نباید دسترسی کامل Account بدهد.
- فرم تعیین Password را در برابر CSRF متناسب با معماری محافظت کنید.
- Password Policy با Registration یکسان باشد.
- Passwordهای افشاشده را Block کنید.
- Password را با Password Hashing Function امن ذخیره کنید.
- Password را در Log ذخیره نکنید.
- Password جدید را Email نکنید.
- User را مجبور کنید Password را دوبار وارد کند.
- پس از Reset، Token را فوراً Invalid کنید.
- Auto Login بعد از Reset را حذف کنید.
- Login عادی و MFA را پس از Reset حفظ کنید.
- Reset Password نباید MFA را خودکار حذف کند.
- Sessionهای قدیمی را Revoke یا حداقل به User امکان Revocation بدهید.
- Remember-Me Token و Refresh Token را در Threat Model قرار دهید.
- بعد از Reset Notification ارسال کنید.
- Notification نباید Secret داشته باشد.
- تغییر Email را جداگانه با Re-authentication محافظت کنید.
- Security Question را تنها Recovery Factor قرار ندهید.
- Recovery Code را مانند Secret حساس مدیریت کنید.
- برای Adminها Recovery Policy سختگیرانهتر داشته باشید.
- رویدادهای Reset را Audit Log کنید.
- Token و OTP را هیچگاه Log نکنید.
- Reset Abuse را مانیتور کنید.
- تمام APIهای Legacy بازیابی Password را Inventory کنید.
- Mobile و Web Recovery Policy را هماهنگ کنید.
- 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 همیشه باید شامل امنیت مسیر بازیابی آن نیز باشد.