it-gundan.com

안티 -CSRF 양식 토큰을 구현하는 올바른 방법은 무엇입니까?

CSRF 에 대해 완전히 알고 있으며 이미 안전한 형식을 구현했지만 아직 결과에 만족하지 못했습니다.

사용자 이름, 양식 정보 및 salt 의 md5로 토큰을 만들어 세션에 저장했습니다. 이것은 탭 브라우징 (활성 해시 배열을 유지하여 해결할 수 있음) 및 타이밍에 문제가 있습니다. 예를 들어 해시가 작동하도록하고 싶습니다. 10 분이지만 해시에 시간 관련 변수를 어떻게 넣습니까?

누구든지 CSRF 보안을 올바르게 만드는 방법을 설명하는 좋은 자료를 알려줄 수 있습니까?

34
naugtur

CSRF 보호를 올바르게 구축하는 가장 좋은 방법 :

하지마.

대부분의 일반적인 프레임 워크에는이 보호 기능이 이미 내장되어 있거나 (ASP.NET, Struts, Ruby 생각합니다)) 이미 검증 된 기존 라이브러리가 있습니다 (예 : OWASP의 CSRFGuard ).

상황에 따라 다른 옵션은 사용자의 재 인증을 강제하지만 구체적이고 민감한 작업에만 적용하는 것입니다.


귀하의 의견에 따라 직접 구현 해야하는 경우 솔루션은 나쁘지 않지만 단순화합니다.
암호화 랜덤 논스 (충분히 긴)를 생성하여 세션 메모리에 저장하고 X 분마다 변경 (만료 시간도 세션에 저장) 할 수 있습니다. 각 양식에서 nonce를 숨겨진 양식 필드에 포함시키고 양식을 게시 할 때 해당 값을 비교하십시오.
양식 토큰이 일치하면 확실합니다. 그렇지 않은 경우 예를 들어 수락 할 수 있습니다. Edge 사례를 처리하기 위해 이전 토큰도 마찬가지입니다.

나는 이것을 스스로 구현하려는 시도가 너무 많이 실패했다고 말해야하지만 실제로이 경로를 권장합니다. 이를 위해 최소한의 패키지를 찾는 것이 좋습니다.

25
AviD

OWASP에 대한 좋은 설명이 있습니다 : OWASP CSRF Prevention Cheat Sheet

요컨대 그들은 두 가지 방법이 있다고 말합니다.

  1. 각 사용자 세션에 임의의 토큰을 추가하십시오. 이 토큰이 존재하고 올바른 경우에만 변경 사항이 적용되며, 그렇지 않으면 요청이 거부되어야합니다. GET 요청은 다른 위치 (브라우저 히스토리, 로그 파일 등)로 토큰을 유출 할 수 있으므로 토큰은 POST 요청)으로 만 전송되어야합니다.

    요청 당 토큰을 생성 할 수도 있지만 사용성 문제가 발생합니다. 예를 들어 뒤로 버튼이 더 이상 제대로 작동하지 않습니다. 그러나 물론 보안은 향상 될 것입니다.

    또한 토큰이 TLS를 통해서만 전송되도록 (보안을 더욱 강화하기 위해) 중간 문제에 사람이 없는지 확인하십시오.

  2. 다른 옵션은 일종의 챌린지-응답 (예 : 보안 문자 또는 일회성 토큰)을 사용하는 것입니다.

OWASP 페이지에는 작동하지 않는 몇 가지 측정 값도 나와 있습니다. 이것들은

  • (비밀) 쿠키 사용
  • GET 요청을 사용하지 않음
  • 다단계 거래
  • URL 재 작성
27
Andreas Arnold

@Andreas Arnold 이외에도 대안이 있습니다. OWasp에서 Encrypted Token Pattern를 구현했습니다.

Csrf 공격을 방지하는 것 외에도 객체 보안을 구현할 수 있다는 이점이 있습니다.

객체 수정 권한이있는 사람 만 그렇게 할 수 있습니다. 다른 것들은 정확한/올바른 암호문이나 키를 가지지 않을 것입니다. 보통 sessionId, timestamp, userId 및/또는 recordId를 암호화합니다.

timestamp는 replayAttacks를 방지합니다. sessionid는이 세션에 대한 변경 사항 만 분리합니다. userId는이 사용자에 대한 변경 사항 만 분리합니다. recordId를 포함 시키면 추가 처리 비용으로 더 많은 보안을 얻을 수 있습니다.

3
Nasir