Những rủi ro bảo mật khi đặt Access-Control-Allow-Origin là gì?


124

Gần đây, tôi đã phải đặt thành Access-Control-Allow-Originđể *có thể thực hiện lệnh gọi ajax giữa nhiều miền phụ.
Bây giờ tôi không thể không cảm thấy rằng tôi đang đặt môi trường của mình vào những rủi ro bảo mật.
Xin hãy giúp tôi nếu tôi làm sai.

Câu trả lời:


69

Bằng cách phản hồi với Access-Control-Allow-Origin: *, tài nguyên được yêu cầu cho phép chia sẻ với mọi nguồn gốc. Về cơ bản, điều này có nghĩa là bất kỳ trang web nào cũng có thể gửi yêu cầu XHR đến trang web của bạn và truy cập phản hồi của máy chủ, điều này sẽ không xảy ra nếu bạn không triển khai phản hồi CORS này.

Vì vậy, bất kỳ trang web nào cũng có thể thay mặt khách truy cập yêu cầu trang web của bạn và xử lý phản hồi của trang web đó. Nếu bạn đã triển khai thứ gì đó như kế hoạch xác thực hoặc ủy quyền dựa trên thứ gì đó được trình duyệt tự động cung cấp (cookie, phiên dựa trên cookie, v.v.), thì các yêu cầu do các trang web của bên thứ ba kích hoạt cũng sẽ sử dụng chúng.

Điều này thực sự gây ra rủi ro bảo mật, đặc biệt nếu bạn cho phép chia sẻ tài nguyên không chỉ cho các tài nguyên đã chọn mà cho mọi tài nguyên. Trong bối cảnh này, bạn nên xem Khi nào là an toàn để kích hoạt CORS? .


2
Nếu bạn có thể đưa ra một ví dụ cụ thể về cách truy cập xác thực được chia sẻ gây ra rủi ro bảo mật, tôi sẽ ủng hộ điều này.
Petrus Theron

1
@Gumbo Nội dung tĩnh thì sao? (ví dụ: nội dung cdn tĩnh, chẳng hạn như javascrip, css, htmls tĩnh, v.v.) Có bất kỳ vấn đề bảo mật nào khi thiết lập Access-Control-Allow-Origin: *chúng không? Sẽ không có nogin, vv, chúng được công khai cho tất cả mọi người?
Umut Benzer

2
@UmutBenzer Không sao cả.
Gumbo

25
Trên thực tế câu trả lời này không hoàn toàn đúng theo tiêu chuẩn CORS hiện tại : "Chuỗi '*' không thể được sử dụng cho tài nguyên hỗ trợ thông tin xác thực." Vì vậy, bạn không thể buộc yêu cầu sử dụng xác thực tạm thời dưới dạng cookie, xác thực HTTP được lưu trong bộ nhớ cache hoặc chứng chỉ SSL ứng dụng khách. Tuy nhiên, nếu ví dụ trang web sử dụng bộ nhớ cục bộ để xác thực, thì đó sẽ là một vấn đề.
Niklas B.

2
@NiklasB: Tôi đã thử kịch bản này và Chrome tuân theo tiêu chuẩn CORS như bạn đã đề cập. tức là chuỗi " " không được hỗ trợ với yêu cầu thông tin xác thực. Đây là những gì được Chrome báo cáo: "XMLHttpRequest không thể tải localhost: 12346 / hello . Không thể sử dụng ký tự đại diện ' ' trong tiêu đề 'Access-Control-Allow-Origin' khi cờ thông tin xác thực là true. Nguồn gốc ' localhost: 12345 ' do đó không được phép truy cập. Chế độ thông tin xác thực của một XMLHttpRequest được kiểm soát bởi thuộc tính withCredentials. "
factotum

37

Access-Control-Allow-Origin: *hoàn toàn an toàn để thêm vào bất kỳ tài nguyên nào, trừ khi tài nguyên đó chứa dữ liệu riêng tư được bảo vệ bởi thứ gì đó ngoài thông tin xác thực tiêu chuẩn (cookie, xác thực cơ bản, chứng chỉ ứng dụng khách TLS).

Vd: Dữ liệu được bảo vệ bởi cookie là an toàn

Hãy tưởng tượng https://example.com/users-private-data, điều này có thể làm lộ dữ liệu riêng tư tùy thuộc vào trạng thái đăng nhập của người dùng. Trạng thái này sử dụng cookie phiên. Thật an toàn để thêm Access-Control-Allow-Origin: *vào tài nguyên này, vì tiêu đề này chỉ cho phép truy cập vào phản hồi nếu yêu cầu được thực hiện mà không có cookie và cần có cookie để lấy dữ liệu cá nhân. Kết quả là không có dữ liệu riêng tư nào bị rò rỉ.

Ví dụ: Dữ liệu được bảo vệ bởi vị trí / ip / mạng nội bộ không an toàn (rất tiếc là phổ biến với mạng nội bộ và thiết bị gia dụng):

Hãy tưởng tượng https://intranet.example.com/company-private-data, điều này làm lộ dữ liệu của công ty tư nhân, nhưng điều này chỉ có thể được truy cập nếu bạn đang sử dụng mạng wifi của công ty. Không an toàn khi thêm Access-Control-Allow-Origin: *vào tài nguyên này, vì nó được bảo vệ bằng cách sử dụng thứ gì đó khác với thông tin đăng nhập tiêu chuẩn. Nếu không, một tập lệnh xấu có thể sử dụng bạn như một đường hầm dẫn đến mạng nội bộ.

Quy tắc ngón tay cái

Hãy tưởng tượng người dùng sẽ thấy gì nếu họ truy cập tài nguyên trong cửa sổ ẩn danh. Nếu bạn hài lòng với việc mọi người nhìn thấy nội dung này (bao gồm cả mã nguồn mà trình duyệt nhận được), bạn có thể thêm vào Access-Control-Allow-Origin: *.


nên "vì nó chỉ cho phép các yêu cầu không có cookie" phải "vì nó chỉ cho phép các yêu cầu có cookie"?
DJCordhose

3
@DJCordhose không. Access-Control-Allow-Origin: *chỉ cho phép các yêu cầu mà không có cookie. Tôi đã chỉnh sửa câu trả lời để làm rõ một chút.
JaffaTheCake

Sự khác biệt giữa "*" và trường hợp không có tiêu đề này là gì. Nó giống nhau không?
Nigrimmist 25/09/19

Tôi rất thích nếu "Nếu không, một tập lệnh xấu có thể sử dụng bạn làm đường hầm dẫn đến mạng nội bộ" có thể được giải thích thêm.
Sam Rueby

@Nigrimmist Sau đó, yêu cầu preflight sẽ không thành công và quyền truy cập tài nguyên sẽ bị chặn
iamareebjamal

9

AFAIK, Access-Control-Allow-Origin chỉ là một tiêu đề http được gửi từ máy chủ đến trình duyệt. Giới hạn nó ở một địa chỉ cụ thể (hoặc vô hiệu nó) không làm cho trang web của bạn an toàn hơn, chẳng hạn như rô bốt. Nếu muốn, rô bốt có thể bỏ qua tiêu đề. Theo mặc định, các trình duyệt thông thường hiện có (Explorer, Chrome, v.v.) tôn trọng tiêu đề. Nhưng một ứng dụng như Postman chỉ đơn giản là bỏ qua nó.

Máy chủ không thực sự kiểm tra 'nguồn gốc' của yêu cầu khi nó trả về phản hồi. Nó chỉ thêm tiêu đề http. Đó là trình duyệt (đầu máy khách) đã gửi yêu cầu quyết định đọc tiêu đề kiểm soát truy cập và thực hiện theo nó. Lưu ý rằng trong trường hợp XHR, nó có thể sử dụng yêu cầu 'TÙY CHỌN' đặc biệt để yêu cầu các tiêu đề trước.

Vì vậy, bất kỳ ai có khả năng viết kịch bản sáng tạo đều có thể dễ dàng bỏ qua toàn bộ tiêu đề, bất cứ điều gì được thiết lập trong đó.

Xem thêm Các vấn đề bảo mật có thể xảy ra khi đặt Access-Control-Allow-Origin .


Bây giờ để thực sự trả lời câu hỏi

Tôi không thể không cảm thấy rằng tôi đang đặt môi trường của mình vào những rủi ro bảo mật.

Nếu ai đó muốn tấn công bạn, họ có thể dễ dàng vượt qua Access-Control-Allow-Origin. Nhưng bằng cách bật '*', bạn sẽ cung cấp cho kẻ tấn công thêm một vài 'vectơ tấn công', chẳng hạn như sử dụng các trình duyệt web thông thường tôn trọng tiêu đề HTTP đó.


6
Hãy nhìn điều này từ quan điểm của một người dùng cuối không thận trọng. Ai đó có thể thiết lập một trang web độc hại chèn JavaScript để chuyển dữ liệu giữa trang web thực và trang web độc hại (giả sử họ muốn lấy cắp mật khẩu của bạn). Trình duyệt web của người dùng cuối thường sẽ chặn giao tiếp trên nhiều trang web này, nhưng nếu Access-Control-Allow-Origin được đặt, thì nó sẽ được phép và người dùng cuối sẽ không ai khôn ngoan hơn.
Brain2000

3
Vâng, thiết lập Access-Control-Allow-Origin *trên một trang web độc hại mà host kịch bản để ăn cắp mật khẩu không được khuyến khích mạnh mẽ :-)
commonpike

6
@commonpike Bạn đúng ở chỗ ai đó có thể tạo tập lệnh để hoàn toàn bỏ qua tiêu đề. Nếu dữ liệu có thể truy cập được, dữ liệu đó có thể truy cập được có hoặc không có tiêu đề CORS. Có một vectơ tấn công khác mà bạn không xem xét. Giả sử tôi đăng nhập vào trang web của ngân hàng của mình. Nếu tôi đi đến một trang khác và sau đó quay lại ngân hàng của mình, tôi vẫn đăng nhập được vì có cookie. Những người dùng khác trên internet có thể truy cập cùng các URL tại ngân hàng của tôi như tôi làm, nhưng họ sẽ không thể truy cập vào tài khoản của tôi nếu không có cookie. Một cách hiệu quả nếu yêu cầu cross-nguồn gốc được cho phép, một trang web độc hại có thể mạo danh ...
Brad

5
@commonpike ... người dùng. Nói cách khác, bạn có thể chỉ truy cập trang web của tôi (thậm chí có thể là một trang web bình thường, không có gì đáng ngờ ... có thể đó là một trang web hợp pháp thực sự vừa bị xâm nhập!) Nhưng một số JavaScript khiến HTTP yêu cầu ngân hàng của bạn chuyển một số tiền vào tài khoản của tôi. Ngân hàng không biết sự khác biệt giữa yêu cầu từ các trang của mình hoặc yêu cầu từ các trang khác. Cả hai đều có cookie đó cho phép yêu cầu thành công.
Brad

3
@commonpike Hãy để tôi cung cấp cho bạn một ví dụ phổ biến hơn ... một ví dụ luôn xảy ra. Giả sử bạn có một bộ định tuyến gia đình thông thường, chẳng hạn như Linksys WRT54g hoặc thứ gì đó. Giả sử rằng bộ định tuyến cho phép các yêu cầu gốc chéo. Một tập lệnh trên trang web của tôi có thể thực hiện các yêu cầu HTTP đến các địa chỉ IP chung của bộ định tuyến (như 192.168.1.1) và định cấu hình lại bộ định tuyến của bạn để cho phép các cuộc tấn công. Nó thậm chí có thể sử dụng trực tiếp bộ định tuyến của bạn làm nút DDoS. (Hầu hết các bộ định tuyến đều có các trang kiểm tra cho phép ping hoặc kiểm tra máy chủ HTTP đơn giản. Những trang này có thể bị lạm dụng hàng loạt.)
Brad

7

Đây là 2 ví dụ được đăng dưới dạng nhận xét, khi ký tự đại diện thực sự có vấn đề:

Giả sử tôi đăng nhập vào trang web của ngân hàng của mình. Nếu tôi đi đến một trang khác và sau đó quay lại ngân hàng của mình, tôi vẫn đăng nhập được vì có cookie. Những người dùng khác trên internet có thể truy cập cùng các URL tại ngân hàng của tôi như tôi làm, nhưng họ sẽ không thể truy cập vào tài khoản của tôi nếu không có cookie. Nếu các yêu cầu có nguồn gốc chéo được cho phép, một trang web độc hại có thể mạo danh người dùng một cách hiệu quả.

- Brad

Giả sử bạn có một bộ định tuyến gia đình thông thường, chẳng hạn như Linksys WRT54g hoặc thứ gì đó. Giả sử rằng bộ định tuyến cho phép các yêu cầu gốc chéo. Một tập lệnh trên trang web của tôi có thể thực hiện các yêu cầu HTTP đến các địa chỉ IP chung của bộ định tuyến (như 192.168.1.1) và định cấu hình lại bộ định tuyến của bạn để cho phép các cuộc tấn công. Nó thậm chí có thể sử dụng trực tiếp bộ định tuyến của bạn làm nút DDoS. (Hầu hết các bộ định tuyến đều có các trang kiểm tra cho phép ping hoặc kiểm tra máy chủ HTTP đơn giản. Chúng có thể bị lạm dụng hàng loạt.)

- Brad

Tôi cảm thấy rằng những bình luận này đáng lẽ phải là câu trả lời, vì chúng giải thích vấn đề bằng một ví dụ thực tế.


8
Ngoại trừ điều này sẽ không hoạt động. "Không thể sử dụng chuỗi '*' cho tài nguyên hỗ trợ thông tin xác thực." w3.org/TR/cors/#resource-requests
bayo

@bayotop Làm cách nào để trình duyệt phân biệt giữa các trang yêu cầu xác thực và những trang có dữ liệu khác trong tiêu đề?
wedstrom

Sau khi đọc liên kết được cung cấp, có "cờ hỗ trợ thông tin đăng nhập" được sử dụng cho mục đích này. Nó dường như được thiết lập theo cách thủ công, vì vậy có lẽ nếu ai đó không biết cách thiết lập CORS chính xác thì họ cũng có thể mắc sai cờ này, vì vậy tôi tin rằng các lỗ hổng ở trên là có thể xảy ra.
wedstrom

2
@wedstrom Cờ được đặt bởi người đưa ra yêu cầu. Dù sao, các kịch bản trên là ví dụ về các cuộc tấn công CSRF. Việc cho phép nguồn gốc '*' sẽ không làm cho bạn dễ bị tổn thương hơn khi bạn đã như vậy (có thể một chút trong trường hợp hiếm hoi). Trong hầu hết các trường hợp, bạn có thể đưa ra yêu cầu xuyên trang độc hại bằng cách sử dụng các biểu mẫu để CORS không thành vấn đề. Trong trường hợp bạn cần thực hiện yêu cầu AJAX, các yêu cầu trước chuyến bay sẽ được thực hiện (đây là điểm mà trình duyệt xuất hiện khi ACAO: '*' và Access-Control-Allow-Credentials: 'true').
bayo

0

Trong trường hợp máy chủ cố gắng vô hiệu hóa hoàn toàn CORS bằng cách đặt bên dưới tiêu đề.

  • Access-Control-Allow-Origin: * (cho trình duyệt biết rằng máy chủ chấp nhận các yêu cầu trang web chéo từ bất kỳ NGUỒN GỐC nào)

  • Access-Control-Allow-Credentials: true (cho trình duyệt biết rằng các yêu cầu trên nhiều trang web có thể gửi cookie)

Có một lỗi an toàn được triển khai trong các trình duyệt sẽ dẫn đến lỗi bên dưới

"Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’"

Vì vậy, trong hầu hết các trường hợp, đặt 'Access-Control-Allow-Origin' thành *sẽ không thành vấn đề. Tuy nhiên, để bảo mật trước các cuộc tấn công, máy chủ có thể duy trì danh sách các nguồn gốc được phép và bất cứ khi nào máy chủ nhận được yêu cầu nguồn gốc chéo, nó có thể xác thực tiêu đề GỐC so với danh sách các nguồn gốc được phép và sau đó lặp lại như cũ trong Access-Control-Allow-Origin đầu trang.

Vì tiêu đề ORIGIN không thể thay đổi bằng javascript chạy trên trình duyệt, trang web độc hại sẽ không thể giả mạo nó.

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.