1. Giới thiệu
Cookie, hay HTTP cookie, web cookie, browser cookie là một đoạn dữ liệu nhỏ được gửi từ phía website và lưu trữ ở trình duyệt của người dùng khi họ duyệt website này. Mỗi lần người dùng load website, trình duyệt sẽ tự động gửi cookie về web server để thông báo cho website biết các hành động trước đó của người dùng.
Cookie được thiết kế để trở thành một cơ chế đáng tin cậy, giúp website ghi nhớ các thông tin trạng thái (chẳng hạn các mặt hàng đang nằm trong giỏ hàng) hoặc lưu trữ các hoạt động của người dùng (bao gồm việc click vào một liên kết, đăng nhập, các trang đã ghé thăm trong tuần, trong tháng hay trong năm,…).
Mặc dù cookie không thể mang theo virus, và cũng không thể cài đặt malware vào máy tính, nhưng việc sử dụng tracking cookie và đặc biệt là cookie của bên thứ ba (third-party cookie) được xem như là cách để xác định các thông tin cá nhân từ lịch sử duyệt web của người dùng. Cookie có thể lưu password hay nội dung mà người dùng nhập vào các form html, chẳng hạn như số thẻ credit card hay địa chỉ cá nhân.
Khi người dùng truy cập vào website lần đầu tiên, cookie sẽ được gửi từ web server đến trình duyệt và được lưu trữ trong máy tính của anh ta. Sau đó, khi anh ta quay lại website, website sẽ nhận ra anh ta vì những thông tin đã được lưu trong cookie.
Authentication cookies là một phương thức phổ biến được sử dụng để xác định xem người dùng có đang đăng nhập website hay không. Nếu không có một cơ chế như vậy, website sẽ khó lòng mà biết được khi nào thì nên gửi những thông tin cá nhân về cho người dùng, và bắt buộc người dùng phải thực hiện thao tác đăng nhập nhiều lần. Authentication cookie tuy rất tiện lợi, nhưng lại tạo ra cơ hội cho hacker có thể đọc được các dữ liệu nhạy cảm trong cookie, từ đó thực hiện các hành động làm tổn hại đến người dùng.
2. Tổng quan về HTTP Cookie
2.1. Lịch sử
Thuật ngữ cookie có nguồn gốc từ thuật ngữ magic cookie, là một đoạn dữ liệu không thay đổi, được gửi nhận bởi chương trình máy tính. Một programmer tên Lou Montuli đã nảy ra ý tưởng sử dụng magic cookie trong truyền thông web vào năm 1994. Tại thời điểm đó, ông đang làm việc cho Netscape Communications, trong một dự án phát triển ứng dụng thương mại điện tử cho MCI. Cookie đã được sử dụng như là một giải pháp trong việc xây dựng các giỏ hàng ảo, giúp các máy chủ của MCI không phải lưu lại trạng thái của các giao dịch mà thay vào đó, chúng được lưu trữ tại máy người dùng.
Cùng với John Giannandrea, Montuli đã viết đặc tả đầu tiên cho Netscape cookie. Version 0.0beta của Mosaic Netscape, được phát hành vào 13/10/1994, đã hỗ trợ cookie. Lần sử dụng cookie đầu tiên (ngoài phòng lab) đã kiểm được khách hàng truy cập vào website của Netscape đã ghé thăm trước đó hay chưa. Montuli đã được cấp bằng sáng chế về cookie vào năm 1995. Và Internet Explorer phiên bản 2 (phát hành tháng 10 năm 1995) đã được tích hợp sử dụng cookie.
Việc giới thiệu cookie không được phổ biến rộng rãi trong thời gian này. Đặc biệt, cookie được chấp nhận mặc định, người dùng không hề được thông báo về sự hiện diện của nó. Công chúng chỉ được biết về cookie sau khi một bài báo viết về nó trên Finacial Times được xuất bản vào 12/02/1996. Kể từ đó, cookie nhận được rất nhiều sự quan tâm, đặc biết là các thông tin riêng tư được chứa trong nó. Cookie đã được mang ra thảo luận trong 2 phiên điều trần của Ủy ban thương mại liên bang Hoa Kỳ vào năm 1996 và 1997.
Cuộc thảo luận đầu tiên về một đặc tả chính thức cho cookie được bắt đầu vào tháng tư năm 1995. Một nhóm đặc biệt trong Lực lượng đặc trách kỹ thuật Internet (IETF) đã được hình thành nhằm mục đích thực hiện công việc này. Cuối cùng, bản đặc tả đã được nhóm công bố vào tháng Hai năm 1997. Bản đặc tả này xác định cookie của bên thứ ba (third-party cookie) hoặc là không được chấp nhận cho tất cả, hoặc ít nhất là không được cho phép mặc định.
Vào tháng Tư năm 2011, đặc tả chuẩn về cookie được sử dụng trong thực tế đã được công bố trong tài liệu RFC 6265.
2.2. Các thuật ngữ
Session cookie
Session cookie, cũng được gọi là in-memory cookie hoặc transient cookie, chỉ tồn tại trong bộ nhớ tạm khi người dùng điều hướng đến website. Nếu hạn sử dụng (expiry date) hoặc khoảng thời gian hiệu lực (validity interval) không được thiết lập lúc tạo cookie thì session cookie sẽ được thiết lập. Thông thường trình duyệt web sẽ tự động delete session cookie khi người dùng tắt trình duyệt.
Persistent cookie
Persistent cookie kéo dài session của người dùng. Nếu một persistent cookie được thiết lập Max-Age là 1 năm thì trong thời hạn đó, giá trị ban đầu được thiết lập trong cookie sẽ được gửi về server mỗi lần người dùng ghé thăm website. Nó có thể được sử dụng để ghi lại các phần thông tin quan trọng, chẳng hạn như người dùng đã ghé thăm website lần đầu tiên như thế nào. Vì lý do này, persistent cookie cũng được gọi với cái tên tracking cookie.
Secure cookie
Secure cookie là một thuộc tính bảo mật được enabled khi sử dụng HTTPS, đảm bảo việc cookie luôn được mã hóa khi chuyển từ client đến server, giúp nó tránh khỏi việc bị nghe trộm làm lộ thông tin. Thêm vào đó, tất cả các cookie phải tuân theo chính sách cùng nguồn gốc (same-origin policy) của trình duyệt.
HttpOnly cookie
Thuộc tính HttpOnly của cookie được hỗ trở bởi hầu hết các trình duyệt. Một HttpOnly session cookie sẽ chỉ được sử dụng trong một HTTP (hoặc HTTPS) request, do đó hạn chế bị truy cập bởi các non-HTTP APIs chẳng hạn Javascript. Việc hạn chế này làm giảm nhẹ nhưng không loại trừ việc đánh cắp cookie thông qua lỗ hổng Cross-site scripting (XSS).
Third-party cookie
Cookie của bên thứ nhất (First-party cookie) là cookie thuộc cùng một domain (hoặc của các sub domain nằm trong cùng domain) hiển thị trên thanh địa chỉ của trình duyệt. Cookie của bên thứ ba (Third-party cookie) là cookie thuộc các domain khác nhau hiển thị trên thanh địa chỉ của trình duyệt. Các trang web có thể có nội dung từ các tên miền của bên thứ ba (chẳng hạn như banner quảng cáo), mà từ đó có thể theo dõi lịch sử duyệt web của người dùng. Các tùy chọn thiết lập riêng tư của hầu hết các trình duyệt đều chặn third-party tracking cookie.
Ví dụ, giả sử người dùng ghé thăm website example1.com. Website này chứa một quảng cáo từ ad.foxytracking.com, khi được load về sẽ lưu luôn cả cookie của ad.foxytracking.com. Sau đó, anh ta truy cập vào một website khác (example2.com), website này cũng chứa một quảng cáo từ ad.foxytracking.com, và nó cũng sẽ thiết lập một cookie thuộc ad.foxytracking.com. Cuối cùng, cả hai cookie này sẽ được gửi đến nhà quảng cáo (advertiser) khi load quảng cáo hoặc truy cập website của họ. Advertiser có thể sử dụng cookies này để xây dựng một lịch sử duyệt web của người dùng trên tất cả các website chứa quảng cáo của họ.
Năm 2014, có một vài website đã thiết lập cookie có thể được đọc bởi hơn 100 third-party domain. Trung bình, một website sẽ được thiết lập khoảng 10 cookie, với số lượng cookie tối đa là trên 800.
Supercookie
Supercookie là cookie có nguồn gốc từ tên miền cấp cao nhất (Top-level domain) chẳng hạn .com, hoặc Public Suffix, chẳng hạn .co.uk. Điều quan trọng là supercookie bị chặn bởi trình duyệt do một số vấn đề về bảo mật. Nếu bỏ chặn, một kẻ tấn công kiểm soát một website độc hại có thể thiết lập supercookie để mạo danh yêu cầu người dùng, gửi request đến các website khác chia sẻ cùng Top-level domain hay Public Suffix. Ví dụ, một supercookie có nguồn gốc từ tên miền .com có thể gây hại đến các request gửi đến example.com, thậm chí nếu cookie đó không xuất phát từ example.com. Nó có thể bị lợi dụng để giả mạo đăng nhập hoặc thay đổi thông tin người dùng.
Zombie cookie
Zombie cookie là loại cookie tự động được tạo lại sau khi người dùng delete chúng. Điều này được thực hiện bằng một script lưu trữ nội dung của cookie đặt ở một vị trí khác, chẳng hạn vùng lưu trữ nội dung Flash, vùng lưu trữ HTML5 hoặc một số cơ chế client-side khác.
2.3. Cấu trúc cookie
Một cookie với kích thước 4KB, bao gồm 7 thành phần chính:
- Name
- Value
- Expires (hạn sử dụng)
- Path (đường dẫn đến nơi cookie có hiệu lực, “/” có nghĩa là cookie có giá trị ở bất cứ đường dẫn nào)
- Domain
- Secure
- HttpOnly
Hai thành phần đầu tiên (name và value) yêu cầu bắt buộc phải có.
2.4. Sử dụng
Quản lý session
Cookie có thể được dùng để duy trì dữ liệu liên quan đến người dùng trong nhiều lần truy cập website khác nhau. Cookie là giải pháp để tạo shopping cart, một giỏ hàng ảo giúp người dùng lưu những mặt hàng mà mình chọn trong lúc duyệt qua các sản phẩm.
Ứng dụng shopping cart hiện nay thường lưu trữ danh sách các mặt hàng trong giỏ trong database phía server thay vì lưu ở cookie phía client. Web server thông thường sẽ gửi đi một cookie chứa định danh session – session ID (là duy nhất). Trình duyệt web sẽ gửi trả lại session ID này kèm theo mỗi yêu cầu mua sắm của người dùng.
Cho phép người dùng đăng nhập vào website là một ứng dụng nữa của cookie. Thông thường, trong lần đăng nhập đầu tiên, web server sẽ gửi cho client một cookie chứa session ID. Người dùng sẽ gửi lên thông tin của họ và ứng dụng web sẽ xác thực session, sau đó cho phép người dùng sử dụng các dịch vụ của mình.
Cookie cung cấp một cơ chế tương tác client/server nhanh chóng và thuận tiện. Một trong những lợi thế của cookie là nó lưu trữ thông tin người dùng trong một file nằm ở máy của người dùng. Việc này làm giảm đáng kể không gian lưu trữ và thời gian xử lý của server.
Cá nhân hóa
Cookie có thể được dùng để ghi nhớ những thông tin cá nhân của người dùng khi họ truy cập website, để hiển thị nhưng nội dung liên quan hơn đến người dùng đó mỗi khi anh ta ghé thăm lại website.
Một ví dụ nổi bật là tính năng gợi ý sách của amazon.com. Khi người dùng click vào một quyển sách, amazon sẽ đưa ra những gợi ý về những quyển sách tiếp theo mà người dùng nên xem. Những gợi ý này dựa trên việc người dùng đã duyệt sách nào trước đó và cuốn sách nào mà họ đã chọn mua.
Một ví dụ khác là tính năng gợi ý tìm kiếm của Google Search. Khi bạn đăng nhập bằng tài khoản cá nhân của mình và thực hiện tìm kiếm, Google sẽ đưa ra các gợi ý “dành riêng cho bạn”, và kết quả mà bạn mong muốn luôn hiện lên trên đầu danh sách.
Theo dõi
Tracking cookie có thể được sử dụng để theo dõi lịch sử duyệt web của người dùng. Điều này cũng có thể được thực hiện bằng cách sử dụng địa chỉ IP của máy tính gửi request đến trang web hoặc dựa vào trường Referrer của HTTP request header, nhưng cookie cho độ chính xác cao hơn. Điều này được thực hiện như sau:
- Nếu người dùng truy cập vào một trang web, nhưng request này lại không chứa cookie, server sẽ giả định rằng đây là lần đầu tiên người dùng ghé thăm trang web này; server sẽ tạo ra một chuỗi ngẫu nhiên và gửi nó như một cookie trở lại trình duyệt cùng với trang web được yêu cầu.
- Từ thời điểm này, cookie sẽ được trình duyệt tự động gửi lên server mỗi khi một trang web mới trong website này được yêu cầu, server sẽ gửi trả lại trang web được request như bình thường, nhưng URL của trang web đó và thời điểm truy cập sẽ được lưu lại trong một file log. Bằng cách phân tích những thông tin được lưu lại trong file log này, lịch sử duyệt web, các trang web thường ghé thăm, thói quen duyệt web của người sẽ được phơi bày sáng tỏ.
2.5. Triển khai
Cookie là dữ liệu được gửi từ server đến trình duyệt. Trình duyệt sau đó sẽ gửi nó trở lại server mà không thay đổi nội dung bên trong, mỗi lần người dùng gửi request đến website. Cookie cũng có thể được thiết lập bởi một ngôn ngữ script, chẳng hạn Javascript.
Mỗi trình duyệt web có thể lưu trữ ít nhất 300 cookie trong một file 4KB, và ít nhất 20 cookie trên mỗi server hay domain.
Thiết lập cookie
Web server và trình duyệt liên lạc với nhau qua giao thức HTTP (HyperText Transfer Protocol). Ví dụ, để truy cập vào trang http://www.example.org/index.html, trình duyệt kết nối đến server bằng cách gửi đi một HTTP Request có dạng như sau:
Server sẽ trả lời lại bằng cách gửi về cho trình duyệt một gói text đơn giản, gọi là HTTP Response. Gói tin này có thể có một dòng chứa nội dung của cookie:
Set-Cookie là trường chỉ thị cho trình duyệt lưu trữ cookie và gửi nó về cho server trong tương lai mỗi khi có request đến server (nếu cookie đó vẫn còn hạn sử dụng). Ví dụ, trình duyệt gửi request đến trang http://www.example.org/spec.html bằng cách gửi đi một HTTP Request có dạng như sau:
Đây là request đến một trang khác thuộc cùng server. Trong trường hợp này, server sẽ hiểu rằng request này có liên quan đến request trước, và nó trả lời lại bằng cách gửi về cho trình duyệt trang web được yêu cầu, có thể thêm vào các giá trị cookie khác nữa.
Giá trị của cookie có thể được sửa đổi bởi server bằng cách gửi về cho trình duyệt trường Set-Cookie: name=value trong HTTP Response. Trình duyệt sau đó sẽ thay thế giá trị cookie cũ bằng giá trị mới này.
Giá trị của cookie có thể bao gồm bất kỳ ký tự ASCII in được nào trừ “,”, “;” và khoảng trắng. Tên của cookie cũng không được chứa ký tự ‘=’, vì đó là ký tự ngăn cách giữa tên và giá trị.
Thuật ngữ cookie crumb thỉnh thoảng được sử dụng để chỉ cặp tên-giá trị của cookie.
Cookie cũng có thể được thiết lập bởi Javascript hoặc một ngôn ngữ kịch bản tương tự. Trong Javascript, đối tượng document.cookie được sử dụng để thiết lập cookie. Thuộc tính HttpOnly có nhiệm vụ ngăn chặn những đoạn script xấu đọc được nội dung cookie.
Các thuộc tính của cookie
Bên cạnh cặp name-value, server cũng có thể thiết lập một số thuộc tính cookie khác: Domain, Path, Expirse, Max-Age, Secure và HttpOnly. Trình duyệt sẽ không gửi các thuộc tính này lên server, nó chỉ gửi cặp name-value mà thôi. Các thuộc tính này được trình duyệt sử dụng để xác định xem khi nào thì xóa cookie, chặn cookie hoặc gửi cookie đến server.
Domain và path
Domain và path xác định phạm vi của cookie. Chúng cho phép trình duyệt xác định được khi nào thì gửi cookie lên server. Nếu không được quy định, chúng mặc định rằng domain và path của đối tượng đã được request. Tuy nhiên, có sự khác nhau giữa cookie được thiết lập cho foo.com mà không có thuộc tính domain, và cookie được thiết lập có thuộc tính domain foo.com. Trong trường hợp đầu tiên, cookie sẽ chỉ được gửi khi có request đến foo.com. Trong trường hợp sau, cookie sẽ được gửi đến tất cả các sub domain của foo.com. Sau đây là một ví dụ về chỉ thị Set-Cookie từ một website sau khi người dùng đăng nhập, từ một request đến docs.foo.com:
Cookie đầu tiên LSID không có thuộc tính domain và có path là /accounts. Trình duyệt sẽ chỉ gửi cookie khi trang được request chứa trong docs.foo.com/accounts. Hai cookie còn lại, HSID và SSID được gửi trở lại server nếu có request nào đến bất kỳ một sub domain của foo.com.
Cookie cũng có thể chỉ được thiết lập cho top domain và sub domain của nó. Thiết lập cookie trên www.foo.com từ www.bar.com sẽ không được phép vì lý do bảo mật.
Expires và Max-Age
Thuộc tính Expires cho trình duyệt biết khi nào thì delete cookie. Ngày tháng trong Expires có dạng như sau: “Wdy, DD Mon YYYY HH:MM:SS GMT”. Max-Age cũng được dùng để thông báo ngày hết hạn của cookie. Cùng xem xét ví dụ sau:
Cookie đầu tiên lu set expire giá trị 15-Jan-2013, nó sẽ được trình duyệt sử dụng khi đến thời hạn này. Cookie thứ hai made_write_conn không có expire, và được sử dụng làm session cookie, nó sẽ bị xóa khi tắt trình duyệt. Cookie thứ ba reg_fb_gate, có expire là thời điểm tại quá khứ, nó sẽ bị delete ngay lập tức.
Secure và HttpOnly
Thuộc tính Secure và HttpOnly không có giá trị, thay vào đó, sự hiện diện của chúng chỉ ra rằng các cở Secure và HttpOnly được áp dụng.
Thuộc tính Secure giữ cho việc truyền cookie trong một kết nối mã hóa. Nếu web server thiết lập cookie với thuộc tính secure từ một kết nối non-secure, cookie vẫn có thể bị chặn bởi kẻ tấn công đứng giữa (tấn công man-in-the-middle).
Thuộc tính HttpOnly chỉ thị cho trình duyệt không để lộ cookie thông qua một kết nối khác ngoài HTTP (hoặc HTTPS), chẳng hạn Javascript, và do đó khó có thể lấy cookie bằng việc khai thác lỗ hổng Cross-Site Scripting (XSS).
3. Một số vấn đề bảo mật khi sử dụng cookie
Nếu một website sử dụng session ID để xác định phiên làm việc của người dùng, kẻ tấn công có thể có thể đánh cắp cookie để giả mạo người dùng. Sau đây là một số kịch bản đánh cắp cookie thường gặp:
Nghe lén (eavesdropping)
Traffic trong một hệ thống mạng có thể bị chặn và đọc bởi một người thứ ba (không phải người nhận và người gửi). Traffic này bao gồm cả cookie. Nếu đường truyền không được mã hóa, kẻ tấn công có thể đọc được những thông tin nhạy cảm chứa trong cookie. Và lợi dụng những thông tin này, kẻ tấn công sẽ mạo danh người dùng thực hiện những hành động nguy hiểm, chẳng hạn như các giao dịch ngân hàng.
Vấn đề này có thể được giải quyết bằng cách sử dụng một giao thức bảo mật giữa máy tính của người dùng và server – giao thức HTTPS. Server có thể sử dụng cờ Secure khi thiết lập cookie. Khi đó, cookie sẽ chỉ được gửi đi thông qua một kênh truyền mã hóa, chẳng hạn một kết nối SSL.
Cross-site scripting
Các ngôn ngữ script, chẳng hạn Javascript, được cho phép đọc các giá trị của cookie và gửi chúng đến các server tùy ý.
Giả sử một website bị dính lỗi Cross-site scripting, hacker có thể chèn vào các đoạn mã độc hại, chẳng hạn như sau:
Khi nạn nhân click vào link trên, trình duyệt sẽ thực thi đoạn script nằm trong thuộc tính onclick: gửi cookie của nạn nhân đến server attacker.com.
Cross-site scripting là một trong những lỗ hổng phổ biến của các website (đứng thức ba trong top 10 lỗ hổng phổ biến nhất năm 2013 – theo OWASP).
Có thể hạn chế nguy cơ của lỗ hổng này bằng cách thiết lập cờ HttpOnly cho cookie. Khi đó, cookie sẽ không bị truy cập bởi các ngôn ngữ script.
Cross-site request forgery
CSRF (Cross-site request forgery) hay one-click attack, là một phương thức khai thác lỗ hổng của website theo đó những lệnh không được phép được thực hiện bởi nạn nhân – những user được website cấp quyền mà họ không hề hay biết.
CSRF sẽ lừa trình duyệt của nạn nhân gửi đi các request http đến các ứng dụng web. Trong trường hợp phiên làm việc của nạn nhân chưa hết hiệu lực thì các request trên sẽ được thực hiện với quyền chứng thực của nạn nhân.
Ví dụ, nạn nhân Bob đang giao dịch ở trang web của ngân hàng X nào đó. Fred là người tấn công, tên này biết được cách thức hoạt động của website ngân hàng X khi muốn chuyển tiền từ account A này sang account B kia như sau:
http://bank.example.com/withdraw?account=accountA&amount=100&for=accountB
Hắn sẽ gửi đến Bob một đường độc hại.
Nếu ngân hàng X lưu thông tin xác thực người dùng trong cookie, và Bob click vào đường link trên, tiền của Bob sẽ được chuyển đến cho Fred.
Để hạn chế nguy cơ này, có thể thiết lập thông số Expires (hạn sử dụng) cho cookie.
4. Kết luận
Cookie được sử dụng ở hầu hết các ứng dụng web hiện nay. Nó cũng chứa những nguy cơ tiềm tàng, ảnh hưởng không nhỏ đến người sử dụng. Do đó, đứng về phía người phát triển, chúng ta cần hiểu rõ về cookie và biết cách thiết lập các thông số cần thiết để ứng dụng có thể an toàn hơn trước các cuộc tấn công của hacker.