호스팅 페이지와 프런트 API의 웹 보안
호스팅 로그인, 계정 포털, 이메일 페이지(인증, 비밀번호 재설정, 초대)와 이들이 호출하는 브라우저 API는 모든 요금제에서 고정된 웹 보안 기준을 따릅니다. 이러한 보호 기능은 끌 수 있는 설정이 아닙니다. 사용자가 제어할 수 있는 설정은 브라우저에서 OAuth 엔드포인트를 호출할 수 있는 웹 출처를 지정하는 것뿐입니다.
사이트 간 요청 위조(CSRF)
상태를 변경하는 요청은 아무것도 읽거나 변경하기 전에 확인됩니다.
- 출처 확인. 호스팅 로그인 API 또는 인증이나 재설정 페이지에 대한 상태 변경 요청에는 환경의 로그인 호스트와 정확히 일치하는
Origin헤더가 있어야 합니다. 다른 출처는origin_not_allowed로 거부됩니다. - 동의 화면. 동의 화면의 폼 제출은
Origin이 페이지 자체 호스트가 아니거나,Sec-Fetch-Site가 있고 값이same-origin이 아닌 경우 거부됩니다. - 폼 토큰. 각 로그인 트랜잭션과 각 이메일 폼에는 환경별 키에서 HMAC-SHA256으로 생성된 고유한 CSRF 토큰이 있습니다. 로그인 API는 이 토큰을
Idp-Csrf-Token헤더로 받으며, 한 폼의 토큰은 다른 폼에서 사용할 수 없습니다. 토큰은 상수 시간 방식으로 비교됩니다. - 쿠키. 로그인 상태를 담는 쿠키는
SameSite=Lax를 사용합니다(아래 참조). 따라서 다른 사이트에서 시작된 요청에는 이 쿠키가 전송되지 않습니다.
교차 출처 요청(CORS)
CORS는 브라우저 애플리케이션이 호출하는 OAuth 엔드포인트에서만 응답합니다. 토큰, 해지, 푸시된 인가 요청, userinfo 엔드포인트가 여기에 해당합니다. 이는 공개 단일 페이지 애플리케이션(spa 유형)에만 적용됩니다.
allowed_web_origins(https://host[:port], 최대 20개, 와일드카드 없음)로 애플리케이션별 허용 출처를 설정합니다. 애플리케이션 생성을 참조하십시오.- 브라우저의 사전 요청(preflight)에는 어떤 애플리케이션이 호출하는지가 포함되지 않으므로, 환경의 활성 공개 단일 페이지 애플리케이션이 허용한 출처의 합집합으로 응답합니다. 실제 요청은 이후 호출한 애플리케이션의 출처 목록으로 확인됩니다.
- 해당 애플리케이션의 목록에 없는 출처는
403 origin_not_allowed로 거부되며Access-Control-Allow-Origin헤더를 받지 않습니다. - 허용된 출처는 정확히 그대로 반환됩니다.
*와null은 전송되지 않으며,Access-Control-Allow-Credentials도 전송되지 않습니다. 모든 교차 출처 응답에는Vary: Origin이 포함됩니다. - 로그인 호스트 자체에서 보낸 요청은 교차 출처가 아니므로 영향을 받지 않습니다.
로그인 후 리디렉션
Next.js SDK를 사용하는 경우 returnTo는 사용자 앱의 경로여야 합니다. 전체 URL이나 //evil.example과 같은 값은 무시되고 사용자는 /로 이동합니다. Next.js SDK를 참조하십시오.
보안 헤더
호스팅 페이지는 모든 응답에 다음 헤더를 설정합니다.
| 헤더 | 값 |
|---|---|
Content-Security-Policy |
default-src 'none'; 스크립트는 응답마다 새로 생성된 nonce가 있는 경우에만 허용; style-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; upgrade-insecure-requests; 스크립트에는 Trusted Types 필요 |
Reporting-Endpoints 및 report-to |
정책 위반은 같은 호스트의 /u/csp-report로 보고됨 |
X-Frame-Options |
DENY: 호스팅 페이지는 프레임에 삽입할 수 없음 |
X-Content-Type-Options |
nosniff |
Referrer-Policy |
no-referrer |
Cross-Origin-Opener-Policy |
same-origin |
Permissions-Policy |
카메라, 마이크, 위치, 결제, USB, 시리얼, HID, 블루투스는 비활성화됨. 패스키 요청은 페이지 자체에 대해 허용됨 |
Cache-Control |
no-store |
이 정책은 인라인 스크립트와 unsafe- 키워드를 허용하지 않습니다. 폼 제출은 페이지 자체 호스트로 제한됩니다. 동의 화면에서는 정책이 요청 중인 애플리케이션의 리디렉션 주소도 허용하므로, 결정 결과를 해당 애플리케이션으로 되돌릴 수 있습니다.
보고 엔드포인트는 8KiB 이하의 브라우저 위반 보고서만 받으며, IP 주소별로 요청 빈도가 제한됩니다. 보고서는 지시문별로 집계됩니다. 기록될 때 쿼리 문자열, 프래그먼트, 사용자 정보는 포함되지 않습니다.
Strict-Transport-Security
keenauth.app의 환경 호스트는max-age=63072000; includeSubDomains를 전송합니다.- 사용자 지정 도메인은
includeSubDomains없이max-age=63072000만 전송합니다. KeenAuth는 도메인의 다른 하위 도메인에 대해 결정할 수 없으므로, 이 선택은 사용자에게 남겨져 있습니다.
쿠키
로그인 상태 쿠키는 __Host- 접두사를 사용합니다. 따라서 브라우저는 HTTPS를 통해, Path=/로, Domain 속성 없이 설정된 경우에만 이 쿠키를 허용합니다. 형제 하위 도메인에서는 설정할 수 없습니다.
| 쿠키 | 플래그 | 용도 |
|---|---|---|
__Host-idp_session |
Secure, HttpOnly, SameSite=Lax |
사용자의 세션. 수명은 세션의 절대 만료 시점에 끝남 |
__Host-idp_device |
Secure, HttpOnly, SameSite=Lax |
기기 인식 |
__Host-idp_ltx 및 __Host-idp_azr_* |
Secure, HttpOnly, SameSite=Lax |
로그인 또는 인가 시도를 이를 시작한 브라우저에 연결 |
__Host-idp_fed_bind |
Secure, HttpOnly, SameSite=None |
엔터프라이즈 SAML 로그인을 위한 단기 바인딩. ID 공급자가 다른 사이트에서 다시 게시하므로 Lax를 사용하면 쿠키가 제거됨 |
쿠키 값은 페이지 스크립트에서 읽을 수 없습니다(HttpOnly).