Tôi có quá kỹ thuật không nếu tôi xem xét hành vi sai trái có chủ ý của người dùng?


12

Có quá kỹ thuật không nếu tôi thêm sự bảo vệ chống lại hành vi sai trái có chủ ý của người dùng (nói một cách nhẹ nhàng), nếu tác hại mà người dùng có thể phải chịu không liên quan đến mã của tôi?

Để làm rõ, tôi đang phơi bày một dịch vụ JSON RESTful đơn giản như thế này:

GET /items - to retrieve list of user's items
PUT /items/id - to modify an item
POST /items - to add a new item

Bản thân dịch vụ này không có nghĩa là được sử dụng qua một trình duyệt, mà chỉ từ các ứng dụng của bên thứ ba, được kiểm soát bởi người dùng (như ứng dụng điện thoại, ứng dụng máy tính để bàn, v.v.). Ngoài ra, bản thân dịch vụ nên không trạng thái (tức là không có phiên).

Việc xác thực được thực hiện với Xác thực cơ bản qua SSL.

Tôi đang nói về một hành vi "có hại" như thế này:

Người dùng nhập url GET trong trình duyệt (không có lý do nào ngoài ...). Trình duyệt yêu cầu Auth cơ bản, xử lý nó và lưu trữ auth cho phiên duyệt hiện tại. Không đóng trình duyệt, người dùng truy cập trang web độc hại, có javascript CSRF / XSRF độc hại tạo POST cho dịch vụ của chúng tôi.

Kịch bản trên rất khó xảy ra và tôi biết rằng từ góc độ kinh doanh, tôi không nên quá lo lắng. Nhưng để cải thiện tình hình, bạn có nghĩ rằng nếu tên người dùng / mật khẩu được yêu cầu trong dữ liệu JSON POST cũng sẽ giúp ích?

Hoặc tôi nên bỏ Basic Auth hoàn toàn, loại bỏ GET và chỉ sử dụng POST / PUT với thông tin ủy quyền trong đó? Vì thông tin lấy được máng GET cũng có thể nhạy cảm.

Mặt khác, việc sử dụng các tiêu đề tùy chỉnh có được coi là triển khai REST thuần túy không? Tôi có thể thả Auth cơ bản và sử dụng các tiêu đề tùy chỉnh. Bằng cách đó, ít nhất có thể tránh được cuộc tấn công CSRF từ trình duyệt và các ứng dụng sử dụng dịch vụ sẽ đặt tên người dùng / mật khẩu trong thạch cao tùy chỉnh. Điều tồi tệ cho phương pháp này là, hiện tại dịch vụ không thể được sử dụng từ trình duyệt.


3
Cũng như với câu trả lời của tôi, tôi cũng muốn để lại tuyên bố này, tôi nghĩ rằng điều này có lẽ sẽ được trả lời tốt hơn trên SO hoặc Security
Jeff Langemeier

1
Tôi nghĩ rằng bạn đã chuyển PUT và POST theo định nghĩa của RFC 2616 ( tools.ietf.org/html/rfc2616#section-9.5 ).
Svante

Câu trả lời:


6

Quá kỹ thuật? Không có gì. Các biện pháp chống XSRF là một phần cần thiết của bất kỳ ứng dụng hoặc dịch vụ web an toàn nào. Nó có thể hoặc không phải là một người cực kỳ khó tin mà ai đó sẽ chọn để tấn công bạn, nhưng điều đó không làm cho phần mềm của bạn không an toàn.

Các hệ thống thường bị tấn công khi sử dụng XSRF và mặc dù kết quả ít ngay lập tức - rõ ràng là xấu hơn so với SQL-tiêm hoặc XSS, nhưng chúng đủ tệ để thỏa hiệp tất cả các tính năng tương tác với người dùng.

Điều đó không có nghĩa là bạn không thể có giao diện RESTful tinh khiết trong đó các tham số duy nhất là thuộc tính của chính cuộc gọi. Bạn phải bao gồm một cái gì đó trong yêu cầu mà kẻ tấn công không thể đoán. Đó có thể là cặp mật khẩu tên người dùng, nhưng đó là sự lựa chọn duy nhất có thể. Bạn có thể có tên người dùng cùng với mã thông báo được tạo từ hàm băm của mật khẩu. Bạn có thể có mã thông báo do chính dịch vụ phát hành tại thời điểm xác thực (có thể được ghi nhớ trong phiên hoặc được xác minh bằng mật mã).

tôi có nên thoát khỏi GET

Không, các yêu cầu GET được sử dụng cho các yêu cầu đọc không có hoạt động viết chủ động (chúng là Id idototent). Nó chỉ ghi các hoạt động yêu cầu bảo vệ XSRF.


Điều gì xảy ra nếu yêu cầu GET có thể tiết lộ thông tin nhạy cảm?
Nắng

@Sunny: Bạn đang xem xét dữ liệu nhạy cảm là gì?
Chris

2
Chris, nếu tôi bị hoang tưởng, mọi dữ liệu đều nhạy cảm, nếu người dùng "sai" nhận được :). Lý thuyết của nó.
Nắng

xin vui lòng, xem lại những thay đổi trong câu hỏi tôi đã thêm.
Nắng

1
Sẽ tốt cho phản hồi (dù là GET hay phương pháp khác) chỉ chứa dữ liệu mà người dùng sẽ thấy. Một cuộc tấn công XSRF chỉ cho phép kẻ tấn công yêu cầu người dùng đưa ra một yêu cầu cụ thể, nó không cho phép họ đọc phản hồi từ yêu cầu đó. Trừ khi tập lệnh đích được xây dựng theo cách đặc biệt để cho phép các trang của bên thứ ba đọc nó từ <script>thẻ, hoặc cố tình ( JSON JSONP Hồi) hoặc vô tình ( JSON không được bảo vệ ).
bobince

32

Không bao giờ tin bất cứ điều gì. Mỗi yêu cầu là một cuộc tấn công. Mỗi người dùng là một hacker. Nếu bạn phát triển với tư duy này, ứng dụng của bạn sẽ an toàn hơn, ổn định hơn và ít có khả năng bị tấn công bởi người dùng độc hại. Tất cả chỉ cần một người thông minh tìm cách bảo mật cho bạn để gặp rắc rối nghiêm trọng với dữ liệu của bạn (một trong những tài nguyên quý giá nhất của bạn ).

Nếu bạn đã xác định lỗ hổng bảo mật trong ứng dụng của mình, hãy làm mọi thứ bạn nghĩ bạn cần làm để cắm lỗ hổng. API của bạn, đặc biệt, phải là phần mềm không đáng tin cậy nhất trong sự tồn tại. Tôi sẽ yêu cầu thông tin đăng nhập và đi với yêu cầu Đăng.


4
YAY cho hoang tưởng! Bạn có kẻ thù! (Và +1 cho mỗi yêu cầu là một cuộc tấn công )
Treb

0

Nếu mã được thiết lập và duy trì, các trường hợp cạnh nên được xem xét và xử lý trên cơ sở từng trường hợp.

CỐ ĐỊNH ĐẾN MỘT SỐ L ERI TRÊN PHẦN CỦA TÔI:

GET vẫn nên được sử dụng như một phần của dịch vụ RESTful thích hợp, xác thực cần phải có trong mọi trường hợp. Điều tôi cố gắng phỏng đoán là vì mục đích bảo mật, GET giống như POST nhưng bài đăng hoạt động mà không đưa thông tin vào thanh địa chỉ, có xu hướng là sự khác biệt lớn về bảo mật (và tại sao tôi không thích GET), nhưng như được đăng bởi @Lee,

GET requests are used to retrieve resources, and PUT/POST are used to add/update 
resources so it would be completely against expectations for a RESTful API to use
PUT/POST to get data. 

Vì ứng dụng này của bên thứ ba sẽ được sử dụng, nên người ta phải tuân theo các thực tiễn tốt cho dịch vụ RESTful để người thực hiện cuối sẽ không bị nhầm lẫn trong phần này.


3
GET khác với POST về mặt bảo mật như thế nào? Cả hai đều được gửi đơn giản qua vận chuyển (HTTP hoặc HTTPS), sự khác biệt duy nhất là chuỗi truy vấn GET được hiển thị trên thanh địa chỉ.
tdammers

1
@Sunny: POST cũng được hiển thị như GET về vấn đề này. Bật telnet và nói chuyện với máy chủ web nếu bạn không tin tôi.
tdammers

1
@Jeff: Lý do tôi đưa lên telnet (hoặc curl, wget hoặc một sniffer kiểu cũ tốt) là vì nó cho phép bạn xem luồng dữ liệu đầy đủ. Có, HTTPS ẩn thông tin này khỏi những kẻ nghe trộm, nhưng bất kỳ ai ở hai đầu của kết nối SSL đều có thể thấy chính xác những gì telnet nhìn thấy.
tdammers

1
@Jeremy: POST không hiển thị các tham số trong thanh địa chỉ, nhưng vì dữ liệu giống như hiển thị trong luồng HTTP thực tế, nên bạn hoàn toàn đúng.
tdammers

7
Các yêu cầu GET được sử dụng để truy xuất tài nguyên và PUT / POST được sử dụng để thêm / cập nhật tài nguyên, do đó sẽ hoàn toàn trái với mong đợi cho API RESTful sử dụng PUT / POST để lấy dữ liệu.
Lee

0

Bạn nên xem xét tất cả các tình huống có thể xảy ra, bao gồm cả người dùng đang tích cực độc hại và (thành công) đảo ngược mọi rào cản "bảo mật bằng cách che khuất".

Nhưng đồng thời, bạn nên đánh giá tác động của một vụ hack thành công và khả năng xảy ra một nỗ lực. Ví dụ:

  • Một dịch vụ nội bộ được bảo vệ bởi một tường lửa vững chắc sẽ ít bị tấn công hơn một dịch vụ trên internet công cộng.

  • Tác động của việc ai đó gỡ xuống một diễn đàn thảo luận khách hàng ít hơn tác động của việc họ đánh cắp thẻ tín dụng của khách hàng.


Quan điểm của tôi là "bảo mật toàn diện" là "vô cùng đắt đỏ" ... và thực tế không thể thực hiện được. Tốt nhất là bạn nên đưa ra quyết định về nơi vẽ đường dựa trên phân tích lợi ích chi phí kỹ lưỡng.


Cảm ơn. Câu hỏi không phải là về việc bảo vệ "khỏi" người dùng, mà là bảo vệ chính người dùng nếu họ hành động vô trách nhiệm. Nhưng câu trả lời của bạn làm cho vài điểm tốt.
Nắng
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.