NhaLapTrinh.comNhà Lập Trình
Bảo mật cơ bản

Phân quyền: ai được xem dữ liệu của ai?

Phân quyền không chỉ là ẩn nút với người không có quyền. Mỗi yêu cầu tới máy chủ phải kiểm tra người này có được làm việc này với đúng dữ liệu này không. Lỗi hay gặp nhất là chỉ kiểm tra đã đăng nhập mà quên kiểm tra dữ liệu có thuộc về người đó không.

🎙️
📑 Nội dung theo chương
  1. 0:35 Xác thực và phân quyền là hai việc
  2. 1:14 Lỗi đổi một con số
  3. 2:08 Ẩn nút không phải là phân quyền
  4. 2:51 Ứng dụng nhiều khách hàng dùng chung
  5. 3:42 Quyền tối thiểu và kiểm tra ở một chỗ
  6. 4:29 Câu hỏi thường gặp
🔊 Bản audio (lồng nhạc nền)

Phân quyền không chỉ là ẩn đi nút bấm với người không có quyền. Mỗi yêu cầu tới máy chủ đều phải kiểm tra: người này có được làm việc này, với đúng dữ liệu này hay không. Lỗi hay gặp nhất là chỉ kiểm tra người dùng đã đăng nhập, mà quên kiểm tra dữ liệu họ đang đòi xem có thuộc về họ hay không.

Chào bạn, đây là Nhà Lập Trình. Nếu tập trước nói không tin dữ liệu người dùng gửi lên, thì tập này nói về một dạng cụ thể và cực kỳ phổ biến của lỗi đó. Nó không cần kỹ năng gì đặc biệt để khai thác, chỉ cần đổi một con số. Và nó có mặt trong rất nhiều ứng dụng mà người viết nghĩ là đã an toàn.

Xác thực và phân quyền là hai việc

Xác thực trả lời câu hỏi bạn là ai. Đăng nhập bằng mật khẩu, bằng mã gửi qua điện thoại, là xác thực. Phân quyền trả lời câu hỏi bạn được làm gì. Hai việc này hay bị nhập làm một.

Hình dung một toà nhà văn phòng. Lễ tân kiểm tra căn cước và phát thẻ từ, đó là xác thực. Nhưng thẻ từ của nhân viên công ty A không được mở cửa văn phòng công ty B trên tầng khác, đó là phân quyền. Một toà nhà chỉ có lễ tân mà mọi thẻ đều mở được mọi cửa thì chẳng an toàn chút nào.

Nhiều ứng dụng làm rất tốt phần lễ tân: đăng nhập chặt chẽ, mật khẩu băm đúng cách. Rồi sau khi vào trong, mọi cửa đều mở.

Phân quyền phải được kiểm tra ở mọi yêu cầu, không phải chỉ lúc đăng nhập.

Lỗi đổi một con số

Hãy hình dung trang xem hoá đơn có đường dẫn kết thúc bằng mã hoá đơn, một con số. Người dùng đăng nhập, xem hoá đơn của mình số một nghìn hai trăm. Rồi họ tò mò đổi con số thành một nghìn hai trăm lẻ một. Và trang hiện hoá đơn của một người khác.

Máy chủ đã kiểm tra người dùng đăng nhập chưa, rồi. Nhưng không kiểm tra hoá đơn đó có thuộc về người đang đăng nhập không. Đây là một trong những lỗ hổng phổ biến nhất trong ứng dụng web, và hậu quả có thể rất nặng: lộ thông tin cá nhân, lộ đơn hàng, lộ hồ sơ bệnh án, tuỳ ứng dụng.

Nó cũng không chỉ xảy ra với việc xem. Sửa, xoá, tải tệp, tất cả đều có thể bị. Đổi con số trong yêu cầu xoá địa chỉ giao hàng, và xoá được địa chỉ của người khác.

Cách sửa không phải là giấu con số đi hay dùng mã khó đoán. Mã khó đoán giúp giảm rủi ro, nhưng không phải lời giải. Lời giải là mỗi lần lấy dữ liệu, máy chủ kiểm tra dữ liệu đó thuộc về ai, và người đang yêu cầu có quyền với nó không.

Ẩn nút không phải là phân quyền

Một lỗi cùng họ: trang quản trị có nút xoá người dùng, chỉ hiện với quản trị viên. Người dùng thường không thấy nút. Người viết nghĩ vậy là xong.

Nhưng nút chỉ là cách gửi một yêu cầu. Ai biết đường dẫn của yêu cầu đó, và đường dẫn thường rất dễ đoán hoặc lộ ra trong mã của trang, đều có thể gửi thẳng mà không cần nút. Nếu máy chủ không kiểm tra người gửi có phải quản trị viên, thì ai cũng xoá được.

Quy tắc là giao diện chỉ dùng để hiện những gì người dùng được làm cho tiện, còn máy chủ mới là nơi quyết định. Mỗi chức năng phía máy chủ phải tự kiểm tra quyền, không giả định rằng người gọi đã đi qua đúng giao diện.

Khi xem lại mã, hãy đặt câu hỏi cho mỗi chức năng: nếu một người dùng bình thường gọi thẳng vào đây thì sao?

Ứng dụng nhiều khách hàng dùng chung

Rủi ro này đặc biệt nặng với ứng dụng phục vụ nhiều doanh nghiệp trên cùng một hệ thống, ví dụ phần mềm bán hàng cho nhiều cửa hàng, phần mềm quản lý cho nhiều trường. Dữ liệu của cửa hàng này tuyệt đối không được lộ sang cửa hàng kia.

Mọi truy vấn phải lọc theo doanh nghiệp của người đang đăng nhập. Chỉ cần một truy vấn quên điều kiện này, ví dụ trong một báo cáo mới viết vội, là dữ liệu của mọi doanh nghiệp bị trộn lẫn.

Cách an toàn là không để việc lọc này phụ thuộc vào trí nhớ của từng lập trình viên. Hãy làm nó ở một chỗ chung: mọi truy vấn đi qua một lớp tự động thêm điều kiện doanh nghiệp, hoặc cơ sở dữ liệu tự áp dụng quy tắc theo người đang kết nối. Lập trình viên muốn bỏ qua phải làm một việc có chủ đích và dễ thấy.

Và viết bài thử nghiệm cho chính điều này: đăng nhập bằng người của doanh nghiệp A, thử lấy dữ liệu của doanh nghiệp B, kết quả phải bị từ chối.

Quyền tối thiểu và kiểm tra ở một chỗ

Nguyên tắc quyền tối thiểu nói rằng mỗi người, mỗi chương trình chỉ nên có đúng những quyền cần cho việc của mình, không hơn. Nhân viên bán hàng không cần quyền xem lương. Chương trình gửi thư không cần quyền xoá cơ sở dữ liệu.

Nguyên tắc này áp dụng cả cho chính hệ thống. Tài khoản cơ sở dữ liệu mà trang web dùng không nên có quyền xoá bảng. Nếu trang web bị xâm nhập, thiệt hại bị giới hạn.

Về tổ chức mã, hãy tập trung việc kiểm tra quyền vào một chỗ thống nhất thay vì rải rác mỗi nơi một kiểu. Khi quy tắc thay đổi, bạn sửa một chỗ. Khi xem lại, bạn đọc một chỗ.

Và mặc định là từ chối. Chức năng mới thêm vào, nếu chưa khai báo quyền, thì không ai dùng được, thay vì ai cũng dùng được. Quên khai báo thì người dùng phàn nàn không vào được, còn hơn là quên khai báo mà lộ dữ liệu.

Câu hỏi thường gặp

Xác thực và phân quyền khác nhau thế nào?

Xác thực xác định bạn là ai, như khi đăng nhập. Phân quyền xác định bạn được làm gì với dữ liệu nào. Một hệ thống cần cả hai, và phân quyền phải được kiểm tra ở mọi yêu cầu.

Vì sao đổi số trên đường dẫn lại xem được dữ liệu người khác?

Vì máy chủ chỉ kiểm tra người dùng đã đăng nhập mà không kiểm tra dữ liệu được yêu cầu có thuộc về họ không. Cách sửa là kiểm tra quyền sở hữu ở mỗi lần lấy dữ liệu.

Dùng mã khó đoán thay số thứ tự có đủ an toàn không?

Giúp giảm rủi ro nhưng không đủ. Mã có thể bị lộ qua nhiều đường. Vẫn phải kiểm tra quyền ở máy chủ cho mọi yêu cầu.

Nguyên tắc quyền tối thiểu là gì?

Là chỉ cấp cho mỗi người dùng và mỗi chương trình đúng những quyền cần thiết cho công việc của họ. Khi có sự cố, thiệt hại bị giới hạn trong phạm vi quyền đó.

Làm sao thử nghiệm lỗi phân quyền?

Đăng nhập bằng một người dùng và thử truy cập dữ liệu hoặc chức năng của người khác hoặc của vai trò cao hơn, bằng cách gọi thẳng yêu cầu. Kết quả đúng phải là bị từ chối.

Cần tư vấn cụ thể cho trường hợp của bạn?

Chúng tôi sẽ liên hệ trong vòng 24 giờ.

Đăng ký tư vấn ngay

Bài viết liên quan

Bạn cần hỗ trợ thêm?

Để lại thông tin, chúng tôi sẽ liên hệ trong 24 giờ.