Làm thế nào để cookie HTTPOnly hoạt động với các yêu cầu AJAX?


195

JavaScript cần quyền truy cập vào cookie nếu AJAX được sử dụng trên một trang web có các hạn chế truy cập dựa trên cookie. Cookie httpOnly có hoạt động trên trang AJAX không?

Chỉnh sửa: Microsoft đã tạo ra một cách để ngăn chặn các cuộc tấn công XSS bằng cách không cho phép truy cập JavaScript vào cookie nếu chỉ định httpOnly. FireFox sau đó đã thông qua này. Vì vậy, câu hỏi của tôi là: Nếu bạn đang sử dụng AJAX trên một trang web, như StackOverflow, thì cookie chỉ là một tùy chọn?

Chỉnh sửa 2: Câu hỏi 2. Nếu mục đích của HttpOnly là ngăn chặn truy cập JavaScript vào cookie và bạn vẫn có thể truy xuất cookie thông qua JavaScript thông qua XmlHttpRequest Object, điểm của HTTPOnly là gì?

Chỉnh sửa 3: Đây là một trích dẫn từ Wikipedia:

Khi trình duyệt nhận được một cookie như vậy, nó được cho là sử dụng nó như bình thường trong các trao đổi HTTP sau đây, nhưng không hiển thị cho các tập lệnh phía máy khách. [32] Các HttpOnlycờ không phải là một phần của tiêu chuẩn nào, và không được thực hiện trong tất cả các trình duyệt. Lưu ý rằng hiện tại không có ngăn chặn đọc hoặc ghi cookie phiên thông qua XMLHTTPRequest. [33].

Tôi hiểu rằng document.cookienó bị chặn khi bạn sử dụng HttpOnly. Nhưng dường như bạn vẫn có thể đọc các giá trị cookie trong đối tượng XMLHttpRequest, cho phép XSS. Làm thế nào để HTTPOnly làm cho bạn an toàn hơn? Bằng cách làm cho cookie về cơ bản chỉ đọc?

Trong ví dụ của bạn, tôi không thể viết thư cho bạn document.cookie, nhưng tôi vẫn có thể đánh cắp cookie của bạn và đăng nó lên miền của tôi bằng cách sử dụng đối tượng XMLHttpRequest.

<script type="text/javascript">
    var req = null;
    try { req = new XMLHttpRequest(); } catch(e) {}
    if (!req) try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
    if (!req) try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
    req.open('GET', 'http://stackoverflow.com/', false);
    req.send(null);
    alert(req.getAllResponseHeaders());
</script>

Chỉnh sửa 4: Xin lỗi, tôi có nghĩa là bạn có thể gửi XMLHttpRequest đến miền StackOverflow và sau đó lưu kết quả của getAllResponseHeaders () vào một chuỗi, thoát khỏi cookie và sau đó đăng nó lên một miền bên ngoài. Có vẻ như Wikipedia và ha.cker đồng tình với tôi về điều này, nhưng tôi rất thích được giáo dục lại ...

Chỉnh sửa cuối cùng: Ahh, rõ ràng cả hai trang web đều sai, đây thực sự là một lỗi trong FireFox . IE6 & 7 thực sự là các trình duyệt duy nhất hiện hỗ trợ đầy đủ cho HTTPOnly.

Để nhắc lại mọi thứ tôi đã học:

  • HttpOnly giới hạn tất cả quyền truy cập vào document.cookie trong IE7 & và FireFox (không chắc chắn về các trình duyệt khác)
  • HttpOnly xóa thông tin cookie khỏi các tiêu đề phản hồi trong XMLHttpObject.get ALLResponseHeaders () trong IE7.
  • XMLHttpObjects chỉ có thể được gửi đến tên miền mà chúng có nguồn gốc, do đó không có đăng tải tên miền chéo của cookie.

chỉnh sửa: Thông tin này có thể không còn được cập nhật.


Tôi đã đưa ra ví dụ của bạn trong một tập lệnh greasemonkey và có vẻ như FF không còn hiển thị cookie. Nghiên cứu và ví dụ tuyệt vời.

Có thể với Chính sách nguồn gốc tương tự, bạn không thể thực hiện một yêu cầu http đến một tên miền không giống với tập lệnh đang chạy; tuy nhiên, tôi tin rằng bạn có thể dễ dàng chuyển cookie bằng cách chuyển hướng người dùng đến một trang bằng window.location và truyền thông tin qua các tham số chuỗi truy vấn.
Luca Marzi

@LucaMarzi " bạn không thể thực hiện một yêu cầu http đến một tên miền không giống với tập lệnh đang chạy trong " Bạn có nói rằng một trang web X không thể bao gồm một hình ảnh từ máy chủ Y không? (một tính năng đã được tất cả các trình duyệt hỗ trợ kể từ khảm?)
tò mò vào

Câu trả lời:


64

Có, cookie chỉ HTTP sẽ ổn cho chức năng này. Họ vẫn sẽ được cung cấp yêu cầu của XmlHttpRequest đến máy chủ.

Trong trường hợp Stack Overflow, cookie sẽ tự động được cung cấp như một phần của yêu cầu XmlHttpRequest. Tôi không biết chi tiết triển khai của nhà cung cấp xác thực Stack Overflow, nhưng dữ liệu cookie đó có thể được sử dụng tự động để xác minh danh tính của bạn ở mức thấp hơn phương thức điều khiển "bỏ phiếu".

Tổng quát hơn, cookie không bắt buộc đối với AJAX. Hỗ trợ XmlHttpRequest (hoặc thậm chí từ xa iframe, trên các trình duyệt cũ hơn) là tất cả những gì được yêu cầu về mặt kỹ thuật.

Tuy nhiên, nếu bạn muốn cung cấp bảo mật cho chức năng kích hoạt AJAX, thì các quy tắc tương tự sẽ được áp dụng như với các trang web truyền thống. Bạn cần một số phương pháp để xác định người dùng đằng sau mỗi yêu cầu và cookie hầu như luôn là phương tiện cho mục đích đó.

Trong ví dụ của bạn, tôi không thể viết thư cho document.cookie của bạn, nhưng tôi vẫn có thể đánh cắp cookie của bạn và đăng nó lên miền của tôi bằng cách sử dụng đối tượng XMLHttpRequest.

XmlHttpRequest sẽ không thực hiện các yêu cầu tên miền chéo (vì chính xác các loại lý do bạn chạm vào).

Thông thường bạn có thể tiêm tập lệnh để gửi cookie đến miền của mình bằng cách sử dụng iframe từ xa hoặc JSONP, nhưng sau đó chỉ HTTP bảo vệ cookie một lần nữa vì không thể truy cập được.

Trừ khi bạn đã thỏa hiệp StackOverflow.com ở phía máy chủ, bạn sẽ không thể đánh cắp cookie của tôi.

Chỉnh sửa 2: Câu hỏi 2. Nếu mục đích của Chỉ có http là để ngăn truy cập JavaScript vào cookie và bạn vẫn có thể truy xuất cookie thông qua JavaScript thông qua Đối tượng XmlHttpRequest, điểm của Chỉ có http là gì?

Hãy xem xét kịch bản này:

  • Tôi tìm thấy một con đường để tiêm mã JavaScript vào trang.
  • Jeff tải trang và JavaScript độc hại của tôi sửa đổi cookie của anh ấy để phù hợp với của tôi.
  • Jeff gửi một câu trả lời xuất sắc cho câu hỏi của bạn.
  • Bởi vì anh ấy gửi nó với dữ liệu cookie của tôi thay vì của anh ấy, câu trả lời sẽ trở thành của tôi.
  • Bạn bỏ phiếu cho câu trả lời xuất sắc "của tôi".
  • Tài khoản thực của tôi nhận được điểm.

Với cookie chỉ có HTTP, bước thứ hai sẽ là không thể, do đó đánh bại nỗ lực XSS của tôi.

Chỉnh sửa 4: Xin lỗi, tôi có nghĩa là bạn có thể gửi XMLHttpRequest đến miền StackOverflow và sau đó lưu kết quả của getAllResponseHeaders () vào một chuỗi, thoát khỏi cookie và sau đó đăng nó lên một miền bên ngoài. Có vẻ như Wikipedia và ha.cker đồng tình với tôi về điều này, nhưng tôi rất thích được giáo dục lại ...

Đúng rồi. Bạn vẫn có thể chiếm quyền điều khiển theo cách đó. Nó làm mỏng đáng kể bầy đàn của những người có thể thực hiện thành công ngay cả khi XSS tấn công bạn.

Tuy nhiên, nếu bạn quay trở lại kịch bản ví dụ của tôi, bạn có thể nhìn thấy nơi HTTP-Only không cắt thành công ra khỏi các cuộc tấn công XSS mà dựa vào sửa đổi các tập tin cookie của khách hàng (không phải là hiếm).

Nó hiểu rõ rằng a) không có cải tiến nào sẽ giải quyết được tất cả các lỗ hổng và b) sẽ không có hệ thống nào được bảo mật hoàn toàn. Chỉ HTTP một công cụ hữu ích trong việc chống lại XSS.

Tương tự, mặc dù hạn chế tên miền chéo trên XmlHttpRequest không thành công 100% trong việc ngăn chặn tất cả các khai thác XSS, bạn vẫn không bao giờ mơ đến việc loại bỏ hạn chế.


Nhiều khung đặt csrf mã thông báo trong cookie . Tôi cho rằng cuộc gọi AJAX cần csrfkiểm tra sẽ không hoạt động trừ khi bạn đặt mã thông báo csrf trong phần tử HTML ẩn để JS truy xuất.
người dùng

4

Không nhất thiết, nó phụ thuộc vào những gì bạn muốn làm. Bạn có thể xây dựng một chút? AJAX không cần quyền truy cập vào cookie để hoạt động, nó có thể tự mình yêu cầu trích xuất thông tin, yêu cầu trang mà cuộc gọi AJAX thực hiện có thể truy cập dữ liệu cookie và chuyển trở lại tập lệnh gọi mà không cần Javascript phải truy cập trực tiếp vào bánh quy


4

Có, chúng là một tùy chọn khả thi cho một trang web dựa trên Ajax. Cookie xác thực không bị thao túng bởi các tập lệnh, nhưng chỉ được trình duyệt đưa vào tất cả các yêu cầu HTTP được thực hiện cho máy chủ.

Các tập lệnh không cần phải lo lắng về việc cookie phiên nói gì - miễn là bạn được xác thực, thì mọi yêu cầu đến máy chủ do người dùng khởi tạo hoặc tập lệnh sẽ bao gồm các cookie thích hợp. Thực tế là các tập lệnh không thể tự biết nội dung của cookie.

Đối với bất kỳ cookie nào được sử dụng cho các mục đích khác ngoài xác thực, chúng có thể được đặt mà không có cờ chỉ HTTP, nếu bạn muốn tập lệnh có thể sửa đổi hoặc đọc những mục này. Bạn có thể chọn và chọn cookie nào chỉ là HTTP, vì vậy, ví dụ mọi thứ không nhạy cảm như tùy chọn UI (thứ tự sắp xếp, thu gọn khung bên trái hoặc không) có thể được chia sẻ trong cookie với tập lệnh.

Tôi thực sự thích cookie chỉ HTTP - đó là một trong những tiện ích mở rộng trình duyệt độc quyền đó là một ý tưởng thực sự gọn gàng.


3

Có thêm một chút về điều này.

Ajax không yêu cầu nghiêm ngặt cookie, nhưng chúng có thể hữu ích như các áp phích khác đã đề cập. Đánh dấu cookie HTTPOnly để ẩn nó khỏi các tập lệnh chỉ hoạt động một phần, bởi vì không phải tất cả các trình duyệt đều hỗ trợ nó, mà còn bởi vì có các cách giải quyết chung.

Thật kỳ lạ khi các tiêu đề XMLHTTPresponse đang cung cấp cookie, về mặt kỹ thuật, máy chủ không phải trả lại cookie với phản hồi. Khi nó được đặt trên máy khách, nó sẽ được đặt cho đến khi hết hạn. Mặc dù có các kế hoạch trong đó cookie được thay đổi với mỗi yêu cầu để ngăn chặn việc sử dụng lại. Vì vậy, bạn có thể tránh được cách giải quyết đó bằng cách thay đổi máy chủ để không cung cấp cookie trên các phản hồi XMLHTTP.

Nói chung, tôi nghĩ rằng HTTPOnly nên được sử dụng một cách thận trọng. Có các cuộc tấn công kịch bản chéo trang web trong đó kẻ tấn công sắp xếp để người dùng gửi yêu cầu giống như ajax bắt nguồn từ một trang web khác, sử dụng các biểu mẫu bài đăng đơn giản, không sử dụng XMLHTTP và cookie vẫn hoạt động của trình duyệt của bạn sẽ xác thực yêu cầu.

Nếu bạn muốn chắc chắn rằng một yêu cầu AJAX được xác thực, chính yêu cầu VÀ các tiêu đề HTTP cần phải chứa cookie. Ví dụ, thông qua việc sử dụng các tập lệnh hoặc đầu vào ẩn duy nhất. HTTPOnly sẽ cản trở điều đó.

Thông thường lý do thú vị để muốn HTTPOnly là để ngăn nội dung của bên thứ ba có trên trang web của bạn đánh cắp cookie. Nhưng có nhiều lý do thú vị để rất thận trọng trong đó có nội dung của bên thứ ba và lọc mạnh mẽ.


1

Cookie được trình duyệt tự động xử lý khi bạn thực hiện cuộc gọi AJAX, do đó, Javascript của bạn không cần phải loay hoay với cookie.


1

Do đó, tôi cho rằng JavaScript cần quyền truy cập vào cookie của bạn.

Tất cả các yêu cầu HTTP từ trình duyệt của bạn truyền thông tin cookie của bạn cho trang web được đề cập. JavaScript có thể đặt và đọc cookie. Cookie không theo định nghĩa được yêu cầu cho các ứng dụng Ajax, nhưng chúng được yêu cầu cho hầu hết các ứng dụng web để duy trì trạng thái người dùng.

Câu trả lời chính thức cho câu hỏi của bạn như cụm từ - "JavaScript có cần truy cập vào cookie nếu AJAX được sử dụng không?" - do đó là "không". Ví dụ, hãy nghĩ đến các trường tìm kiếm nâng cao sử dụng các yêu cầu Ajax để cung cấp các tùy chọn đề xuất tự động. Không cần thông tin cookie trong trường hợp đó.


XmlHttpRequest cần cookie. Tìm kiếm nâng cao mà bạn đề cập có thể ở phía sau trang đăng nhập. Nhưng liệu Javascript có cần hiển thị giá trị cookie cho VM hay không là một câu hỏi khác.
Ông Shiny và New 安 宇

1

Như đã làm rõ - từ quan điểm của máy chủ, trang được yêu cầu AJAX yêu cầu về cơ bản không khác với yêu cầu nhận HTTP tiêu chuẩn được thực hiện bởi người dùng nhấp vào liên kết. Tất cả các thuộc tính yêu cầu thông thường: tác nhân người dùng, ip, phiên, cookie, v.v. được chuyển đến máy chủ.


"Phiên" không phải là một khái niệm HTTP. Đó là một khái niệm cấp cao được xây dựng dựa trên các khái niệm HTTP bằng một khung.
tò mò 23/11/18

0

Không, trang mà các yêu cầu cuộc gọi AJAX cũng có quyền truy cập vào cookie & đó là những gì kiểm tra xem bạn đã đăng nhập chưa.

Bạn có thể thực hiện xác thực khác với Javascript, nhưng tôi không tin tưởng nó, tôi luôn thích đặt bất kỳ loại kiểm tra xác thực nào ở phía sau.


0

Vâng, cookie rất hữu ích cho Ajax.

Đặt xác thực vào URL yêu cầu là thực tế xấu. Có một mục tin tức tuần trước về việc nhận mã thông báo xác thực trong URL từ bộ đệm của google.

Không, không có cách nào để ngăn chặn các cuộc tấn công. Các trình duyệt cũ hơn vẫn cho phép truy cập tầm thường vào cookie thông qua javascript. Bạn chỉ có thể bỏ qua http, v.v. Bất cứ điều gì bạn nghĩ ra đều có thể nhận được đủ nỗ lực. Bí quyết là làm cho nó quá nhiều nỗ lực để có giá trị.

Nếu bạn muốn làm cho trang web của mình an toàn hơn (không có bảo mật hoàn hảo), bạn có thể sử dụng cookie xác thực hết hạn. Sau đó, nếu cookie bị đánh cắp, kẻ tấn công phải sử dụng nó trước khi hết hạn. Nếu họ không thì bạn có một dấu hiệu tốt có hoạt động đáng ngờ trên tài khoản đó. Cửa sổ thời gian càng ngắn thì càng tốt cho bảo mật nhưng càng tải nhiều hơn cho máy chủ của bạn tạo và duy trì các khóa.

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.