2013-05-01 4 views
4

지금 당장 세션 당 csrf 토큰이 있습니다. 그리고 숨겨진 필드를 사용하여이 토큰 JSP를 추가합니다. CSRF : 요청마다 토큰 생성

token = (String) session.getAttribute(CSRF_TOKEN_FOR_SESSION_NAME); 
    if (null==token) { 
     token = UUID.randomUUID().toString(); 
     session.setAttribute(CSRF_TOKEN_FOR_SESSION_NAME, token); 
    } 

모든 요청에 ​​대해

, 여기

//calls the above snippet and this time token will not be null 
String st = CSRFTokenManager.getTokenForSession(request.getSession()); 
String rt = CSRFTokenManager.getTokenFromRequest(request); 

는, using이이 문자열 true 또는 false를 반환 하나를 비교할 같습니다 : 다음 코드는 세션 당 하나를 제공합니다.

제 질문은 세션에서 토큰을받지 않고 요청마다 토큰을 생성하려고하면 어떻게됩니까? 비교하는 동안, 나는 세션과 요청에서 얻을 것이다. 이 좋은 생각이거나 뭔가 빠졌습니까?

대신 위의 조각을 사용하여, 나는

//for every request generate a new and set in session 
    token = UUID.randomUUID().toString(); 
    session.setAttribute(CSRF_TOKEN_FOR_SESSION_NAME, token); 

    //get the token from session and request and compare 
    String st = (String) request.getSession().getAttribute("CSRF_TOKEN_FOR_SESSION_NAME"); 
    String rt = CSRFTokenManager.getTokenFromRequest(request); 
+0

토큰을 생성하고 세션에 저장하지 않을 수 있습니다. 그것을 폼에 숨겨진 필드로 추가하고 쿠키로 추가하십시오. 요청을 받으면 필드와 쿠키의 값을 비교하십시오. –

+0

확실하지는 않지만 쿠키는 CSRF 공격에 취약합니다. –

+0

@ user1609085 CSRF 토큰의 아이디어는 공격자가 다른 사용자 A를 가장 한 "숨겨진"요청을 보내려고한다는 것입니다. 공격자는 다른 웹 사이트를 사용하여 주입 할 수 있습니다 일부 악의적 인 자바 스크립트 코드는이 사이트에서 쿠키 또는 특수 헤더 (브라우저가 공격자에게 그렇게하지 못하게)에 토큰을 보낼 수 없다는 점이 중요합니다. 즉 토큰이 일반적으로 거기에 들어간 이유입니다. – le0diaz

답변

5

당신은 위에서 언급 한 흐름의 주위에 반전 할 것 다음으로 이동합니다. 비교할 때마다 새 토큰을 만들어야합니다.

  • 사용자의 방문 페이지 1 세션에 저장 TokenA : 사용자가 브라우저의 뒤로 버튼을 안타 토큰 당 요청하기

    하나의 큰 단점이다.

  • 사용자가 Page2에 대한 링크를 클릭하여 TokenA을 제출합니다. 앱에서 세션 중에 TokenA을 확인하고 사용자에게 TokenB을 제공합니다.
  • 사용자가 페이지 1로 돌아 가기 위해 뒤로 버튼을 누르면 세션 정보가 업데이트되지 않습니다.
  • 페이지 1은 여전히 ​​사용자가 링크를 클릭하거나 TokenA를 제출 페이지 3에 양식을 제출, TokenA에 대한 정보를 가지고 있지만, 세션이 약 TokenB
  • 앱은 이것을 CSRF 공격
  • 이 때문에

고려 알고, 토큰을 언제, 어떻게 업데이트 할 것인지에 대해 세심한주의를 기울여야합니다.

+0

내 응용 프로그램에서 이러한 유형의 구성이 필요합니다.이 유형의 구성에 대해 제안 해 드리겠습니다. – user243405

+0

안녕하세요, 저는 오래된 게시물 인 것을 알고 있지만 지금 당장 같은 상황에 처해 있습니다. 내 이해를 확인해 주시겠습니까 : 1) 사용자가 페이지 1을 방문하면 String st = (String) request.getSession(). getAttribute ("CSRF_TOKEN_FOR_SESSION_NAME"); 호출되어 null입니다. 이 문자열 뒤에 rt = CSRFTokenManager.getTokenFromRequest (request); 이 호출되어 세션 속성에 새 값을 생성하고 설정합니다. 비교는 언제 끝날까요? – Aman

+0

사용자가 페이지를 새로 고침하면 어떻게됩니까? – Aman

-1

제이가 제안한 해결책 외에도 클라이언트 응답에 다양한 캐시 제어 헤더를 설정하여 웹 페이지 캐싱을 피하는 것이 좋습니다.

+0

약간의 문맥이 없으면 나는 당신의 제안이 정말로 나쁘다고 생각한다. Jay가 설명한 흐름은 전혀 실용적이지 않습니다. GET 요청 시간의 99 %는 데이터를 업데이트하지 않기 때문에 시스템이 잘못 설계된 이유입니다. 그래서 당신은 POST | PUT | DELETE | HEAD ...를 보호 할 뿐이며, 폼에서 돌아 오는 사람들에게는 잘 디자인 된 앱에서는 뒤로 버튼 상황이 일반적이지 않습니다. 일반적으로 리디렉션 양식을 게시 한 후 브라우저 기록으로 돌아갈 때 양식을 다시 게시 할 수 없습니다. – le0diaz