답변:
이 사람은 빠르다 :
당신은 그것이 있어야한다고 생각할 수도 있지만 실제로는 그렇지 않습니다!
쿠키 이름과 값에 허용되는 문자는 무엇입니까?
고대 Netscape cookie_spec 에 따르면 전체 NAME=VALUE
문자열은 다음과 같습니다.
세미콜론, 쉼표 및 공백을 제외한 일련의 문자
그래서 -
일을해야하고, 내가 여기에있어 브라우저에서 확인을 것으로 보인다; 어디에 문제가 있습니까?
위의 의미로 :
=
포함하는 것이 합법적이지만 잠재적으로 모호 할 수 있습니다. 브라우저는 항상 =
문자열 의 첫 번째 기호에서 이름과 값을 분리 하므로 실제로 =
는 NAME이 아닌 VALUE에 기호를 넣을 수 있습니다 .언급되지 않은 것은 Netscape가 스펙 작성에 끔찍하지만 브라우저에서 지속적으로 지원되는 것 같습니다.
NAME 또는 VALUE는 빈 문자열 일 수 있습니다.
=
문자열에 기호 가 없으면 브라우저는이를 빈 문자열 이름을 가진 쿠키로 취급합니다 . 즉와 Set-Cookie: foo
동일합니다 Set-Cookie: =foo
.
브라우저가 빈 이름으로 쿠키를 출력하면 등호를 생략합니다. 그래서 Set-Cookie: =bar
낳는다 Cookie: bar
.
등호 주위의 공백은 잘리지 만 이름과 값의 쉼표와 공백은 실제로 작동하는 것 같습니다.
제어 문자 ( \x00
~ \x1F
더하기 \x7F
)는 허용되지 않습니다
언급되지 않았고 브라우저가 완전히 일치하지 않는 것은 ASCII가 아닌 문자입니다 (유니 코드).
실제로 쿠키에는 ASCII가 아닌 문자를 전혀 사용할 수 없습니다. 유니 코드, 제어 코드 또는 기타 임의 바이트 시퀀스를 사용하려는 경우 cookie_spec은 사용자가 선택한 임시 인코딩 체계를 사용하도록 요구하고 (JavaScript에서 생성 한대로) URL 인코딩을 encodeURIComponent
합리적인 선택으로 제안 합니다.
의 측면에서 실제 표준이 성문화 쿠키 행동 몇 가지 시도를하고 있지만, 아무도 지금까지 실제로 현실 세계를 반영 없다.
RFC 2109 는 원래 Netscape cookie_spec을 체계화하고 수정하려는 시도였습니다. 이 표준에서는 RFC 2616 토큰 (a -
는 여전히 허용됨)을 사용하므로 더 많은 특수 문자가 허용되지 않으며 다른 문자와 함께 따옴표로 묶인 문자열에 값만 지정할 수 있습니다. 어떤 브라우저도 한계, 인용 된 문자열의 특수 처리 및 이스케이프 처리 또는이 사양의 새로운 기능을 구현 한 적이 없습니다.
RFC 2965 는 2109를 정리하고 '버전 2 쿠키'체계로 더 많은 기능을 추가했습니다. 아무도 그 중 어느 것도 구현하지 않았습니다. 이 스펙은 이전 버전과 동일한 토큰 및 따옴표로 묶인 문자열 제한을 가지고 있으며, 말도 안되는 많은 부하입니다.
RFC 6265 는 역사적 혼란을 해결하기위한 HTML5 시대의 시도입니다. 여전히 실제와 정확히 일치하지는 않지만 이전 시도보다 훨씬 낫습니다. 브라우저가 지원하는 것 중 적어도 일부는 작동하지만 작동하지 않는 구문을 도입하지는 않습니다 (이전 인용 문자열) .
6265에서 쿠키 이름은 여전히 RFC 2616으로 지정됩니다. token
즉, 영숫자 더하기에서 선택할 수 있습니다.
!#$%&'*+-.^_`|~
쿠키 값에서는 (브라우저에 의해 필터링 된) 제어 문자와 (일관되지 않은) 비 ASCII 문자를 공식적으로 금지합니다. 공간, 쉼표 및 세미콜론에 대한 cookie_spec의 금지를 유지하고 실제로 이전 RFC를 구현 한 가난한 바보와의 호환성을 위해 전체 값을 감싸는 따옴표 이외의 백 슬래시와 따옴표를 금지했습니다 (그러나이 경우 따옴표는 여전히 인코딩 체계가 아닌 값). 따라서 알파 플러스와 함께 당신을 떠나십시오 :
!#$%&'()*+-./:<=>?@[]^_`{|}~
실제로 우리는 원래의 최악의 Netscape cookie_spec을 사용하고 있으므로 쿠키를 소비하는 코드는 거의 모든 것을 만날 준비가되어 있어야하지만 쿠키를 생성하는 코드의 경우 RFC 6265의 하위 집합을 따르는 것이 좋습니다.
Name="Va;lue"; max-age...
합니다. 브라우저에서는 작동하지 않으며 RFC 6265에서는 허용되지 않습니다. RFC 6265는 2965를 대체하도록 제안되었으며 현실을 조금 더 잘 반영하려고 시도합니다.
1*<any CHAR except CTLs or separators>
과 분리되어 (
, )
, <
, >
, @
, ,
, ;
, :
, \
, "
, /
, [
, ]
, ?
, =
, {
, }
, SP
와 HT
, 쿠키 이름은 alphanums해야하므로 플러스!#$%&'*+-.?^_`|~
ASP.Net에서는 System.Web.HttpUtility
쿠키에 쓰기 전에 쿠키 값을 안전하게 인코딩하고 읽을 때 쿠키를 원래 형식으로 다시 변환하는 데 사용할 수 있습니다 .
// Encode
HttpUtility.UrlEncode(cookieData);
// Decode
HttpUtility.UrlDecode(encodedCookieData);
이렇게하면 앰퍼샌드가 중지되고 값이 쿠키에 기록 될 때 값을 여러 이름 / 값 쌍으로 분할하는 부호와 같습니다.
일반적으로 브라우저마다 다릅니다. 안전한 측면을 유지하기 위해 base64는 JSON 객체를 인코딩하고 모든 것을 저장합니다. 그렇게하면 해독하고 JSON을 구문 분석해야합니다. base64에 사용 된 모든 문자는 모든 브라우저가 아니라도 대부분 잘 재생됩니다.
여기에 가능한 한 적은 단어가 있습니다 . 탈출 할 필요가없는 캐릭터에 집중하십시오 :
쿠키의 경우 :
abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789!#$%&'()*+-./:<>?@[]^_`{|}~
URL의 경우
abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789.-_~!$&'()*+,;=:@
쿠키 및 URL (교차로)
abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789!$&'()*+-.:@_~
당신이 대답하는 방법입니다.
쿠키의 경우 = 는 일반적으로 쿠키 값을 설정하는 데 사용되므로 제거되었습니다.
URL의 경우 =가 유지되었습니다. 교차로는 분명히 없다.
var chars = "abdefghijklmnqrstuvxyz"; chars += chars.toUpperCase() + "0123456789" + "!$&'()*+-.:@_~";
특히 쿠키가 마지막 문자를 발견하면 큰 따옴표로 묶인 Java 쿠키 환경에서 이스케이프가 여전히 발생하고 예기치 않은 상황이 발생합니다.
안전을 위해 A-Za-z1-9를 사용하십시오. 그게 내가 할 일입니다.
2011 년 4 월에 발표 된 최신 rfc6265 :
cookie-header = "Cookie:" OWS cookie-string OWS
cookie-string = cookie-pair *( ";" SP cookie-pair )
cookie-pair = cookie-name "=" cookie-value
cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
; US-ASCII characters excluding CTLs,
; whitespace DQUOTE, comma, semicolon,
; and backslash
당신이 보면 @bobince의 대답 당신은 새로운 규제가 더 엄격 것을 알 수있다.
간단합니다 :
<쿠키 이름>은 제어 문자 (CTL), 공백 또는 탭을 제외한 모든 US-ASCII 문자 일 수 있습니다. 또한 다음과 같은 구분 기호 문자를 포함해서는 안됩니다. () <> @,; : \ "/ []? = {}.
<cookie-value>는 큰 따옴표로 선택적으로 설정할 수 있으며 CTL, 공백, 큰 따옴표, 쉼표, 세미콜론 및 백 슬래시를 제외한 모든 US-ASCII 문자가 허용됩니다. 인코딩 : 많은 구현은 쿠키 값에 대해 URL 인코딩을 수행하지만 RFC 사양에 따라 필요하지는 않습니다. 허용되는 문자에 대한 요구 사항을 충족시키는 데 도움이됩니다.
링크 : https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Directives
한 가지 더 고려하십시오. 최근에 PHP 스크립트에 게시 된 일부 민감한 데이터를 암호화 된 쿠키로 변환하고 반환하는 데 필요한 스키마를 구현했습니다.이 쿠키는 '안전한'것으로 보장 된 모든 base64 값을 사용했습니다. 따라서 RC4를 사용하여 데이터 항목을 정식으로 암호화했습니다. base64_encode를 통한 출력과 쿠키를 사이트에 행복하게 반환했습니다. base64로 인코딩 된 문자열에 "+"기호가 포함될 때까지 테스트가 잘 진행되는 것 같았습니다. 문자열은 아무 문제없이 페이지 쿠키에 기록되었습니다. 쿠키가 변경되지 않은 상태로 작성되었는지 확인한 다음 내 PHP라는 후속 페이지에서 $ _COOKIE 배열을 통해 쿠키를 얻었을 때 문자열에 "+"기호가없는 것을 발견했습니다. ASCII 공간.
쿠키를 사용하여 임의의 데이터를 "안전하게"저장하기 위해 base64를 사용하는 것에 대한 수많은 참고 자료를 제시 한 이후로이 시나리오에 대해 읽은 유사한 해결되지 않은 불만이 얼마나 많은지를 고려할 때 문제를 지적하고 인정할만한 해결책을 제시 할 것이라고 생각했습니다.
데이터 조각에 대해 암호화를 수행 한 다음 base64_encode를 사용하여 "쿠키 안전"으로 설정 한 후이를 통해 출력 문자열을 실행하십시오.
// from browser to PHP. substitute troublesome chars with
// other cookie safe chars, or vis-versa.
function fix64($inp) {
$out =$inp;
for($i = 0; $i < strlen($inp); $i++) {
$c = $inp[$i];
switch ($c) {
case '+': $c = '*'; break; // definitly won't transfer!
case '*': $c = '+'; break;
case '=': $c = ':'; break; // = symbol seems like a bad idea
case ':': $c = '='; break;
default: continue;
}
$out[$i] = $c;
}
return $out;
}
여기에서는 쿠키로 사용하기 위해 인코딩 된 값을 페이지에 반환하기 전에 "+"를 다른 "쿠키 안전"문자로 대체하고 있습니다. 처리되는 문자열의 길이는 변경되지 않습니다. 동일한 (또는 사이트의 다른 페이지)가 내 PHP 스크립트를 다시 실행하면 문자가 누락되지 않고이 쿠키를 복구 할 수 있습니다. 쿠키를 내가 만든 것과 동일한 fix64 () 호출을 통해 다시 전달해야한다는 것을 기억해야하며 거기에서 일반적인 base64_decode ()로 해독하고 스키마의 다른 암호 해독을 수행 할 수 있습니다.
쿠키에 사용 된 base64 문자열을 손상없이 PHP로 다시 전송할 수 있도록 PHP에서 설정할 수있는 설정이있을 수 있습니다. 그 동안 이것은 작동합니다. "+"는 "법적"쿠키 값일 수 있지만 이러한 문자열을 PHP로 다시 전송하려면 ($ _COOKIE 배열을 통해) PHP로 다시 전송하려는 경우 다시 처리하여 제거하는 것이 좋습니다. 문제가있는 문자를 복구하고 복구 후 복원하십시오. 선택할 수있는 다른 "쿠키 안전"문자가 많이 있습니다.
나중에 변수를 사용하는 경우 path
실제로 악센트 문자를 사용할 수 있지만 실제로 브라우저 경로와 일치하지는 않습니다. 이를 위해서는 URIEncode해야합니다. 그래서 이렇게 :
const encodedPath = encodeURI(myPath);
document.cookie = `use_pwa=true; domain=${location.host}; path=${encodedPath};`
따라서 "허용 된"문자는 사양에 포함 된 것 이상일 수 있습니다. 그러나 사양 내에서 유지하고 URI 인코딩 문자열을 사용하여 안전해야합니다.
;
이 큰 따옴표로 묶인 한 문자를 가질 수 있다고 명시하고 있습니까? 같은 :Set-Cookie: Name=Va";"lue; Max-Age=3600