파트너가 등록한 도메인에서만 사용할 수있는 API를 공개하고 있습니다. 콘텐츠는 부분적으로 공개되지만 (하지만 우리가 알고있는 도메인에만 표시되는 것이 바람직 함) 대부분 사용자에게 비공개입니다. 그래서:
결정 어떤 표시됩니다, 우리의 사용자는 우리와 함께 로그인해야하지만,이 별도로 처리됩니다.
어디 를 결정하려면데이터가 표시 공개 API 키를 사용하여 우리가 알고있는 도메인에 대한 액세스를 제한하고 무엇보다도 개인 사용자 데이터가 CSRF에 취약하지 않도록합니다 .
이 API 키는 실제로 누구나 볼 수 있으며 다른 방법으로 파트너를 인증하지 않습니다. 하지 않으며 REFERER가 필요하지 않습니다 . 그래도 안전합니다.
때 우리의 get-csrf-token.js?apiKey=abc123
IS 요청 :
열쇠를 찾아 abc123
데이터베이스 를 찾고 해당 키에 대한 유효한 도메인 목록을 가져옵니다.
CSRF 유효성 검사 쿠키를 찾습니다. 존재하지 않는 경우 보안 임의 값을 생성하여 입력하십시오. 하고 HTTP 전용 세션 쿠키 . 쿠키가 존재하는 경우 기존 임의 값을 가져옵니다.
API 키에서 CSRF 토큰을 만들고 쿠키에서 임의의 값을 만듭니다. 서명합니다 . (서버에 토큰 목록을 유지하는 대신 값에 서명합니다. 서명 된 토큰에서 두 값을 모두 읽을 수 있습니다. 괜찮습니다.)
응답이 캐시되지 않도록 설정하고 쿠키를 추가하고 다음과 같은 스크립트를 반환합니다.
var apiConfig = apiConfig || {};
if(document.domain === 'expected-domain.com'
|| document.domain === 'www.expected-domain.com') {
apiConfig.csrfToken = 'API key, random value, signature';
// Invoke a callback if the partner wants us to
if(typeof apiConfig.fnInit !== 'undefined') {
apiConfig.fnInit();
}
} else {
alert('This site is not authorised for this API key.');
}
노트:
위의 내용은 서버 측 스크립트가 요청을 위조하는 것을 방지하지 않지만 다음과 같은 경우 에만 도메인이 일치 하는지 확인합니다. 브라우저에서 요청한 합니다.
자바 스크립트에 대한 동일 출처 정책은 브라우저가로드 한 후 자바 스크립트 소스를 검사 XHR (아약스)를 사용할 수 없도록합니다. 대신 일반 브라우저는 <script src="https://our-api.com/get-csrf-token.js?apiKey=abc123">
(또는 동적 인 동급)을 사용해서 만로드 할 수 있으며 그런 다음 코드를 실행합니다. 물론 서버가 Cross-Origin 리소스 공유를 지원 해서는 안됩니다. 생성 된 JavaScript에 대해 또는 JSONP를 .
브라우저 스크립트는 document.domain
위 스크립트를로드하기 전에 의 값을 변경할 수 있습니다 . 그러나 동일한 출처 정책은 just , to 또는 일부 브라우저에서 다시 쓰기와 같은 접두사 를 제거 하여 도메인을 단축하는 것만 허용 합니다.subdomain.example.com
example.com
myblog.wordpress.com
wordpress.com
bbc.co.uk
co.uk
.
서버 측 스크립트를 사용하여 JavaScript 파일을 가져 오면 서버도 쿠키를 가져옵니다. 그러나 제 3 자 서버는 사용자의 브라우저가 해당 쿠키를 당사 도메인에 연결하도록 할 수 없습니다. 따라서 서버 측 스크립트를 사용하여 가져온 CSRF 토큰 및 유효성 검사 쿠키는 브라우저가 아닌 후속 서버 측 호출에서만 사용할 수 있습니다. 그러나 이러한 서버 측 호출에는 사용자 쿠키가 포함되지 않으므로 공개 데이터 만 가져올 수 있습니다. 이것은 서버 측 스크립트가 파트너의 웹 사이트에서 직접 스크랩 할 수있는 것과 동일한 데이터입니다.
사용자가 로그인 할 때 원하는 방식으로 사용자 쿠키를 설정하십시오. (사용자는 JavaScript를 요청하기 전에 이미 로그인했을 수 있습니다.)
서버에 대한 모든 후속 API 요청 (GET 및 JSONP 요청 포함)에는 CSRF 토큰, CSRF 유효성 검사 쿠키 및 사용자 쿠키 (로그온 한 경우)가 포함되어야합니다. 이제 서버는 요청을 신뢰할 수 있는지 결정할 수 있습니다.
유효한 CSRF 토큰이 있으면 브라우저에서로드 한 경우 JavaScript가 예상 도메인에서 로드 되었는지 확인 합니다.
유효성 검사 쿠키가 없는 CSRF 토큰의 존재 는 위조임을 나타냅니다.
CSRF 토큰과 CSRF 유효성 검사 쿠키가 모두 존재한다고해서 어떤 것도 보장되지 않습니다. 위조 된 서버 측 요청이거나 브라우저의 유효한 요청 일 수 있습니다. (지원되지 않는 도메인에서 만든 브라우저의 요청 일 수 없습니다.)
사용자 쿠키의 존재는 사용자가 로그온되었는지 확인하지만 사용자가 주어진 파트너의 구성원인지, 사용자가 올바른 웹 사이트를보고 있는지 확인하지 않습니다.
CSRF 유효성 검사 쿠키가 없는 사용자 쿠키의 존재 는 위조임을 나타냅니다.
사용자 쿠키가 있으면 브라우저를 통해 현재 요청이 이루어집니다. (사용자가 알 수없는 웹 사이트에 자신의 자격 증명을 입력하지 않는다고 가정하고 사용자가 자신의 자격 증명을 사용하여 서버 측 요청을 수행하는 것을 신경 쓰지 않는다고 가정합니다.) CSRF 유효성 검사 쿠키 도 있는 경우 해당 CSRF 유효성 검사 쿠키는 또한 브라우저를 사용하여 받았습니다. 다음으로 에도 유효한 서명 토큰 CSRF를 가지고, 그리고CSRF 유효성 검사 쿠키의 임의 번호가 해당 CSRF 토큰의 임의 번호와 일치하면 해당 토큰에 대한 JavaScript도 CSRF 쿠키가 설정된 이전 요청 중에 수신되어 브라우저를 사용합니다. 이것은 또한 토큰이 설정되기 전에 위의 JavaScript 코드가 실행되었으며 그 당시 도메인이 주어진 API 키에 대해 유효했음을 의미합니다.
따라서 서버는 이제 서명 된 토큰의 API 키를 안전하게 사용할 수 있습니다.
서버가 요청을 신뢰하지 않는 경우 403 Forbidden이 반환됩니다. 위젯은 사용자에게 경고를 표시하여 이에 대응할 수 있습니다.
CSRF 유효성 검사 쿠키는 서명 된 CSRF 토큰과 비교하기 때문에 서명 할 필요가 없습니다. 쿠키에 서명하지 않으면 각 HTTP 요청이 더 짧아지고 서버 유효성 검사가 조금 더 빨라집니다.
생성 된 CSRF 토큰은 무기한 유효하지만 유효성 검사 쿠키와 결합해서 만 유효하므로 브라우저가 닫힐 때까지 효과적입니다.
토큰 서명의 수명을 제한 할 수 있습니다. OWASP 권장 사항 을 충족하기 위해 사용자가 로그 아웃 할 때 CSRF 유효성 검사 쿠키를 삭제할 수 있습니다. 그리고 여러 파트너간에 사용자 별 난수를 공유하지 않으려면 쿠키 이름에 API 키를 추가 할 수 있습니다. 그러나 새로운 토큰이 요청되면 CSRF 유효성 검사 쿠키를 쉽게 새로 고칠 수 없습니다. 사용자가 여러 창에서 동일한 사이트를 탐색하고 단일 쿠키를 공유 할 수 있기 때문입니다 (새로 고침 할 때 모든 창에서 업데이트되고 그 후에 다른 창의 JavaScript 토큰은 더 이상 해당 단일 쿠키와 일치하지 않습니다.)
OAuth를 사용하는 사람들 은 JavaScript 아이디어를 얻은 OAuth 및 클라이언트 측 위젯을 참조하십시오 . 를 들어 서버 측 우리가 도메인을 제한하기 위해 자바 스크립트 코드에 의존 할 수있는 API의 사용, 우리는 비밀 키 대신의 공개 API 키를 사용하고 있습니다.