ì¿ í¤ë ë¸ë¼ì°ì ì ì ì¥ëë ìì í¬ê¸°ì 문ìì´ë¡, RFC 6265 ëª ì¸ìì ì ìí HTTP íë¡í ì½ì ì¼ë¶ì ëë¤.
ì¿ í¤ë ì£¼ë¡ ì¹ ìë²ì ìí´ ë§ë¤ì´ì§ëë¤. ìë²ê° HTTP ìëµ í¤ë(header)ì Set-Cookieì ë´ì©ì ë£ì´ ì ë¬íë©´, ë¸ë¼ì°ì ë ì´ ë´ì©ì ìì²´ì ì¼ë¡ ë¸ë¼ì°ì ì ì ì¥í©ëë¤. ì´ê² ë°ë¡ ì¿ í¤ì
ëë¤. ë¸ë¼ì°ì ë ì¬ì©ìê° ì¿ í¤ë¥¼ ìì±íëë¡ í ëì¼ ìë²(ì¬ì´í¸)ì ì ìí ëë§ë¤ ì¿ í¤ì ë´ì©ì Cookie ìì² í¤ëì ë£ì´ì í¨ê» ì ë¬í©ëë¤.
ì¿ í¤ë í´ë¼ì´ì¸í¸ ìë³ê³¼ ê°ì ì¸ì¦ì ê°ì¥ ë§ì´ ì°ì ëë¤.
- ì¬ì©ìê° ë¡ê·¸ì¸íë©´ ìë²ë HTTP ìëµ í¤ëì
Set-Cookieì ë´ê¸´ âì¸ì ìë³ì(session identifier)â ì 보를 ì¬ì©í´ ì¿ í¤ë¥¼ ì¤ì í©ëë¤. - ì¬ì©ìê° ëì¼ ëë©ì¸ì ì ìíë ¤ê³ íë©´ ë¸ë¼ì°ì ë HTTP
Cookieí¤ëì ì¸ì¦ ì ë³´ê° ë´ê¸´ ê³ ì³ê°(ì¸ì ìë³ì)ì í¨ê» ì¤ì´ ìë²ì ìì²ì ë³´ë ëë¤. - ìë²ë ë¸ë¼ì°ì ê° ë³´ë¸ ìì² í¤ëì ì¸ì ìë³ì를 ì½ì´ ì¬ì©ì를 ìë³í©ëë¤.
document.cookie íë¡í¼í°ë¥¼ ì´ì©íë©´ ë¸ë¼ì°ì ììë ì¿ í¤ì ì ê·¼í ì ììµëë¤.
ì¿ í¤ì ë¤ìí ì¿ í¤ì ìµì ì ë¤ë£¨ë ì¼ì ì½ì§ ììµëë¤. ì´ ì±í°ìì ì´ì ëí´ ìì¸í ììë³´ëë¡ íê² ìµëë¤.
ì¿ í¤ ì½ê¸°
ì§ê¸ ë³´ê³ ìë ì´ ì¬ì´í¸ì ê´ë ¨ë ì¿ í¤ê° ë¸ë¼ì°ì ì ì ì¥ëì´ìëì§ ììë´ ìë¤.
// javascript.infoìì Google Analytics(GA)를 ì¬ì©í´ ë°ì´í°ë¥¼ ìì§íê³ ììµëë¤.
// ì´ì ê´ë ¨ë ì¿ í¤ë¥¼ íì¸í´ ë´
ìë¤.
alert( document.cookie ); // cookie1=value1; cookie2=value2;...
document.cookieë name=value ìì¼ë¡ 구ì±ëì´ìê³ , ê° ìì ;ë¡ êµ¬ë¶í©ëë¤. ì´ë, ì íëë íëì ë
립ë ì¿ í¤ë¥¼ ëíë
ëë¤.
;ì 기ì¤ì¼ë¡ document.cookieì ê°ì ë¶ë¦¬íë©´ ìíë ì¿ í¤ë¥¼ ì°¾ì ì ììµëë¤. ì ê· ííìì´ë ë°°ì´ ê´ë ¨ í¨ì를 í¨ê» ì¬ì©í´ì ë§ì´ì£ .
ì´ì ê´í ì°ìµë¬¸ì 를 ìëìì íì´ë³´ê¸¸ ê¶ì í©ëë¤. ì¿ í¤ ì¡°ìì ì°ì´ë ëª ê°ì§ í¬í¼(ëì°ë¯¸) í¨ì를 ì±í° ëì ëª ìí´ ëìì¼ë, ì´ë¥¼ ì°¸ê³ íì ë ì¢ìµëë¤.
ì¿ í¤ ì°ê¸°
document.cookieì ì§ì ê°ì ì¸ ì ììµëë¤. ì´ë cookieë ë°ì´í° íë¡í¼í°ê° ìë ì ê·¼ì(accessor) íë¡í¼í°ì
ëë¤. ìì íë¡í¼í° getterì setterìì íìµí ë°ì ê°ì´, ì ê·¼ì íë¡í¼í°ì ê°ì í ë¹íë ê²ì ë°ì´í° íë¡í¼í°ì ê°ì í ë¹íë ê²ê³¼ë ì¡°ê¸ ë¤ë¥´ê² ì²ë¦¬ë©ëë¤.
document.cookieì ê°ì í ë¹íë©´, ë¸ë¼ì°ì ë ì´ ê°ì ë°ì í´ë¹ ì¿ í¤ë¥¼ ê°±ì í©ëë¤. ì´ë, ë¤ë¥¸ ì¿ í¤ì ê°ì ë³ê²½ëì§ ììµëë¤.
ìëì ê°ì´ ì½ë를 ìì±íë©´ ì´ë¦ì´ userì¸ ì¿ í¤ë¥¼ ì°¾ì ê·¸ ê°ì Johnì¼ë¡ ê°±ì í©ëë¤.
document.cookie = "user=John"; // ì´ë¦ì´ 'user'ì¸ ì¿ í¤ì ê°ë§ ê°±ì í¨
alert(document.cookie); // 모ë ì¿ í¤ ë³´ì¬ì£¼ê¸°
ì½ë를 ì¤ííë©´ ì¬ë¬ ê°ì ì¿ í¤ê° ì¶ë ¥ëë ê²ì íì¸í ì ììµëë¤. ì´ë¥¼ íµí´ document.cookie= ì°ì°ì 모ë ì¿ í¤ë¥¼ ë®ì´ì°ì§ ìê³ , ëª
ìë ì¿ í¤ì¸ userì ê°ë§ ê°±ì í ê²ì ì ì ììµëë¤.
ì¿ í¤ì ì´ë¦ê³¼ ê°ì í¹ë³í ì ì½ì´ ì기 ë문ì 모ë ê¸ìê° íì©ë©ëë¤. íì§ë§ íìì ì í¨ì±ì ì¼ê´ì± ìê² ì ì§í기 ìí´ ë°ëì ë´ì¥ í¨ì encodeURIComponent를 ì¬ì©íì¬ ì´ë¦ê³¼ ê°ì ì´ì¤ì¼ì´í ì²ë¦¬í´ ì¤ì¼ í©ëë¤.
// í¹ì ê°(공백)ì ì¸ì½ë© ì²ë¦¬í´ ì¤ì¼ í©ëë¤.
let name = "my name";
let value = "John Smith"
// ì¸ì½ë© ì²ë¦¬ë¥¼ í´, ì¿ í¤ë¥¼ my%20name=John%20Smith ë¡ ë³ê²½íììµëë¤.
document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
alert(document.cookie); // ...; my%20name=John%20Smith
ì¿ í¤ì ëª ê°ì§ ì ì½ ì¬íì´ ììµëë¤.
encodeURIComponentë¡ ì¸ì½ë©í ì´íìname=valueìì 4KB를 ëì ì ììµëë¤. ì´ ì©ëì ëë ì ë³´ë ì¿ í¤ì ì ì¥í ì ììµëë¤.- ëë©ì¸ íëë¹ ì ì¥í ì ìë ì¿ í¤ì ê°ìë 20ì¬ ê° ì ëë¡ íì ëì´ ììµëë¤. ê°ìë ë¸ë¼ì°ì ì ë°ë¼ ì¡°ê¸ì© ë¤ë¦ ëë¤.
ì¿ í¤ì ëª ê°ì§ ìµì ì´ ììµëë¤. ëªëª ìµì ì ì주 ì¤ìí기 ë문ì ê¼ ì§ì í´ ì¤ì¼ í©ëë¤.
ìµì
ì key=value ë¤ì ëì´íê³ ;ë¡ êµ¬ë¶í©ëë¤. ìëì ê°ì´ ë§ì´ì£ .
document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"
path
path=/mypath
URL path(ê²½ë¡)ì ì ëì¬ë¡, ì´ ê²½ë¡ë ì´ ê²½ë¡ì íì ê²½ë¡ì ìë íì´ì§ë§ ì¿ í¤ì ì ê·¼í ì ììµëë¤. ì ë ê²½ë¡ì´ì´ì¼ íê³ , (미 ì§ì ì) 기본ê°ì íì¬ ê²½ë¡ì ëë¤.
path=/admin ìµì
ì ì¬ì©íì¬ ì¤ì í ì¿ í¤ë /adminê³¼ /admin/somethingìì ë³¼ ì ìì§ë§, /home ì´ë /adminpageìì ë³¼ ì ììµëë¤.
í¹ë³í ê²½ì°ê° ìëë¼ë©´, path ìµì
ì path=/ê°ì´ 루í¸ë¡ ì¤ì í´ ì¹ì¬ì´í¸ì 모ë íì´ì§ìì ì¿ í¤ì ì ê·¼í ì ìëë¡ í©ìë¤.
domain
domain=site.com
ì¿ í¤ì ì ê·¼ ê°ë¥í domain(ëë©ì¸)ì ì§ì í©ëë¤. ë¤ë§, ëª ê°ì§ ì ì½ì´ ìì´ì ì무 ëë©ì¸ì´ë ì§ì í ì ììµëë¤.
domain ìµì
ì ì무 ê°ë ë£ì§ ììë¤ë©´, ì¿ í¤ë¥¼ ì¤ì í ëë©ì¸ììë§ ì¿ í¤ì ì ê·¼í ì ììµëë¤. site.comìì ì¤ì í ì¿ í¤ë other.comìì ì»ì ì ìì£ .
ì´ ì¸ì ê¹ë¤ë¡ì´ ì ì½ì¬íì´ íë ë ììµëë¤. ìë¸ ëë©ì¸(subdomain)ì¸ forum.site.comììë ì¿ í¤ ì 보를 ì»ì ì ìë¤ë ì ì
ëë¤.
// site.comìì ì¿ í¤ë¥¼ ì¤ì í¨
document.cookie = "user=John"
// site.comì ìë¸ëë©ì¸ì¸ forum.site.comìì user ì¿ í¤ì ì ê·¼íë ¤ í¨
alert(document.cookie); // ì°¾ì ì ìì
ìë¸ ëë©ì¸ì´ë ë¤ë¥¸ ëë©ì¸ìì ì¿ í¤ì ì ìí ë°©ë²ì ììµëë¤. site.comìì ìì±í ì¿ í¤ë¥¼ other.comìì ì ë ì ì¡ë°ì ì ììµëë¤.
ì´ë° ì ì½ì¬íì ìì ì±ì ëì´ê¸° ìí´ ë§ë¤ì´ì¡ìµëë¤. 민ê°í ë°ì´í°ê° ì ì¥ë ì¿ í¤ë ê´ë ¨ íì´ì§ììë§ ë³¼ ì ìëë¡ í기 ìí´ì ë§ì´ì£ .
ê·¸ë°ë° ì ë§ forum.site.comê³¼ ê°ì ìë¸ ëë©ì¸ìì site.comìì ìì±í ì¿ í¤ ì 보를 ì»ì ë°©ë²ì´ ìë 걸ê¹ì? ë°©ë²ì´ ììµëë¤. site.comìì ì¿ í¤ë¥¼ ì¤ì í ë domain ìµì
ì ë£¨í¸ ëë©ì¸ì¸ domain=site.comì ëª
ìì ì¼ë¡ ì¤ì í´ ì£¼ë©´ ëì£ .
// site.comìì
// ìë¸ ëë©ì¸(*.site.com) ì´ëìë ì¿ í¤ì ì ìíê² ì¤ì í ì ììµëë¤.
document.cookie = "user=John; domain=site.com"
// ì´ë ê² ì¤ì íë©´
// forum.site.comì ê°ì ìë¸ëë©ì¸ììë ì¿ í¤ ì 보를 ì»ì ì ììµëë¤.
alert(document.cookie); // user=John ì¿ í¤ë¥¼ íì¸í ì ììµëë¤.
íì í¸íì± ì ì§ë¥¼ ìí´ (site.com ìì ì ì ë¶ì¸) domain=.site.comë domain=site.comê³¼ ëì¼íê² ìëí©ëë¤. ì¤ëë í기ë²ì´ê¸´ íì§ë§ 구ì ë¸ë¼ì°ì 를 ì§ìíë ¤ë©´ ì´ í기ë²ì ì¬ì©íë ê²ì´ ì¢ìµëë¤.
ì´ë ê² domain ìµì
ê°ì ì ì í ì¬ì©íë©´ ìë¸ ëë©ì¸ììë ì¿ í¤ì ì ê·¼í ì ììµëë¤.
expiresì max-age
expires(ì í¨ ì¼ì)ë max-age(ë§ë£ 기ê°) ìµì ì´ ì§ì ëì´ìì§ ìì¼ë©´, ë¸ë¼ì°ì ê° ë«í ë ì¿ í¤ë í¨ê» ìì ë©ëë¤. ì´ë° ì¿ í¤ë¥¼ "ì¸ì ì¿ í¤(session cookie)"ë¼ê³ ë¶ë¦ ëë¤.
expires ë max-age ìµì
ì ì¤ì íë©´ ë¸ë¼ì°ì 를 ë«ìë ì¿ í¤ê° ìì ëì§ ììµëë¤.
expires=Tue, 19 Jan 2038 03:14:07 GMT
ë¸ë¼ì°ì ë ì¤ì ë ì í¨ ì¼ìê¹ì§ ì¿ í¤ë¥¼ ì ì§íë¤ê°, í´ë¹ ì¼ìê° ëë¬íë©´ ì¿ í¤ë¥¼ ìëì¼ë¡ ìì í©ëë¤.
ì¿ í¤ì ì í¨ ì¼ìë ë°ëì GMT(Greenwich Mean Time) í¬ë§·ì¼ë¡ ì¤ì í´ì¼ í©ëë¤. date.toUTCStringì ì¬ì©íë©´ í´ë¹ í¬ë§·ì¼ë¡ ì½ê² ë³ê²½í ì ììµëë¤. ìëë ì í¨ ê¸°ê°ì´ íë£¨ì¸ ì¿ í¤ë¥¼ ë§ëë ììì
ëë¤.
// ì§ê¸ì¼ë¡ë¶í° í루 í
let date = new Date(Date.now() + 86400e3);
date = date.toUTCString();
document.cookie = "user=John; expires=" + date;
expires ìµì
ê°ì ê³¼ê±°ë¡ ì§ì íë©´ ì¿ í¤ë ìì ë©ëë¤.
max-age=3600
max-ageë expires ìµì
ì ëìì¼ë¡, ì¿ í¤ ë§ë£ 기ê°ì ì¤ì í ì ìê² í´ì¤ëë¤. íì¬ë¶í° ì¤ì íê³ ì íë ë§ë£ì¼ìê¹ì§ì ìê°ì ì´ë¡ íì°í ê°ì ì¤ì í©ëë¤.
0ì´ë ììê°ì ì¤ì íë©´ ì¿ í¤ë ë°ë¡ ìì ë©ëë¤.
// 1ìê° ë¤ì ì¿ í¤ê° ìì ë©ëë¤.
document.cookie = "user=John; max-age=3600";
// ë§ë£ 기ê°ì 0ì¼ë¡ ì§ì íì¬ ì¿ í¤ë¥¼ ë°ë¡ ìì í¨
document.cookie = "user=John; max-age=0";
secure
secure
ì´ ìµì ì ì¤ì íë©´ HTTPSë¡ íµì íë ê²½ì°ìë§ ì¿ í¤ê° ì ì¡ë©ëë¤.
secure ìµì
ì´ ìì¼ë©´ 기본 ì¤ì ì´ ì ì©ëì´ http://site.comìì ì¤ì (ìì±)í ì¿ í¤ë¥¼ https://site.comìì ì½ì ì ìê³ , https://site.comìì ì¤ì (ìì±)í ì¿ í¤ë http://site.comìì ì½ì ì ììµëë¤.
ì¿ í¤ë 기본ì ì¼ë¡ ëë©ì¸ë§ íì¸íì§ íë¡í ì½ì ë°ì§ì§ ì기 ë문ì ëë¤.
íì§ë§ secure ìµì
ì´ ì¤ì ë ê²½ì°, https://site.comìì ì¤ì í ì¿ í¤ë http://site.comìì ì ê·¼í ì ììµëë¤. ì¿ í¤ì 민ê°í ë´ì©ì´ ì ì¥ëì´ ìì´ ìí¸íëì§ ìì HTTP ì°ê²°ì íµí´ ì ë¬ëë 걸 ìì¹ ìëë¤ë©´ ì´ ìµì
ì ì¬ì©íë©´ ë©ëë¤.
// (https:// ë¡ íµì íê³ ìë¤ê³ ê°ì ì¤)
// ì¤ì í ì¿ í¤ë HTTPS íµì ììë§ ì ê·¼í ì ìì
document.cookie = "user=John; secure";
samesite
ë ë¤ë¥¸ ë³´ì ìì±ì¸ samesite ìµì
ì í¬ë¡ì¤ ì¬ì´í¸ ìì² ìì¡°(cross-site request forgery, XSRF) 공격ì ë§ê¸° ìí´ ë§ë¤ì´ì§ ìµì
ì
ëë¤.
ìë XSRF 공격 ìë리ì¤ë¥¼ íµí´ ì´ ìì±ì ëì ë°©ìê³¼ ì¸ì ì´ ìì±ì ì ì©íê² ì¬ì©í ì ìëì§ ììë³´ëë¡ í©ìë¤.
XSRF 공격
íì¬ bank.comì ë¡ê·¸ì¸ëì´ìë¤ê³ ê°ì í´ ë´
ìë¤. í´ë¹ ì¬ì´í¸ìì ì¬ì©ëë ì¸ì¦ ì¿ í¤ê° ë¸ë¼ì°ì ì ì ì¥ëê³ , ë¸ë¼ì°ì ë bank.comì ìì²ì ë³´ë¼ ëë§ë¤ ì¸ì¦ ì¿ í¤ë¥¼ í¨ê» ì ì¡í ê²ì
ëë¤. ìë²ë ì ì¡ë°ì ì¿ í¤ë¥¼ ì´ì©í´ ì¬ì©ì를 ìë³íê³ , ë³´ìì´ íìí ì¬ì ê±°ë를 ì²ë¦¬í©ëë¤.
ì´ì (ë¡ê·¸ììíì§ ìê³ ) ë¤ë¥¸ ì°½ì ëìì ì¹ ìíì íë ëì¤ì ë»íì§ ìê² evil.comì ì ìíë¤ ê°ì í´ ë´
ìë¤. ì´ ì¬ì´í¸ì í´ì»¤ìê² ì¡ê¸ì ìì²íë í¼(form) <form action="https://bank.com/pay">ì´ ìê³ , ì´ í¼ì ìëì¼ë¡ ì ì¶ëëë¡ ì¤ì ëì´ ììµëë¤.
í¼ì´ evil.comìì ìí ì¬ì´í¸ë¡ ë°ë¡ ì ì¡ë ë ì¸ì¦ ì¿ í¤ë í¨ê» ì ì¡ë©ëë¤. bank.comì ìì²ì ë³´ë¼ ëë§ë¤ bank.comìì ì¤ì í ì¿ í¤ê° ì ì¡ë기 ë문ì
ëë¤. ìíì ì ì¡ë°ì ì¿ í¤ë¥¼ ì½ì´ (í´ì»¤ê° ìë) ê³ì 주ì¸ì´ ì ìí ê²ì´ë¼ ìê°íê³ í´ì»¤ìê² ëì ì¡ê¸í©ëë¤.
ì´ë° 공격ì í¬ë¡ì¤ ì¬ì´í¸ ìì² ìì¡°ë¼ê³ ë¶ë¦ ëë¤.
ì¤ì ìíì ë¹ì°í ì´ ê³µê²©ì ë§ì ì ìëë¡ ìì¤í
ì ì¤ê³í©ëë¤. bank.comìì ì¬ì©íë 모ë í¼ì "XSRF ë³´í¸ í í°(protection token)"ì´ë¼ë í¹ì íë를 ë£ì´ì ë§ì´ì£ . ì´ í í°ì ì
ìì ì¸ íì´ì§ìì ë§ë¤ ì ìê³ , ì격 íì´ì§ììë íì³ ì¬ ì ìëë¡ êµ¬íëì´ ììµëë¤. ë°ë¼ì ì
ìì ì¸ íì´ì§ìì í¼ì ì ì¡íëë¼ë ë³´í¸ í í°ì´ ìê±°ë ìë²ì ì ì¥ë ê°ê³¼ ì¼ì¹íì§ ì기 ë문ì ìì²ì´ 무ì©ì§ë¬¼ì´ ë©ëë¤.
íì§ë§ ì´ë° ì ì°¨ë 구íì ìê°ì´ 걸린ë¤ë ë¨ì ì ìë°í©ëë¤. 모ë í¼ì ë³´í¸ í í°ì ì¸í í´ì¤ì¼ íì£ . ëí ìì² ì ë¶ë¥¼ ê²ìí´ì¼ í©ëë¤.
samesite ìµì
ì¿ í¤ì samesite ìµì
ì ì´ì©íë©´ âXSRF ë³´í¸ í í°â ìì´ë (ì´ë¡ ìì¼ë¡) í¬ë¡ì¤ ì¬ì´í¸ ìì² ì조를 ë§ì ì ììµëë¤.
ì´ ìµì ì ë ê°ì§ ê°ì ì¤ì í ì ììµëë¤.
samesite=strict(ê°ì ì¤ì íì§ ìê³ ê·¸ë¥samesiteìµì ë§ ì¨ì¤ë ëì¼íê² ëìí¨)
ì¬ì©ìê° ì¬ì´í¸ ì¸ë¶ìì ìì²ì ë³´ë¼ ë, samesite=strict ìµì
ì´ ìë ì¿ í¤ë ì ëë¡ ì ì¡ëì§ ììµëë¤.
ë©ì¼ì ìë ë§í¬ë¥¼ ë°ë¼ ì ìíê±°ë evil.comê³¼ ê°ì ì¬ì´í¸ìì í¼ì ì ì¡íë ê²½ì° ë±ê³¼ ê°ì´ ì 3ì ëë©ì¸ìì ìì²ì´ ì´ë¤ì§ ë ì¿ í¤ê° ì ì¡ëì§ ìì£ .
ì¸ì¦ ì¿ í¤ì samesite ìµì
ì´ ìë ê²½ì°, XSRF 공격ì ì ëë¡ ì±ê³µíì§ ëª»í©ëë¤. evil.comìì ì ì¡íë ìì²ì ì¿ í¤ê° ìì ê²ì´ê³ , bank.comì 미ì¸ì ì¬ì©ììê² ì§ê¸ì íì©íì§ ìì ê²ì´ê¸° ë문ì
ëë¤.
ì´ ë³´í¸ì¥ì¹ë 꽤 믿ì ë§í©ëë¤. bank.comìì ìííë 모ë ìì
ì samesite ì¿ í¤ë¥¼ í¨ê» ì ì¡í기 ë문ì´ì£ .
íì§ë§ ì½ê°ì ë¶í¸í¨ë ê°ìí´ì¼ í©ëë¤.
ë§ì½ ì¬ì©ìê° ë©ëª¨ì¥ ë±ì bank.comì ìì²ì ë³´ë¼ ì ìë ë§í¬ë¥¼ 기ë¡í´ ëìë¤ê° ì´ ë§í¬ë¥¼ í´ë¦í´ ì ìíë©´ bank.comì´ ì¬ì©ì를 ì¸ìíì§ ëª»íë ìí©ì´ ë°ìí기 ë문ì
ëë¤. ì¤ì ë¡ ì´ë° ê²½ì° samesite=strict ìµì
ì´ ì¤ì ë ì¿ í¤ë ì ì¡ëì§ ììµëë¤.
ì´ë° 문ì ë ì¿ í¤ ë ê°ë¥¼ í¨ê» ì¬ì©í´ í´ê²°í ì ììµëë¤. "Hello, John"ê³¼ ê°ì íì ë©ìì§ë¥¼ ì¶ë ¥í´ì£¼ë "ì¼ë° ì¸ì¦(general recognition)"ì© ì¿ í¤, ë°ì´í° êµí ì ì¬ì©íë samesite=strict ìµì
ì´ ìë ì¿ í¤ë¥¼ ë°ë¡ ë¬ì ë§ì´ì£ . ì´ë ê² íë©´ ì¸ë¶ ì¬ì´í¸ë¥¼ íµí´ ì ê·¼í ì¬ì©ìë ì ìì ì¼ë¡ íì ë©ìì§ë¥¼ ë³¼ ì ììµëë¤. ì§ê¸ì 무조건 ìíì ì¬ì´í¸ë¥¼ íµí´ìë§ ìíëëë¡ ë§ë¤ë©´ ë©ëë¤.
samesite=lax
samesite=laxë ì¬ì©ì ê²½íì í´ì¹ì§ ìì¼ë©´ì XSRF 공격ì ë§ì ì ìë ëì¨í ì ê·¼ë²ì
ëë¤.
strictì ë§ì°¬ê°ì§ë¡ laxë ì¬ì´í¸ ì¸ë¶ìì ìì²ì ë³´ë¼ ë ë¸ë¼ì°ì ê° ì¿ í¤ë¥¼ ë³´ë´ë 걸 ë§ìì¤ëë¤. íì§ë§ ìì¸ì¬íì´ ì¡´ì¬í©ëë¤.
ìë ë ì¡°ê±´ì ëìì ë§ì¡±í ëë samesite=lax ìµì
ì ì¤ì í ì¿ í¤ê° ì ì¡ë©ëë¤.
-
âìì íâ HTTP ë©ìëì¸ ê²½ì°(ì: GET ë°©ì. POST ë°©ìì í´ë¹íì§ ìì).
ìì í HTTP ë©ìë 목ë¡ì RFC7231 ëª ì¸ìì íì¸í ì ììµëë¤. ìì í ë©ìëë ì½ê¸° ìì ë§ ìííê³ ì°ê¸°ë ë°ì´í° êµí ìì ì ìííì§ ììµëë¤. ì°¸ê³ ë¡, ë§í¬ë¥¼ ë°ë¼ê°ë íìë íì GET ë°©ìì´ê¸° ë문ì ìì í ë©ìëë§ ì°ì ëë¤.
-
ìì ì´ ìµìì ë 벨 íììì ì´ë£¨ì´ì§ ë(ë¸ë¼ì°ì 주ìì°½ìì URLì ë³ê²½íë ê²½ì°).
ëë¤ìì ìì ì ì´ ì¡°ê±´ì 충족í©ëë¤. íì§ë§
<iframe>ììì íìì´ ì¼ì´ëë ê²½ì°ë ìµìì ë 벨 íìì´ ìë기 ë문ì ì´ ì¡°ê±´ì 충족íì§ ëª»í©ëë¤. AJAX ìì² ëí íì íìê° ìëë¯ë¡ ì´ ì¡°ê±´ì 충족íì§ ëª»í©ëë¤.
ë¸ë¼ì°ì 를 ì´ì©í´ ì주 íë ìì
ì¸ "í¹ì URLë¡ ì´ëí기"를 ì¤ííë ê²½ì°, samesite=lax ìµì
ì´ ì¤ì ëì´ ìì¼ë©´ ì¿ í¤ê° ìë²ë¡ ì ì¡ë©ëë¤. ë
¸í¸ì ì ì¥ë ë§í¬ë¥¼ ì¬ë ê²ë í¹ì URLë¡ ì´ëíë íìì´ë¯ë¡ ì ì¡°ê±´ë¤ì 충족í©ëë¤.
íì§ë§ ì¸ë¶ ì¬ì´í¸ìì AJAX ìì²ì ë³´ë´ê±°ë í¼ì ì ì¡íë ë±ì ë³µì¡í ìì ì ìëí ëë ì¿ í¤ê° ì ì¡ëì§ ììµëë¤.
ì´ë° ì ì½ì¬íì´ ìì´ë ê´ì°®ë¤ë©´, samesite=lax ìµì
ì ì¬ì©ì ê²½íì í´ì¹ì§ ìì¼ë©´ì ë³´ìì ê°íí´ì£¼ë ë°©ë²ì¼ë¡ íì©í ì ìì ê²ì
ëë¤.
samesiteë ì¢ì ìµì
ì´ê¸´ íì§ë§, íê°ì§ 문ì ì ì´ ììµëë¤.
- ì¤ëë ë¸ë¼ì°ì (2017ë
ì´ì ë²ì )ìì
samesiteìµì ì ì§ìíì§ ììµëë¤.
ë°ë¼ì samesite ìµì
ì¼ë¡ë§ ë³´ì ì²ë¦¬ë¥¼ íê² ëë©´, 구ì ë¸ë¼ì°ì ìì ë³´ì 문ì ê° ë°ìí ì ììµëë¤.
구ì ë¸ë¼ì°ì ì ëìíì§ ëª»íë¤ë 문ì ê° ì긴 íì§ë§, samesite ìµì
ì XSRF í í° ê°ì ë¤ë¥¸ ë³´ì 기ë²ê³¼ í¨ê» ì¬ì©íë©´ ë³´ìì ê°íí ì ììµëë¤. 구ì ë¸ë¼ì°ì 를 ëë ì¬ì©íì§ ìë ëê° ì¤ë©´ XSRF í í° ìì íìíì§ ìê² ì£ .
httpOnly
ì´ ìµì ì ìë°ì¤í¬ë¦½í¸ì ì í ê´ê³ê° ìì§ë§, íí 리ì¼ì ìì±ë를 ëì´ê¸° ìí´ ì ì ì¸ê¸íê³ ëì´ê°ëë¡ íê² ìµëë¤.
httpOnly ìµì
ì ì¹ìë²ìì Set-Cookie í¤ë를 ì´ì©í´ ì¿ í¤ë¥¼ ì¤ì í ë ì§ì í ì ììµëë¤.
ì´ ìµì
ì ìë°ì¤í¬ë¦½í¸ ê°ì í´ë¼ì´ì¸í¸ 측 ì¤í¬ë¦½í¸ê° ì¿ í¤ë¥¼ ì¬ì©í ì ìê² í©ëë¤. document.cookie를 íµí´ ì¿ í¤ë¥¼ ë³¼ ìë ìê³ ì¡°ìí ìë ììµëë¤.
í´ì»¤ê° ì ìì ì¸ ìë°ì¤í¬ë¦½í¸ ì½ë를 íì´ì§ì ì½ì íê³ ì¬ì©ìê° ê·¸ íì´ì§ì ì ìí기를 기ë¤ë¦¬ë ë°©ìì 공격ì ìë°©í ë ì´ ìµì ì ì¬ì©í©ëë¤. ì°ë¦¬ê° ë§ë ì¬ì´í¸ì í´ì»¤ê° ì ìì ì¸ ì½ë를 ì½ì íì§ ëª»íëë¡ ìë°©í´ì¼ íì§ë§, ë²ê·¸ê° ìì íë¥ ì ì¸ì ë ì기 ë문ì í´ì»¤ê° ì½ë를 ì½ì í ê°ë¥ì±ì´ ìì ì ììµëë¤.
ì´ë° ìí©ì´ ë§ì íë ë°ìíë©´, ì¬ì©ìê° ì¹ íì´ì§ì 방문í ë document.cookie를 ë³¼ ì ìê³ ì¡°ìë í ì ìë í´ì»¤ì ì½ëë í¨ê» ì¤íë©ëë¤. ë¬¼ë¡ ì¿ í¤ì ì¸ì¦ ì ë³´ê° ìì´ì í´ì»¤ê° ì´ ì 보를 íì¹ê±°ë ì¡°ìí ì ìê² ë©ëë¤. ì¢ì§ ìì ìí©ì´ ë°ìíì£ .
íì§ë§ httpOnly ìµì
ì´ ì¤ì ë ì¿ í¤ë document.cookieë¡ ì¿ í¤ ì 보를 ì½ì ì ì기 ë문ì ì¿ í¤ë¥¼ ë³´í¸í ì ììµëë¤.
ë¶ë¡: ì¿ í¤ í¨ì
ì¿ í¤ë¥¼ ë¤ë£° ë ì ì©íê² ì¬ì©í ì ìë ëª ê°ì§ í¨ì를 ìê°í©ëë¤. document.cookie를 ìëì¼ë¡ ì¡°ìíì§ ìê³ ì´ í¨ìë¤ì íì©íë©´ ì¢ ë í¸ë¦¬íê² ì¿ í¤ë¥¼ ë¤ë£° ì ììµëë¤.
ì ì¬í 기ë¥ì íë ë¤ìí ì¿ í¤ ë¼ì´ë¸ë¬ë¦¬ê° ì¡´ì¬íë¯ë¡, ì´ ì½ëë ë°ëª¨ 목ì ì¼ë¡ ë´ì£¼ìë©´ ë ê² ê°ìµëë¤. ë°ëª¨ì´ì§ë§ ì¤ì íê²½ììë ëìíë ì½ëì ëë¤.
getCookie(name)
ì¿ í¤ì ì ê·¼íë ê°ì¥ ì§§ì ë°©ë²ì ì ê· ííì(regular expression) ì ì¬ì©íë ê²ì ëë¤.
ìë getCookie(name) í¨ìë 주ì´ì§ nameì ì¿ í¤ë¥¼ ë°íí©ëë¤.
// 주ì´ì§ ì´ë¦ì ì¿ í¤ë¥¼ ë°ííëë°,
// ì¡°ê±´ì ë§ë ì¿ í¤ê° ìë¤ë©´ undefined를 ë°íí©ëë¤.
function getCookie(name) {
let matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
ì ì½ëìì new RegExpë ; name=<value> í¨í´ì 찾기 ìí´ ëì ì¼ë¡ ìì±ë©ëë¤.
주ìí ì ì ì¿ í¤ê°ì ì¸ì½ë©ëì´ìë ìíì´ê¸° ë문ì getCookieë ë´ì¥ í¨ìì¸ decodeURIComponent를 ì´ì©í´ ì¿ í¤ê°ì ëì½ë©íë¤ë ì ì
ëë¤.
setCookie(name, value, options)
íì¬ ê²½ë¡(path=/)를 기본ì¼ë¡, 주ì´ì§ nameê³¼ value를 ê°ì§ ì¿ í¤ë¥¼ ì¤ì í©ëë¤(ë¤ë¥¸ 기본ê°ì ì¶ê°í ì ììµëë¤).
function setCookie(name, value, options = {}) {
options = {
path: '/',
// íìí ê²½ì°, ìµì
기본ê°ì ì¤ì í ìë ììµëë¤.
...options
};
if (options.expires instanceof Date) {
options.expires = options.expires.toUTCString();
}
let updatedCookie = encodeURIComponent(name) + "=" + encodeURIComponent(value);
for (let optionKey in options) {
updatedCookie += "; " + optionKey;
let optionValue = options[optionKey];
if (optionValue !== true) {
updatedCookie += "=" + optionValue;
}
}
document.cookie = updatedCookie;
}
// Example of use:
setCookie('user', 'John', {secure: true, 'max-age': 3600});
deleteCookie(name)
ë§ë£ 기ê°ì ììë¡ ì¤ì íë©´ ì¿ í¤ë¥¼ ìì í ì ììµëë¤.
function deleteCookie(name) {
setCookie(name, "", {
'max-age': -1
})
}
주ì: ì¿ í¤ë¥¼ ê°±ì íê±°ë ìì í ëë, ì¿ í¤ë¥¼ ì¤ì í ë ì§ì íë ëë©ì¸ì´ë ê²½ë¡ë¥¼ ì¬ì©í´ì¼ í©ëë¤.
í¨ê» ë³´ë©´ ì¢ì ìë£: cookie.js
ë¶ë¡: ìë íí° ì¿ í¤
ì¬ì©ìê° ë°©ë¬¸ ì¤ì¸ ëë©ì¸ì´ ìë ë¤ë¥¸ ëë©ì¸ìì ì¤ì í ì¿ í¤ë¥¼ "ìë íí° ì¿ í¤(third-party cookie)"ë¼ê³ ë¶ë¦ ëë¤.
ìì:
-
site.comì í¹ì íì´ì§ìì ì´ë¯¸ì§ ë°°ë(banner)를 ë¶ë¬ìµëë¤. ë°°ëë ë¤ë¥¸ ëë©ì¸<img src="https://ads.com/banner.png">ìì ê°ì ¸ìµëë¤. -
ads.comì ìë ì격 ìë²ë ë°°ëì í¨ê»Set-Cookieí¤ë를 ì ì¡í´ ë¸ë¼ì°ì ê°id=1234ì ê°ì ì¿ í¤ë¥¼ ì¤ì íëë¡ í©ëë¤. ì´ ì¿ í¤ëads.comëë©ì¸ìì ì¤ì í ê²ì´ê¸° ë문ìads.comììë§ ë³¼ ì ììµëë¤. -
ì¬ì©ìê°
ads.comì ë¤ì ì ìíë©´, ì격 ìë²ë ìì²ê³¼ í¨ê» ì ì¡ë°ì ì¿ í¤ìid를 ì´ì©í´ í´ë¹ ì ì 를 ì¸ìí©ëë¤. -
ì¬ì©ìê°
site.comì ë ëother.comì ì ìíê³ ì´ ì¬ì´í¸ìë ë°°ëê° ìì¼ë©´ads.comì ë ì¿ í¤ë¥¼ ì ì¡ë°ìµëë¤. ì´ ì¿ í¤ëads.comìì ì¤ì í ê²ì´ê¸° ë문ì´ì£ . ì´ë¥¼ ì´ì©í´ads.comì ì¬ì©ì를 ì¸ìíê³ , ì´ ì¬ì©ìê° ì´ë¤ ì¬ì´í¸ë¡ ì´ëíëì§ë¥¼ ì¶ì í©ëë¤.
ê´ê³ íì¬ë ì¬ì©ìì ì´ì© íí를 ì¶ì íê³ , ê´ê³ 를 ì ê³µí기 ìí´ ì¤ëì ë¶í° ìë íí° ì¿ í¤ë¥¼ ì¬ì©íê³ ììµëë¤. ìëíí° ì¿ í¤ë ì¿ í¤ë¥¼ ì¤ì í ëë©ì¸ì ì¢
ìë기 ë문ì ads.comì ì¬ì©ìê° ì´ë¤ ì¬ì´í¸ë¥¼ 방문íëì§ ì¶ì í ì ììµëë¤.
ê·¸ë°ë° ì¬ëë¤ì ëêµ°ê° ìì ì ê°ìíë 걸 ì¢ìíì§ ììµëë¤. ë¸ë¼ì°ì ì ì´ë° ì¿ í¤ë¥¼ ë¹íì±í í ì ìë 기ë¥ì´ ìëë°, ì´ ê¸°ë¥ì ì¬ì©íë©´ ì¶ì ì ë§ì ì ììµëë¤.
ì¬ê¸°ì ëíì¬ ëªëª 모ë ë¸ë¼ì°ì ë ìë íí° ì¿ í¤ë¥¼ ìí í¹ë³í ì ì± ì ëì íì¬ ê´ê³ íì¬ì ì¶ì ì ë§ì ì ìê² í©ëë¤.
- Safarië ìëíí° ì¿ í¤ë¥¼ ì ë©´ì ì¼ë¡ íì©íì§ ììµëë¤.
- Firefoxë ìë íí° ëë©ì¸ "ë¸ë 리ì¤í¸(black list)"를 ë§ë¤ì´ 리ì¤í¸ì ì¤ë¥¸ ëë©ì¸ì ìë íí° ì¿ í¤ë¥¼ ì°¨ë¨í©ëë¤.
<script src="https://google-analytics.com/analytics.js">ê°ì íê·¸ë¡ ìë íí° ëë©ì¸ìì ì¤í¬ë¦½í¸ë¥¼ ì½ì´ì¤ê³ , ì´ ì¤í¬ë¦½í¸ ìì document.cookieë¡ ì¿ í¤ë¥¼ ì¤ì íë ì½ëê° ìë¤ë©´, ì´ë ë§ë¤ì´ì§ ì¿ í¤ë ìëíí° ì¿ í¤ê° ìëëë¤.
ì¤í¬ë¦½í¸ìì ì¿ í¤ë¥¼ ì¤ì í ê²½ì°ì ë§ë¤ì´ì§ë ì¿ í¤ë íì¬ íì´ì§ì ëë©ì¸ì ìíê² ë©ëë¤. ì¤í¬ë¦½í¸ì ì ëì ìê´ìì´ ë§ì´ì£ .
ë¶ë¡: GDPR
ì´ ì£¼ì ë ìë°ì¤í¬ë¦½í¸ì ì í ê´ê³ê° ìì§ë§, ì¿ í¤ë¥¼ ì¤ì í ë ëª ì¬í´ì¼ í ì¬íì ëë¤.
EU(ì ë½ì°í©)ìë ì¬ì©ì ê°ì¸ ì ë³´ ë³´í¸ë¥¼ ê°ì íë ë²ë ¹ì¸ GDPRì´ ììµëë¤. ì¿ í¤ë¥¼ ì¶ì íë ê²½ì° ì¬ì©ìë¡ë¶í° ëª ìì ì¸ íê°ë¥¼ ì»ì´ì¼ íë¤ë ê²ì´ ì´ ë²ë ¹ì ì¤ì ìê±´ ì¤ íëì ëë¤.
ì´ ìê±´ì ì¿ í¤ë¥¼ ì´ì©í ì¬ì©ì ì¶ì , ìë³ì ê´í ë´ì©ì ë´ê³ ììµëë¤.
ë°ë¼ì ì¿ í¤ë¥¼ ì¤ì íê³ , ì´ ì¿ í¤ë¥¼ ì ë³´ ì ì¥ì ì©ëë¡ë§ ì¬ì©íë¤ë©´ ì´ ë²ë ¹ì´ ê°ì íë ì¬íì ì§í¬ íìê° ììµëë¤. ì¬ì©ì를 ì¶ì íê±°ë ìë³íì§ ìëë¤ë©´ ë§ì´ì£ .
íì§ë§, ì¸ì¦ ì¸ì ê³¼ í¨ê» ì¿ í¤ë¥¼ ì¤ì íê±°ë id를 ì¶ì íë¤ë©´ ì¬ì©ìì ëì를 ë°ëì ì»ì´ì¼ í©ëë¤.
ì¹ ì¬ì´í¸ë ë¤ìê³¼ ê°ì ë°©ë²ì¼ë¡ GDPRì ëìí ì ììµëë¤. ì´ ë°©ë²ì´ ì ì©ë ì¬ì´í¸ë¥¼ ì ìí´ ë³´ì ê²½íì´ ìì¼ë¦¬ë¼ ìê°í©ëë¤.
-
ì¸ì¦ë ì¬ì©ìì ëí´ìë§ ì¶ì ì¿ í¤ë¥¼ ì¤ì íë ¤ë ê²½ì°
ê°ì ììì âê°ì¸ ì ë³´ ì·¨ê¸ ë°©ì¹¨ ëìâ ê°ì íì¸ëì ë§ë¤ê³ , ì¬ì©ìê° ì´ì ëìí ê²½ì°ìë§ ì¶ì ì¿ í¤ë¥¼ ì¤ì í©ëë¤.
-
모ë ì¬ì©ì를 ëìì¼ë¡ ì¶ì ì¿ í¤ë¥¼ ì¤ì íë ¤ë ê²½ì°
ìµì´ 방문ììê² ì¿ í¤ì¤ì ì ëí ëì를 ì구íë "ìì ì°½"ì ë³´ì¬ì£¼ê³ , ì¬ì©ìê° ì´ì ëìí ê²½ì°ìë§ ì½í ì¸ ë¥¼ íìíê³ , ì¶ì ì¿ í¤ë¥¼ ì¤ì í©ëë¤. ìë¡ì´ 방문ìë ì´ë° ì ì°¨ê° ë²ê±°ë¡ë¤ê³ ìê°í ì ììµëë¤. ì½í ì¸ ë¥¼ ê°ë¦¬ë©´ì "무조건 í´ë¦í´ì¼ íë ì°½"ì ê·¸ ë구ë ë¬ê°ìíì§ ìì£ . íì§ë§ GDPRì ì¤ìíë ¤ë©´ ì´ ì°½ì´ ë°ëì ìì´ì¼ í©ëë¤.
GDPRì ì¿ í¤ì ëí´ìë§ ë¤ë£¨ì§ ìê³ , ì ë°ì ì¸ ë³´ì ì´ìì ê´í ë´ì©ì ë¤ë£¹ëë¤. ìì¸í ì¬íì ì´ íí 리ì¼ì ë²ì를 ë²ì´ë기 ë문ì GDPRì ëí ì´ì¼ê¸°ë ì¬ê¸°ì ë§ì¹ëë¡ íê² ìµëë¤.
ìì½
document.cookieë ì¿ í¤ì ì ê·¼í ì ìëë¡ í´ì¤ëë¤.
- ì°ê¸°ë í´ë¹ ì¿ í¤ì ê°ë§ ê°±ì í©ëë¤.
- ì¿ í¤ ì´ë¦ê³¼ ê°ì ê¼ ì¸ì½ë©í´ì¼ í©ëë¤.
- ì¿ í¤ íëê° ì°¨ì§íë ì©ëì ìµë 4KBê¹ì§ì´ê³ , ì¬ì´í¸ íëë¹ ì½ 20ì¬ ê°ë¥¼ íì©í©ëë¤(ë¸ë¼ì°ì ì ë°ë¼ ë¤ë¦).
ì¿ í¤ ìµì :
path=/ì 기본ê°ì íì¬ ê²½ë¡ì´ê³ , ì¤ì í ê²½ë¡ë ê·¸ íì ê²½ë¡ììë§ ì¿ í¤ ì 보를 ë³¼ ì ììµëë¤.domain=site.comìµì ì ìë¬´ë° ê°ì ì ë ¥íì§ ììë¤ë©´ ì¿ í¤ë¥¼ ì¤ì í ëë©ì¸ììë§ ì¿ í¤ ì 보를 ì»ì ì ììµëë¤. ëª ìì ì¼ë¡ ëë©ì¸ 주ì를 ì¤ì í ê²½ì°ì, í´ë¹ ëë©ì¸ì ìë¸ ëë©ì¸ììë ì¿ í¤ ì 보를 ì»ì ì ììµëë¤.expires/max-ageë ì¿ í¤ì ë§ë£ ìê°ì ì í´ì¤ëë¤. ì´ ìµì ì´ ìì¼ë©´ ë¸ë¼ì°ì ê° ë«í ë ì¿ í¤ë ê°ì´ ìì ë©ëë¤.secureë HTTPS ì°ê²°ììë§ ì¿ í¤ë¥¼ ì¬ì©í ì ìê² í©ëë¤.samesiteë ìì²ì´ ì¸ë¶ ì¬ì´í¸ìì ì¼ì´ë ë, ë¸ë¼ì°ì ê° ì¿ í¤ë¥¼ ë³´ë´ì§ 못íëë¡ ë§ìì¤ëë¤. XSRF 공격ì ë§ë ë° ì ì©í©ëë¤.
ì¶ê° ì¬í:
- ë¸ë¼ì°ì ì ë°ë¼ ìë íí° ì¿ í¤ë¥¼ íì©íì§ ìì ì ììµëë¤. Safarië 기본ì ì¼ë¡ ìë íí° ì¿ í¤ë¥¼ ê¸ì§í©ëë¤.
- ì¬ì©ìê° EU êµê° 거주ìì¸ ê²½ì° GDPRì ì¤ìí´ì¼ í©ëë¤. ë°ë¼ì, ì¬ì©ì ì¶ì ì ë°ëì ëì를 ì»ì´ì¼ í©ëë¤.
ëê¸
<code>í그를, ì¬ë¬ ì¤ë¡ 구ì±ë ì½ë를 ì½ì íê³ ì¶ë¤ë©´<pre>í그를 ì´ì©íì¸ì. 10ì¤ ì´ìì ì½ëë plnkr, JSBin, codepen ë±ì ìëë°ì¤ë¥¼ ì¬ì©íì¸ì.