2009-12-16 4 views
8

Tôi đang phát triển hệ thống đăng nhập và xác thực cho một trang web PHP mới và đã được đọc về các cuộc tấn công và lỗ hổng khác nhau. Tuy nhiên, đó là một chút bối rối, vì vậy tôi muốn kiểm tra xem cách tiếp cận của tôi có hợp lý không.Phát triển chiến lược xác thực và đăng nhập PHP an toàn

tôi có kế hoạch lưu trữ các dữ liệu sau:

  • Trong phiên họp: sử dụng id, băm + muối HTTP_USER_AGENT

  • Trong cookie và trong cơ sở dữ liệu: thẻ ngẫu nhiên , hashed + salted identifier

Trên mọi trang, tôi kế hoạch thực hiện các việc sau:

  1. Nếu có phiên, hãy xác thực bằng cách sử dụng điều đó. Kiểm tra xem HTTP_USER_AGENT có khớp với số trong phiên được lưu trữ không.

  2. Nếu không có phiên nào tồn tại, hãy sử dụng cookie để xác thực. Kiểm tra mã thông báo và mã nhận diện trong cookie khớp với các mã trong cơ sở dữ liệu.

  3. Nếu cookie không hợp lệ hoặc không tồn tại, hãy yêu cầu người dùng đăng nhập.

Có bất kỳ sai sót rõ ràng nào trong vấn đề này không? Miễn là tôi đặt một thời gian chờ trong cookie, tôi nên khá an toàn, phải không? Có điều gì tôi đang thiếu?

Rất cám ơn trước.

+0

cũng xem xét sử dụng một số hệ thống sử dụng mã thông báo cho các hành động quan trọng ... – TheHippo

+0

Chính xác, lưu trữ id phiên trong cơ sở dữ liệu là lỗi lớn. Bằng cách lưu trữ các id phiên trong cơ sở dữ liệu bạn làm cho tiêm sql chống lại hệ thống của bạn có giá trị hơn nhiều. Bạn phải giả định rằng hệ thống của bạn sẽ bị xâm phạm và bạn phải có kế hoạch hành động để giải quyết vi phạm. Đây là lý do tại sao mật khẩu được lưu trữ dưới dạng băm. Hơn nữa php đi kèm với một trình xử lý phiên, nếu bạn tái phát minh ra sự rên rỉ, tôi đảm bảo với bạn rằng nó sẽ kém an toàn hơn. – rook

+0

Có rất nhiều bài đọc tốt ở đây: http://stackoverflow.com/questions/549/the-definitive-guide-to-website-authentication-beta#477579 –

Trả lời

12

Một vài suy nghĩ ngẫu nhiên:

  1. gì nếu tôi ăn cắp cookie của một trong những người dùng của bạn (sử dụng một cuộc tấn công XSS bằng cách tiêm một số mã JS trong trang web của bạn)? Sau đó tôi sẽ rơi vào trường hợp 2. và do đó có thể đăng nhập. IMHO, nếu bạn muốn xác thực thực sự an toàn, không sử dụng cookie "nhớ tôi" để lưu trữ thông tin đăng nhập của người dùng.
  2. Nếu bạn lưu trữ thông tin xác thực trong cookie, vui lòng không lưu trữ mật khẩu rõ ràng.
  3. Kiểm tra HTTP_USER_AGENT là bước đầu tiên tốt để ngăn chặn tấn công phiên, nhưng có thể bạn có thể kết hợp nó với địa chỉ IP? Sẽ khó khăn hơn nhiều khi bạn sử dụng cùng một trình duyệt.

Nhưng trong mọi trường hợp, cảm ơn bạn đã dành thời gian suy nghĩ về một chương trình xác thực tốt. Rất nhiều nhà phát triển PHP không.

EDIT: cho bản ghi, hãy để tôi làm rõ một điểm ở đây: có hai cookie trong sự phân tách này. Một được thiết lập tự động bằng PHP để truyền bá ID phiên (đôi khi, chúng tôi thấy các trang web đặt nó trong URL, ví dụ: www.example.com/page.php?sessionId = [...]) và thứ hai do bạn tạo để lưu trữ thông tin xác thực người dùng và xác thực anh ta khi phiên bị mất. Tấn công XSS áp dụng cho cả hai, tức là kẻ tấn công có thể ăn cắp cookie phiên và chiếm quyền điều khiển phiên (có thời gian giới hạn) hoặc lấy cắp cookie thông tin xác thực và xác thực sau.

+0

Kiểm tra sự kết hợp của tác nhân người dùng và 3 octet đầu tiên của IP là khá tốt. Tôi đã viết một bài báo về chủ đề này tại http://www.jqueryin.com/2009/11/20/php-secure-sessions/. –

+0

Thật vậy, user agent + ip address là quá đủ. Nhưng tại sao lại giảm octet cuối cùng? IMO, nó là phần quan trọng nhất của địa chỉ IP, vì hàng xóm của tôi có thể nằm trong cùng một mạng con ISP và do đó có cùng ba octet đầu tiên? Tuyệt vời btw bài viết, tôi personnaly sử dụng hai muối: một trong những cố định trong một tập tin cấu hình, và một tạo ngẫu nhiên về tạo người dùng. – Wookai

+0

Lưu trữ cookie trong cơ sở dữ liệu là ý tưởng HORRILBE. Nó có nghĩa là nếu kẻ tấn công có lỗ hổng tiêm sql, anh ta có thể truy cập ngay lập tức mà không cần phải bẻ khóa mật khẩu băm. – rook

2

không được có. phiên php được lưu trữ trên máy chủ của bạn không phải là người dùng. php simpily để lại một cookie phiên chỉ vào nó. nếu bạn không chia sẻ lưu trữ phiên, thậm chí không cần phải băm.

joe

1

Tùy thuộc vào an toàn như thế nào bạn muốn trở thành ..

lỗ hổng cross-site: phép nói rằng một trang web khác chỉ đạo các trình duyệt để gửi biểu mẫu để trang web của bạn mà không một cái gì đó giống như đăng thư rác (hoặc tệ hơn) nếu đó người dùng đã đăng nhập vào biểu mẫu gửi sẽ hoạt động. Bạn sẽ cần phải kiểm tra referer và một formID ẩn được tạo cho mỗi form để bảo vệ chống lại điều này hoàn toàn.

Thứ hai: Nếu bạn có lưu lượng truy cập từ trung bình đến cao, sessionID có thể được lặp lại hoặc thậm chí được đoán, tôi sẽ kiểm tra ID cũ được tạo trong cookie của người dùng.

1

Đề án có vẻ không cần thiết phức tạp theo một vài cách, trong đó độ phức tạp thêm không giúp bạn đạt được bất kỳ điều gì về chức năng hoặc bảo mật.

  1. Mọi dữ liệu được gửi bởi trình duyệt (ví dụ: cookie, Tác nhân người dùng) là giả mạo. Kiểm tra User-agent sẽ chỉ giúp đỡ khi kẻ tấn công đứng sau NAT giống như người dùng giả mạo và kẻ tấn công đang sử dụng một trình duyệt khác nhưng không nghĩ đến việc thay đổi User-agent.
  2. Phiên lưu trữ phía máy khách id phiên sử dụng cookie hoặc tham số truy vấn URL. Nếu bạn muốn kéo dài tuổi thọ của phiên, hãy sử dụng session_set_cookie_params để giữ cookie phiên lâu hơn.

Tác nhân người dùng không phải là dữ liệu bí mật, do đó việc băm không cần thiết.

Các vụ tấn công mà cookie phiên + kiểm tra IP từ xa sẽ không bắt là:

  1. kẻ tấn công là phía sau cùng NAT như là người dùng
  2. tấn công tiêm mù, nơi mà các tấn công giả mạo IP của người dùng. Mặc dù chỉ được viết, những thứ này vẫn có thể gây ra một số thiệt hại.
  3. các cuộc tấn công sử dụng trình duyệt của riêng người dùng, chẳng hạn như cross-site request forgery (CSRF).

2) có thể được ngăn chặn nếu bạn có thể thực hiện một cách để gửi thử thách cho trình duyệt của người dùng, mà phải được trả lời trước khi hoàn thành yêu cầu, nhưng điều này là khó khăn khi bạn không viết máy khách. Với AJAX nó có thể được thực hiện. 3) (như được lưu ý bởi MindStalker) có thể được ngăn chặn bằng cách kiểm tra tiêu đề Referer, hoạt động vì các cuộc tấn công CSRF không có khả năng ảnh hưởng đến các tiêu đề tùy ý, và XMLHttpRequest không nên cho phép tiêu đề Người giới thiệu (theo W3C standard , mặc dù việc triển khai có thể không tuân thủ). Với iframe, có thể kiểm tra Referer. Ngoài ra, tiêu đề Người giới thiệu có thể bị chặn phía máy khách.

2

Lưu trữ cookie trong cơ sở dữ liệu là ý tưởng HORRILBE. Nó có nghĩa là nếu kẻ tấn công có lỗ hổng tiêm sql, anh ta có thể truy cập ngay lập tức mà không cần phải bẻ khóa mật khẩu băm.

Phát biểu trong đó bạn cần sử dụng sha256 cho mật khẩu, nếu bạn sử dụng md5(), bạn có thể bị tấn công về mặt kỹ thuật và bạn có thể được cấp số CVE.

KHÔNG BAO GIỜ tạo ID phiên của riêng bạn, sử dụng session_start() và siêu $ _SESSION toàn cầu.

Đây là cách an toàn để chuyển hướng mọi người. Nếu bạn không chết sau khi tiêu đề() phần còn lại của mã php vẫn được thực thi mặc dù nó không được hiển thị bởi các trình duyệt thông thường (hacker vẫn thấy nó :)

header("location: index.php"); 
die(); 

Thành thật mà nói nếu an ninh lẫn lộn bạn, don không viết hệ thống bảo mật. Mọi người đã viết hơn 1.000 hệ thống đăng nhập cho PHP một mình và phần lớn là dễ bị tổn thương. Dự án này có hệ thống xác thực an toàn: http://code.google.com/p/michael-the-messenger/downloads/list

+0

Về điểm đầu tiên của bạn - Tôi không có nghĩa là nó sẽ lấy cookie của người dùng và lưu nó trong cơ sở dữ liệu; đó sẽ là ngớ ngẩn! Tôi có nghĩa là một mã thông báo và một định danh được tạo ra và sau đó một bản sao được đặt trong cookie và một bản sao khác trong cơ sở dữ liệu. Không có dữ liệu nào từ cookie chuyển vào cơ sở dữ liệu, vì vậy nó không thể được tiêm theo cách đó. Cảm ơn bạn đã biết về tiêu đề(), tôi chưa bao giờ biết điều đó. –

+0

Chính xác, đó là một sai lầm lớn. Bằng cách lưu trữ các giá trị cookie trong cơ sở dữ liệu bạn làm cho tiêm sql chống lại hệ thống của bạn có giá trị hơn nhiều. Bạn phải giả định rằng hệ thống của bạn sẽ bị xâm phạm và bạn phải có kế hoạch hành động để giải quyết vi phạm. Đây là lý do tại sao mật khẩu được lưu trữ dưới dạng băm. Hơn nữa php đi kèm với một trình xử lý phiên, nếu bạn tái phát minh ra sự rên rỉ, tôi đảm bảo với bạn rằng nó sẽ kém an toàn hơn. – rook

+0

Đừng lo - Tôi không có kế hoạch tạo trình xử lý phiên của riêng mình! –

1

Hầu hết các trang web chỉ sử dụng phiên PHP; dữ liệu phiên ($ _SESSION) nằm ở a file trên máy chủ của bạn. Tất cả những gì được gửi đến trình duyệt là ID phiên. Đảm bảo tạo lại phiên mỗi yêu cầu (session_regenerate_id). Bạn không cần phải gửi hai cookie hoặc bất cứ thứ gì.

Điều này ít dễ bị tấn công trong phiên vì mọi yêu cầu đều là ID mới, do đó, một ID cũ chặn bởi kẻ tấn công là vô ích.

Giải pháp tốt nhất, rõ ràng là sử dụng SSL trong toàn bộ phiên.

0

IMHO cũng quan trọng là thông tin phiên được thay đổi sau khi đăng nhập thành công. Để lưu thông tin phiên trong cơ sở dữ liệu không được lưu vì tiêm.

0

-sử dụng sha1 với muối -nhiều khóa học bạn phải xác định rằng mọi biểu mẫu không an toàn để mã thông báo được sử dụng cho mọi biểu mẫu. Bạn tạo mọi mục nhập biểu mẫu và vệ sinh nó bằng cách sử dụng preg_match. Một quá trình được gọi là vệ sinh.