Cross-origin resource sharing (CORS)
Last updated
Last updated
Cross-origin resource sharing (CORS) là một cơ chế trình duyệt cho phép truy cập tới nhiều tài nguyên khác nhau(như JavaScript, fonts, ...) từ các domain khác với domain của trang đó.
Nó mở rộng và thêm tính linh hoạt cho SOP. Tuy nhiên, nó cũng tiềm ẩn nguy cơ xảy ra các cuộc tấn công giữa các doamin nếu chính sách CORS của trang web được định cấu hình và triển khai yếu. CORS không phải là biện pháp bảo vệ chống lại các cuộc tấn công cross-origin, chẳng hạn như giả mạo yêu cầu trên nhiều trang web (CSRF).
Các bạn có thể đọc một bài mình research SOP ở đây
Access-Control-Allow-Origin
header được bao gồm response từ một website tới một request gốc từ một website khác và xác định nguồn gốc được permit của request. Trình duyệt web so sánh Access-Control-Allow-Origin
với request gốc của trang web và cho phép truy cập tới response nếu chúng khớp.
Cross-origin resource sharing (CORS) quy định rõ ràng nội dung header giữa các web servers và các trình duyệt mà hạn chế origin cho tài nguyên web request ngồi domain gốc. Đặc tả của CORS xác định rõ một tập hợp các header của giao thức trong đó Access-Control-Allow-Origin là quan trọng nhất. Những cái header này được return bởi một server khi một website requests một cross-doamin resource với một Origin header được thêm vào trình duyệt.
Ví dụ: Giả sử một website với miền gốc: shang.com thực hiện một cross-domain request sau:
Server ở sha1vu.com trả về response sau:
Khi đó trình duyệt sẽ cho phép code chạy trên shang.com được truy cập tới response bởi vì Origin khớp nhau.
Đặc tả của Access-Control-Allow-Origin cho phép nhiều origin(multiple) hoặc giá trị null hoặc ký tự đại diện * . Tuy nhiên không trình duyệt hỗ trợ multiple origin và có những hạn chế về việc sử dụng ký tự đại diện * .
Hành vi mặc định của request cross-origin resource là request được pass mà không xác đinh như cookies và Authorization header. Tuy nhiên cross-domain server có thể cho phép đọc phản hồi khi thông tin xác thực được pass tới nó bởi setting của CORS Access-Control-Allow-Credentials
header là true. Bây giờ nếu request của website sử dụng JS để trình bày rằng nó đang gửi cookie ở request:
Và response tới request là:
Sau đó trình duyệt sẽ cho phép request của website đọc response, bởi vì Access-Control-Allow-Credentials
response header được set là: true
The header Access-Control-Allow-Origin
hỗ trợ ký tự đại diện.
Ví dụ:
Ghi chú rằng ký tự đại diện có thể không được sử dụng với bất kỳ giá trị nào. Ví dụ header sau đây không hợp lệ:
Access-Control-Allow-Origin:
https://*.normal-website.com
Từ góc độ bảo mật, việc sử dụng ký tự đại diện bị hạn chế trong đặc điểm kỹ thuật vì bạn không thể kết hợp ký tự đại diện với cross-origin việc chuyển giao thông tin xác thực (xác thực, cookie hoặc chứng chỉ phía khách hàng). Do đó, cross-domain server response của form:
Không được phép vì điều này sẽ không an toàn, hiển thị bất kỳ nội dung xác thực nào trên trang web mục tiêu cho mọi người.
Với các ràng buộc này, một số máy chủ Web tự động tạo ra các Access-Control-Allow-Origin
header dựa trên the client-specified origin. Đây là một cách giải quyết cho các ràng buộc CORS không an toàn.
Pre-flight checks đã được thêm vào đặc tả CORS để bảo vệ tài nguyên kế thừa khỏi các tùy chọn yêu cầu mở rộng được CORS cho phép.
Trong một số trường hợp nhất định, khi yêu cầu từ cross-domain bao gồm phương pháp HTTP hoặc tiêu đề non-standard, cross-origin requests được đi trước bởi một yêu cầu sử dụng OPTIONS
method và CORS protocol cần phải kiểm tra method và header nào được cho phép trước khi cho phép cross-origin request. Đây được gọi là Prefligh Check. Server sẽ trả về một danh sách các method được phép ngoài origin đáng tin cậy và kiểm tra trình duyệt để xem liệu method của trang web yêu cầu có được phép không.
Ví dụ: đây là yêu cầu trước chuyến bay đang tìm cách sử dụng phương thức này cùng với tiêu đề yêu cầu tùy chỉnh được gọi làPUT
Special-Request-Header
:
Server sẽ trả về response như sau:
Response này set các method được cho phép (PUT
, POST
và OPTIONS
) và các request header được phép (Special-Request-Header). Trong trường hợp cụ thể này, Cross-domain server cũng cho phép gửi thông tin đăng nhập và Access-Control-Max-Age header
xác định khung thời gian tối đa để lưu trữ pre-flight response
để sử dụng lại. Nếu các request methods và headers được cho phép (như trong ví dụ này) thì trình duyệt sẽ xử lý cross-origin request theo cách thông thường. Pre-flight
sẽ thêm một extra HTTP request vào cross-domain request.
CORS không cũng cấp bảo vệ khỏi tấn công CSRF, đây là một nhận định sai lầm.
CORS là được kiểm soát nới lỏng SOP, do đó CORS được cấu hình kém/yếu thực sự có thể làm tăng khả năng tấn công CSRF.
Có nhiều cách khác nhau để thực hiện các cuộc tấn công CSRF mà không cần sử dụng CORS, bao gồm các hình thức HTML đơn giản và bao gồm cross-domain resource.
Nhiều trang web hiện đại sử dụng CORS để cho phép truy cập từ các domain phụ và các bên thứ ba đáng tin cậy. Việc thực hiện CORS của họ có thể chứa lỗi hoặc chắc chắn đảm bảo rằng mọi thứ hoạt động bình thường và điều này có thể dẫn đến các lỗ hổng có thể khai thác. (Lỗ hổng phát sinh từ các vấn đề cấu hình CORS)\
Một số ứng dụng cần cung cấp quyền truy cập vào một số domain khác. Duy trì danh sách các doamin được phép yêu cầu nỗ lực không ngừng và bất kỳ sai sót nào cũng có nguy cơ phá vỡ chức năng. Vì vậy, một số ứng dụng sử dụng con đường dễ dàng để cho phép truy cập hiệu quả từ bất kỳ miền nào khác.
Một cách để thực hiện việc này là đọc Origin header từ các yêu cầu và bao gồm response header cho biết request origin được cho phép.
Ví dụ: hãy xem xét một ứng dụng nhận được request sau:
Sau đó nó respond với:
Các header này cho biết rằng quyền truy cập được cho phép từ domain yêu cầu (malicious-website.com
) và các yêu cầu trên nhiều origin có thể bao gồm cookie (Access-Control-Allow-Credentials: true
) và do đó sẽ được xử lý trong session.
Bởi vì ứng dụng reflect origin tùy ý trong Access-Control-Allow-Origin
header, điều này có nghĩa là hoàn toàn bất kỳ miền nào cũng có thể truy cập tài nguyên từ domain vuln. Nếu response chứa bất kỳ thông tin nhạy cảm nào như API key hoặc token CSRF, bạn có thể truy xuất điều này bằng cách chạy script sau trên trang web của bạn:
Một số ứng dụng hỗ trợ quyền truy cập từ nhiều nguồn gốc làm như vậy bằng cách sử dụng danh sách trắng có nguồn gốc được phép. Khi nhận được yêu cầu CORS, nguồn gốc được cung cấp được so sánh với danh sách trắng. Nếu nguồn gốc xuất hiện trên danh sách trắng thì nó được phản ánh trong tiêu đề có nguồn gốc kiểm soát truy cập để truy cập được cấp. Ví dụ: ứng dụng nhận được một yêu cầu bình thường như:
Ứng dụng kiểm tra Origin dựa trên list of origin được phép của nó và, nếu nó nằm trong danh sách, reflect origin như sau:
Các lỗi thường phát sinh khi triển khai whitelists CORS Orgin. Một số tổ chức quyết định cho phép truy cập từ tất cả các domain phụ của họ (bao gồm cả những subdomain chưa tồn tại trong tương lai). Và một số ứng dụng cho phép truy cập từ nhiều domain của các tổ chức khác bao gồm cả domain phụ của họ. Các quy tắc này thường được triển khai bằng cách khớp các tiền tố hoặc hậu tố URL hoặc sử dụng các biểu thức thông thường. Bất kỳ lỗi nào trong quá trình triển khai đều có thể dẫn đến việc cấp quyền truy cập cho các miền bên ngoài ngoài ý muốn.
Note: Các tổ chức hay các Group tập đoàn thường sẽ dùng một domain chính và từ đó chia ra các subdomain cho các mục đích khác mà họ cho phép các subdomain của ứng dụng đó có thể truy cập tới tài nguyên gốc như là shang.vn thì blog.shang.vn cũng có thể truy cập tài nguyên gốc nhưng nếu hacker.shang.com thì cũng có thể...
Ví dụ: giả sử một ứng dụng cấp truy cập cho toàn bộ domain kết thúc bằng:
Kẻ tấn công có thể chiếm được truy cập bằng cách đăng ký domain kiểu như này:
Ngoài ra nếu ứng dụng cấp truy cập cho toàn bộ domain có bắt đầu bằng:
Kẻ tấn công có thể chiếm được truy cập bằng cách đăng ký domain kiểu như này:
Thông số kỹ thuật cho Header Origin trợ giá trị . Các trình duyệt có thể gửi giá trị trong Origin header trong các tình huống bất thường khác nhau: null null
Cross-origin redirects.
Requests from serialized data.
Request using the protocol. file:
Sandboxed cross-origin requests.
Một số ứng dụng có thể đưa ra whitelist có orgin để hỗ trợ phát triển địa phương của ứng dụng.
Ví dụ: Giả sử một ứng dụng nhận được yêu cầu có nguồn gốc chéo sau: null
Và server respond sẽ như này:
Trong tình huống này, kẻ tấn công có thể sử dụng các thủ thuật khác nhau để tạo yêu cầu có nguồn gốc chéo có chứa giá trị trong tiêu đề gốc. Điều này sẽ đáp ứng danh sách trắng, dẫn đến truy cập tên miền chéo.
Ví dụ: điều này có thể được thực hiện bằng cách sử dụng một sandboxed cross-origin request của form: null iframe
Ngay cả CORS được định cấu hình "correctly" cũng thiết lập mối quan hệ tin cậy giữa hai nguồn gốc. Nếu một trang web tin tưởng một nguồn gốc dễ bị tấn công bởi tập lệnh chéo trang (XSS), thì kẻ tấn công có thể khai thác XSS để tiêm một số JavaScript sử dụng CORS để truy xuất thông tin nhạy cảm từ trang web tin cậy ứng dụng dễ bị tấn công.
Cho một request như sau:
Nếu server phản hồi như này:
Sau đó kẻ tấn công tìm lỗ hổng XSS để có thể trộm API Key, url nó sẽ như sau:subdomain.vulnerable-website.com
Giả sử một ứng dụng sử dụng nghiêm ngặt HTTPS cũng danh sách trắng là một tên miền phụ đáng tin cậy đang sử dụng HTTP đơn giản.
Ví dụ: khi ứng dụng nhận được yêu cầu sau:
Ứng dụng respond như này:
Trong tình huống này, một kẻ tấn công có thể chặn lưu lượng truy cập của người dùng nạn nhân có thể khai thác cấu hình CORS để thỏa hiệp sự tương tác của nạn nhân với ứng dụng. Cuộc tấn công này liên quan đến các bước sau:
Người dùng sửa dụng bất kỳ HTTP request nào
Kẻ tấn công sẽ inject một redirection tới: http://trusted-subdomain.vulnerable-website.com
Trình duyệt của nạn nhân sẽ follow chuyển hướng:
Kẻ tấn công chặn HTTP request đơn giản và return một response giả mạo chứ một CORS request tới: https://vulnerable-website.com
Trình duyệt nạn nhân sẽ tạo CORS request bao gồm origin: http://trusted-subdomain.vulnerable-website.com
Ứng dụng cho phép request vì đây là a whitelisted origin. Dữ liệu nhạy cảm được được trả về trong response.
Trang giả mạo của kẻ tấn công có thể đọc dữ liệu nhạy cảm và truyền dữ liệu đó đến bất kỳ domain nào dưới sự kiểm soát của kẻ tấn công.
Cuộc tấn công này có hiệu quả ngay cả khi trang web dễ bị tấn công mạnh mẽ trong việc sử dụng HTTPS, không có endpoint HTTP và tất cả các cookie được gắn flag là an toàn.
Hầu hết tấn công CORS dựa vào sự hiện diện của header response:
Nếu không có header đó, trình duyệt của người dùng nạn nhân sẽ từ chối gửi cookie của họ, có nghĩa là kẻ tấn công sẽ chỉ có quyền truy cập vào nội dung không xác thực mà họ có thể dễ dàng truy cập bằng cách duyệt trực tiếp vào trang web đích.
Tuy nhiên, có một tình huống phổ biến trong đó kẻ tấn công không thể truy cập trực tiếp vào một trang web: khi đó là một phần của mạng nội bộ của tổ chức và nằm trong không gian địa chỉ IP riêng tư. Các trang web nội bộ thường được giữ ở một tiêu chuẩn bảo mật thấp hơn so với các trang web bên ngoài, cho phép kẻ tấn công tìm thấy các lỗ hổng và truy cập thêm.
Ví dụ: Cross-origin request trong mạng private có thể như sau:
Server tra về:
Máy chủ ứng dụng đang trust các yêu cầu tài nguyên từ bất kỳ origin nào mà không cần thông tin đăng nhập. Nếu người dùng trong không gian địa chỉ IP riêng tư truy cập Internet công khai thì có thể thực hiện cuộc tấn công dựa trên CORS từ trang web bên ngoài sử dụng trình duyệt của nạn nhân làm proxy để truy cập tài nguyên mạng nội bộ.
Các lỗ hổng CORS phát sinh chủ yếu dưới dạng cấu hình sai. Do đó, phòng ngừa là một vấn đề cấu hình. Các phần sau đây mô tả một số biện pháp phòng thủ hiệu quả chống lại các cuộc tấn công CORS.
Nếu một tài nguyên web chứa thông tin nhạy cảm, nguồn gốc phải được chỉ định đúng trong header: Access-Control-Allow-Origin
Nó có vẻ hiển nhiên nhưng Origin được chỉ định trong header chỉ nên là các trang web đáng tin cậy. Đặc biệt, việc reflect orgin từ các cross-origin requests mà không cần xác thực có thể dễ dàng khai thác và nên tránh. Access-Control-Allow-Origin
Tránh sử dụng header . Cross-origin resource gọi từ các tài liệu nội bộ và sandboxed requests có thể chỉ định Origin. CORS header nên được xác định đúng đối với Origin đáng tin cậy cho các máy chủ riêng và công cộng. Access-Control-Allow-Origin: null null
Tránh sử dụng ký tự đại diện trong mạng nội bộ. Chỉ tin tưởng cấu hình mạng để bảo vệ tài nguyên nội bộ là không đủ khi các trình duyệt nội bộ có thể truy cập các domain bên ngoài không đáng tin cậy.
CORS xác định các hành vi của trình duyệt và không bao giờ thay thế cho việc bảo vệ dữ liệu nhạy cảm phía máy chủ - kẻ tấn công có thể trực tiếp giả mạo yêu cầu từ bất kỳ nguồn đáng tin cậy nào. Do đó, máy chủ web nên tiếp tục áp dụng các biện pháp bảo vệ đối với dữ liệu nhạy cảm, chẳng hạn như authentication và session management, ngoài CORS được định cấu hình đúng.
______________________________________________Hết___________________________________________________