Cách tốt nhất để thực hiện 'quên mật khẩu'? [đóng cửa]


153

Tôi đang tìm kiếm phương pháp tốt nhất để thực hiện tính năng "quên mật khẩu".

Tôi đưa ra 2 ý tưởng:

  1. Khi người dùng nhấp vào quên mật khẩu, người dùng được yêu cầu nhập tên người dùng, email và có thể ngày sinh hoặc họ. Sau đó, một thư có mật khẩu tạm thời sẽ được gửi đến tài khoản email của người dùng. Người dùng sử dụng mật khẩu tạm thời để đăng nhập và đặt lại mật khẩu của mình.

  2. Tương tự, nhưng email sẽ chứa một liên kết để cho phép người dùng đặt lại mật khẩu của mình.

Hoặc bất cứ ai có thể đề nghị cho tôi một cách tốt hơn và an toàn? Tôi cũng đang suy nghĩ để gửi mật khẩu hoặc liên kết tạm thời, buộc người dùng đặt lại mật khẩu trong vòng 24 giờ, nếu không mật khẩu hoặc liên kết tạm thời sẽ không thể sử dụng được. Làm thế nào để làm điều đó?


Tôi đã gắn thẻ lại bài đăng vì điều này vượt ra ngoài JSF - có thể bạn sẽ nhận được nhiều phản hồi hơn theo cách đó.
McDowell

6
@Whoever Có một làn sóng "hãy xóa câu hỏi đóng này vì XYZ" trên meta những tháng này. Tôi chỉ muốn đưa ra rằng không nên xóa câu hỏi đặc biệt này, trừ khi nó được chứng minh rằng các giải pháp còn thiếu sót và sự tồn tại của nó gây tổn hại nặng nề hơn là giúp bảo mật.
Félix Gagnon-Grenier

1
OWASP "cheat sheet" cho chiến lược khôi phục mật khẩu đã quên: owasp.org/index.php/ trên
daiscog

Liên kết được đề xuất bởi @megaflop hiện đang bị hỏng một cách đáng buồn, đây là liên kết mới: cheatsheetseries.owasp.org/cheatsheets/
Kẻ

Câu trả lời:


185

Cập nhật: sửa đổi vào tháng 5 năm 2013 để có cách tiếp cận tốt hơn

  1. Người dùng nhập tên người dùng của mình và nhấn "quên mật khẩu". Tôi cũng đề xuất tùy chọn nhập địa chỉ email thay vì tên người dùng, vì tên người dùng đôi khi cũng bị quên.
  2. Hệ thống này có một bảng password_change_requestsvới các cột ID, TimeUserID. Khi người dùng mới nhấn nút, một bản ghi được tạo trong bảng. Các Timecột chứa thời gian khi người dùng nhấn nút "Quên mật khẩu". Đây IDlà một chuỗi. Một chuỗi ngẫu nhiên dài được tạo ra (giả sử là GUID) và sau đó được băm như mật khẩu (là một chủ đề riêng biệt trong chính nó). Băm này sau đó được sử dụng làm 'ID' trong bảng.
  3. Hệ thống sẽ gửi một email đến người dùng có chứa một liên kết trong đó. Liên kết cũng chứa chuỗi ID gốc (trước khi băm). Liên kết sẽ là một cái gì đó như thế này : http://www.mysite.com/forgotpassword.jsp?ID=01234567890ABCDEF. Trang quênpassword.jsp sẽ có thể truy xuất tham số ID. Xin lỗi, tôi không biết Java, vì vậy tôi không thể cụ thể hơn.
  4. Khi người dùng nhấp vào liên kết trong email, anh ta sẽ được chuyển đến trang của bạn. Trang lấy ra IDtừ URL, băm nó một lần nữa và kiểm tra bảng. Nếu một bản ghi như vậy ở đó và không quá, giả sử, 24 giờ, người dùng sẽ được nhắc nhở nhập mật khẩu mới .
  5. Người dùng nhập mật khẩu mới, nhấn OK và mọi người sống hạnh phúc mãi mãi ... cho đến lần sau!

1
cách thích hợp nhất để thực hiện điều này sẽ là - gửi mã thông báo đặt lại mật khẩu tạm thời dưới dạng email dưới dạng văn bản đơn giản cho người dùng (nhưng không bao giờ lưu trữ dưới dạng văn bản đơn giản trong DB) - sau khi người dùng nhập tạm thời này ngay lập tức buộc anh ta phải nhập lại mật khẩu mới - đối với người hoang tưởng, hãy đảm bảo rằng máy chủ smtp của bạn có ssl, vì vậy thư của bạn chứa thông tin nhạy cảm sẽ không bị rình mò. đối với hầu hết các trường hợp, phương pháp này khá an toàn. nếu trường hợp của bạn yêu cầu bảo mật hơn nữa, có lẽ bạn không nên có người dùng quên mật khẩu của họ: S
Kaushik Gopal

6
Tại sao tạo một chuỗi / hướng dẫn ngẫu nhiên, băm nó và sử dụng hàm băm? Hướng dẫn không đủ?
Jeroen K

15
@jeroenk - Vì vậy, nếu ai đó đánh cắp DB của bạn, anh ta không thể giả mạo liên kết "Đặt lại mật khẩu" và thay đổi mật khẩu của ai đó.
Vilx-

4
về cơ bản, đây là cách được mô tả để đặt lại mật khẩu crackstation.net/hashing-security.htmlm#faq
TruthOf42

1
@David - Ach, tôi muốn chỉnh sửa bài, nhưng chủ đề đã bị khóa. :( OK, chúng ta hãy thử lại: bảng của bạn sẽ chứa các cột: ID, UserID, Time, TokenHash.. Bạn sẽ tạo ra HAI dài, chuỗi ngẫu nhiên Đặt chuỗi đầu tiên ( "id") trong IDcột; băm thứ hai (các "token" ) và đặt hàm băm vào TokenHashcột. Tạo liên kết như thế forogotPassword.jsp?id=asdasd&token=asdasd. Mã thông báo trong liên kết KHÔNG được băm. Điều này có ý nghĩa bây giờ không?
Vilx-

28

Tất cả phụ thuộc vào trang web của bạn và mức độ bảo mật mà bạn đang cố gắng đạt được nhưng quy trình cơ bản cho ứng dụng web diễn ra như sau:

  1. Người dùng điều hướng đến trang 'quên mật khẩu của tôi' và nhập tên người dùng hoặc email của họ (tùy theo số nào là duy nhất) để yêu cầu đặt lại mật khẩu.

  2. Tùy chọn ở giai đoạn này, bạn có thể xác nhận yêu cầu bằng cách hỏi thêm thông tin, chẳng hạn như câu trả lời cho câu hỏi bảo mật được xác định trước hoặc ngày sinh của họ, v.v. Cấp độ thêm này ngăn người dùng nhận email mà họ không yêu cầu.

  3. Tra cứu tài khoản của người dùng. Lưu mật khẩu tạm thời (thường là GUID) và dấu thời gian đối với bản ghi tài khoản. Gửi email cho người dùng có chứa mật khẩu tạm thời.

  4. Người dùng nhấp vào liên kết chứa mật khẩu tạm thời và số nhận dạng người dùng trong email hoặc điều hướng đến trang 'quên mật khẩu của tôi' và sao chép & dán mật khẩu tạm thời và số nhận dạng của họ. Người dùng nhập mật khẩu mới của họ và xác nhận nó.

  5. Tra cứu bản ghi của người dùng và nếu thời gian hiện tại nằm trong giới hạn thời gian được chỉ định (ví dụ: 1 giờ) của dấu thời gian được lưu trong bước 2 thì băm và lưu mật khẩu mới. (Rõ ràng chỉ khi mật khẩu tạm thời khớp!). Xóa GUID tạm thời và dấu thời gian.

Hiệu trưởng ở đây là người dùng được gửi email mật khẩu tạm thời cho phép họ thay đổi mật khẩu. Mật khẩu được lưu trữ ban đầu (cần được băm!) Không bao giờ được thay đổi thành mật khẩu tạm thời trong trường hợp người dùng nhớ nó.

Mật khẩu ban đầu sẽ không bao giờ được hiển thị cho người dùng vì nó cần được băm và không xác định.

Lưu ý quá trình này phụ thuộc hoàn toàn vào bảo mật tài khoản email của người dùng. Vì vậy, nó phụ thuộc vào mức độ bảo mật mà bạn muốn đạt được. Điều này thường là đủ cho hầu hết các trang web / ứng dụng.


24

Troy Hunt đưa ra một số điểm tuyệt vời trong bài viết của mình, Mọi thứ bạn từng muốn biết về việc xây dựng tính năng đặt lại mật khẩu an toàn . Các trích đoạn có liên quan nhất là:

[T] đây là hai cách tiếp cận phổ biến:

  1. Tạo mật khẩu mới trên máy chủ và gửi email
  2. Gửi email một URL duy nhất sẽ tạo điều kiện cho quá trình đặt lại

Mặc dù có rất nhiều hướng dẫn ngược lại, điểm đầu tiên thực sự không phải là nơi chúng ta muốn. Vấn đề với việc này là nó có nghĩa là một mật khẩu liên tục - mật khẩu bạn có thể quay lại và sử dụng bất cứ lúc nào - hiện đã được gửi qua một kênh không an toàn và nằm trong hộp thư đến của bạn.

...

Nhưng có một vấn đề lớn hơn với cách tiếp cận đầu tiên ở chỗ nó làm cho việc khóa tài khoản độc hại trở nên đơn giản. Nếu tôi biết địa chỉ email của một người sở hữu tài khoản tại một trang web thì tôi có thể khóa chúng khỏi tài khoản đó bất cứ khi nào tôi muốn chỉ bằng cách đặt lại mật khẩu của họ; đó là tấn công từ chối dịch vụ phục vụ trên một đĩa bạc! Đây là lý do tại sao thiết lập lại là điều chỉ nên xảy ra sau khi xác minh thành công quyền của người yêu cầu thực hiện.

Khi chúng tôi nói về một URL đặt lại, chúng tôi đang nói về một địa chỉ trang web duy nhất cho trường hợp cụ thể này của quy trình đặt lại.

...

Những gì chúng tôi muốn làm là tạo một mã thông báo duy nhất có thể được gửi trong email dưới dạng một phần của URL đặt lại, sau đó khớp lại với một bản ghi trên máy chủ cùng với tài khoản của người dùng, do đó xác nhận chủ sở hữu tài khoản email thực sự là người cố gắng đặt lại mật khẩu. Ví dụ: mã thông báo có thể là Mã 3ce7854015cd38c862cb9e14a1ae552b thép và được lưu trữ trong một bảng cùng với ID của người dùng thực hiện đặt lại và thời gian mã thông báo được tạo ra (nhiều hơn trong một khoảnh khắc). Khi email được gửi đi, nó chứa một URL như là Reset Reset /? Id = 3ce7854015cd38c862cb9e14a1ae552b, và khi người dùng tải cái này, trang sẽ kiểm tra sự tồn tại của mã thông báo và do đó xác nhận danh tính của người dùng và cho phép xác nhận danh tính của người dùng được thay đổi.

...

Một điều khác mà chúng tôi muốn làm với URL đặt lại là giới hạn thời gian mã thông báo để quá trình đặt lại phải được hoàn thành trong một khoảng thời gian nhất định, giả sử trong vòng một giờ.

...

Cuối cùng, chúng tôi muốn đảm bảo rằng đây là quy trình một lần. Khi quá trình đặt lại hoàn tất, mã thông báo sẽ bị xóa để URL đặt lại không còn hoạt động. Cũng như điểm trước, điều này là để đảm bảo kẻ tấn công có một cửa sổ rất hạn chế trong đó chúng có thể lạm dụng URL đặt lại. Tất nhiên, mã thông báo không còn cần thiết nếu quá trình đặt lại hoàn tất thành công.

Anh ta đưa ra nhiều điểm tốt hơn về việc tránh rò rỉ thông tin, CAPTCHA, xác thực hai yếu tố và tất nhiên là các cách thực hành cơ bản tốt nhất như băm mật khẩu. Tôi nghĩ điều quan trọng cần lưu ý là tôi không đồng ý với Troy về tính hữu ích của các câu hỏi bảo mật, thích sự hoài nghi của Bruce Schneier về thực tiễn :

Điểm của tất cả những câu hỏi này là như nhau: mật khẩu dự phòng. Nếu bạn quên mật khẩu, câu hỏi bí mật có thể xác minh danh tính của bạn để bạn có thể chọn một mật khẩu khác hoặc để trang web gửi e-mail mật khẩu hiện tại của bạn cho bạn. Đó là một ý tưởng tuyệt vời từ góc độ dịch vụ khách hàng - người dùng ít có khả năng quên tên thú cưng đầu tiên của mình hơn một số mật khẩu ngẫu nhiên - nhưng rất tệ cho bảo mật. Câu trả lời cho câu hỏi bí mật dễ đoán hơn nhiều so với mật khẩu tốt và thông tin công khai hơn nhiều.


1
Liên kết đó có hình ảnh NSFW rõ ràng, có một liên kết để thay đổi điều này nhưng rất nhiều người quét một trang đầu tiên. Ý tưởng ngu ngốc!
nik0lai

Liên kết đến bài viết của Troy Hunt đã thay đổi. Goto troyhunt.com/everything-you-ever-wocate-to-ledge
knarfancho 20/07/17

@knarfancho Đã sửa, cảm ơn!
Dave Liepmann

15

Tôi sẽ đi với:

  1. Yêu cầu người dùng email, kiểm tra email đã được đăng ký
  2. Tạo GUID và gửi nó đến email đó
  3. Chưa đặt lại mật khẩu
  4. Người dùng nhấp vào liên kết và sau đó phải nhập thẻ mới
  5. Đặt lại mật khẩu chỉ sau khi người dùng ở trong trang web của bạn và đã nhấp vào nút đặt lại sau khi nhập mật khẩu mới.
  6. Làm cho GUID đó có thể hết hạn trong một khoảng thời gian ngắn để làm cho nó an toàn hơn.

Tôi không muốn gặp rắc rối khi hỏi a? nhưng nó có liên quan đến câu trả lời của bạn Bạn đang tạo GUID như thế nào?
KingAndrew

2
-1 vì không triển khai một số loại băm trên liên kết bạn đang gửi cho người đó
TruthOf42

11

Khi bạn gửi bất kỳ thông tin nào qua email, nó sẽ không được bảo mật. Có quá nhiều cách để ai đó có thể có được nó. Nó sẽ là trò chơi trẻ con của một hacker lành nghề đang tìm cách đánh cắp thông tin của bạn.

Không gửi bất kỳ thông tin cá nhân nào như mật khẩu và thông tin thu nhập qua email vì nó có thể trở thành RẤT NHIỀU KHẢ NĂNG cho bạn và tổ chức của bạn nếu thông tin đó bị rò rỉ hoặc đánh cắp. Hãy suy nghĩ về an ninh nghiêm túc. Nó chỉ mất một sự cố cho tất cả các viên gạch rơi xuống.

Đối với việc lấy lại mật khẩu, hãy đọc kỹ Thực hành tốt nhất Quên mật khẩu .

Điểm mấu chốt là một ứng dụng tuân theo các thực tiễn tốt nhất sẽ cho phép người dùng đặt lại mật khẩu của chính mình. Câu hỏi bảo mật cá nhân nên được sử dụng. Ứng dụng không nên gửi email, hiển thị mật khẩu, cũng như không đặt bất kỳ mật khẩu tạm thời nào.

EDIT: Liên kết cập nhật



Tôi đã thử liên kết về Quên mật khẩu Thực tiễn tốt nhất và gặp lỗi 500 máy chủ. Bạn có nghĩ rằng máy chủ đã ngừng hoạt động hoặc có một liên kết khác để theo dõi?
KingAndrew


liên kết đã chết một lần nữa.
Eric đối phó


7

Như đã nói, nó phụ thuộc vào mức độ bảo mật cần thiết, tuy nhiên, nếu bạn cần một mức độ cao hơn, một số giải pháp mới mà tôi đã thấy bao gồm;

  • Hiển thị một nửa mật khẩu tạm thời khi danh tính người dùng đã được xác nhận (câu hỏi bảo mật, địa chỉ email, v.v.) sau đó nửa còn lại được gửi đến tài khoản email. Nếu tài khoản email đã bị xâm phạm, không có khả năng cùng một người đó cũng đã thực hiện được một cuộc tấn công trung gian. (Nhìn trên Cổng chính phủ Vương quốc Anh)

  • Xác nhận danh tính qua email và phương tiện khác - ví dụ mã được gửi qua văn bản đến điện thoại di động đã đăng ký. (Nhìn trên eBay / PayPal)

Đối với một nơi nào đó ở giữa hai thái cực này, việc thực hiện các câu hỏi bảo mật có thể là cách để được đề cập bởi DaveG.


6

Nếu bạn bao gồm một địa chỉ email với đăng ký. Nút "quên mật khẩu" sẽ gửi email đến địa chỉ email đó. Nó đảm bảo rằng thông tin được gửi đến một email đáng tin cậy.

(Trừ khi cơ sở dữ liệu bị hack, nhưng sau đó không có gì an toàn).



4

Tôi sẽ thực thi các địa chỉ email duy nhất trên các tài khoản.

Sau đó, việc gửi một liên kết đến một trang tạm thời cho phép người đó thay đổi mật khẩu là một vấn đề đơn giản. (cho phép 24 giờ hoặc ít hơn)

Tài khoản email của người dùng là liên kết yếu nhất trong kịch bản này.


2

Không bao giờ gửi email mật khẩu cho người dùng. Ngay cả khi nó được tạo tự động. Cách tiếp cận tốt nhất (được đề xuất và sử dụng bởi Sans và những người khác):

  1. Trên trang quên mật khẩu, hãy hỏi email / id người dùng và mật khẩu MỚI từ người dùng.
  2. Gửi liên kết đến email được lưu trữ cho tài khoản đó bằng liên kết kích hoạt.
  3. Khi người dùng nhấp vào liên kết đó, kích hoạt mật khẩu mới.

Nếu anh ta không nhấp vào liên kết trong vòng 24 giờ hoặc lâu hơn, hãy tắt liên kết (để nó không thay đổi mật khẩu nữa).

Không bao giờ thay đổi mật khẩu mà không có sự đồng ý của người dùng. Điều này có nghĩa là không gửi email mật khẩu mới chỉ vì ai đó nhấp vào liên kết quên mật khẩu và tìm ra tên tài khoản.


13
Tôi quan tâm đến kỹ thuật này. Attacker nhập email của bạn và mật khẩu MỚI. Chủ tài khoản nhận được email, đọc sai nội dung nào đó và nhấp vào liên kết. Kẻ tấn công đứng bên cạnh, thử mật khẩu mới mỗi phút, giành quyền truy cập vào tài khoản cho đến khi chủ tài khoản nhận ra điều gì đã xảy ra và cuối cùng chuyển đến trang "quên mật khẩu".
Odi - Xceed

Một vấn đề khác! cung cấp mật khẩu mới về thời gian đặt lại mật khẩu không phải là một lựa chọn tốt. Tôi có thể quên mật khẩu mới một lần nữa nếu kiểm tra email của tôi sau nhiều giờ!
Yazid Erman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.