XSRF-TOKEN 와 X-CSRF-TOKEN
HTTP 401 응답
업체에서 HTTP PUT 요청시
TOKEN값을 헤더에 세팅해서 보내달라고 하여
헤더(Request Header)에 X-CSRF-TOKEN와 토큰 값을 추가했다.
포스트맨(Post-man)으로 PUT 요청 테스트시 잘 되는데
내가 만든 호출 API에서 PUT 요청시 401응답이 왔다.
HTTP 401 상태 코드(Unauthorized) 이란?
401 Unauthorized
HTTP 상태 중 401(Unauthorized)는 클라이언트가 인증되지 않았거나,
유효한 인증 정보가 부족하여 요청이 거부되었음을 의미하는 상태값이다.
즉, 클라이언트가 인증되지 않았기 때문에 요청을 정상적으로 처리할 수 없다고 알려주는 것이다.
401(Unauthorized) 응답을 받는 대표적인 경우는 로그인이 되어 있지 않은 상태에서 무언가 요청을 하는 경우이다.
=> 클라이언트가 인증되지 않았거나, 유효한 인증 정보가 부족하여 요청이 거부
httpbin.org 로 찔러서
내가 보낸 요청을 보았는데도
포스트맨이랑 딱히 다른점이 없었다..
아래는 내가 보낸 헤더 내용이다.
httpbin.org Request Headers
"headers": {
"Accept": "application/json",
"Agency-Id": "TEST",
"Cache-Control": "no-cache",
"Content-Length": "205",
"Content-Type": "application/json",
"Host": "httpbin.org",
"Pragma": "no-cache",
"User-Agent": "Jersey/2.23.2 (HttpUrlConnection 1.8.0_292)",
"X-Amzn-Trace-Id": "Root=1-xxxx",
"X-Csrf-Token": "3xxxxx-fxxxx-4xxx-8xxx-d0xxxxxxxx"
}
Post-man Request Headers
agency-id: TEST
X-CSRF-TOKEN: 3xxxxx-fxxxx-4xxx-8xxx-d0xxxxxxxx
Content-Type: application/json
User-Agent: PostmanRuntime/7.36.3
Accept: application/json
Host: api.greenit.cc:21001
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 261
Cookie: XSRF-TOKEN=3xxxxx-fxxxx-4xxx-8xxx-d0xxxxxxxx
다른 점이라고 하면,
포스트 맨에서는
Cookie: XSRF-TOKEN=3xxxxx-fxxxx-4xxx-8xxx-d0xxxxxxxx
위 값을 보내주는거 말고는 없었다..
설마 이게 문제일까 싶어서
포스트맨에서 Cookie를 강제로 삭제 후 PUT 요청을 해보니 401 응답이 왔다.
그 이후 구글링을 해보니
보안상의 이유로 쿠키로 XSRF-TOKEN을 넣어서 보내주는게 일반적이라고 한다.
그래서
URL 호출하는 로직에
.cookie("XSRF-TOKEN", mapHeader.get("X-CSRF-TOKEN").toString())
이렇게
쿠키 값을 세팅해주니 200 OK 응답이 왔다.
ㅠ_______ㅜ
결론은 저 쿠키,
XSRF-TOKEN 값의 유무였다.
👉🏼 결론
첫 요청에서는 XSRF 토큰(헤더 쿠키)이 포함되어 있지 않기 때문에 서버에서 401 Unauthorized 응답을 반환하였고,
두 번째 요청에서는 XSRF 토큰(헤더 쿠키)이 포함되어 있기 때문에 서버는 요청을 승인하고 200 OK 응답을 반환했다.
원래는 프론트(Front)에서 예를드면 Ajax호출할때 쿠키 세팅하는거라고 들었는데..
만드신 개발자분이 귀찮으셨는지.. 빼먹으셔서
API 호출임에 불구하고
쿠키까지 세팅해서 넣어야 했던거 같다..
잘 모르는 부분이라 확실한건 아니지만
ㅠ____ㅜ
공부를 좀 해봐야겠다
그리고 403 오류를 해결은 하긴 했지만,
이 토큰에 대해 간단하게 개념을 정리 해보려고 한다.
XSRF-TOKEN (CSRF) 란?
XSRF-TOKEN - CSRF(Cross-Site Request Forgery : 사이트 간 요청 위조)
공격을 방지하는 데 사용되는 토큰이다.
서버는 요청에 함께 제공된 CSRF 토큰을 검증하여 요청이 유효한지 확인한다.
만약 요청에 CSRF 토큰이 없거나 유효하지 않다면 서버는 보안 상의 이유로 요청을 거부할 수 있다.
따라서 서버의 보안 정책에 따라 CSRF 토큰이 필요할 수 있으며,
이를 요청에 포함하지 않으면 요청이 거부될 수 있다 ! (=> 403 응답)
CSRF 토큰은 사용자의 세션에 연결되어 있으며, 사용자의 모든 요청에 함께 보내진다.
CSRF 토큰은 악의적인 웹 사이트가 사용자의 브라우저를 통해 특정 작업을 수행하는 것을 방지하고,
오직 신뢰할 수 있는 웹 사이트가 사용자의 세션을 변경할 수 있도록 허용한다.
따라서 "XSRF-TOKEN" 쿠키는 CSRF 공격을 방지하기 위해 사용되며,
웹 애플리케이션이 사용자의 세션을 안전하게 유지하기 위한 보안 메커니즘 중 하나이다.
csrf
- Is used in html forms (not ajax)
- Produced in backend while rendering html form.
- we can not set request header in html forms directly, so an easy way is to send it via form input as a hidden field.
- you can name this hidden input whatever you want.
e.g. <input name="my_csrf_input" value="a_hashed_string_the_csrf_value">
x-csrf-token
- It is added to the request header for ajax requests.
- To use it, we can put the csrf value in a meta tag while rendering the html, then in front end we can get the value from that meta tag and send it to backend.
- Laravel specific: When using laravel as backend. Laravel checks this header automatically and compares it to the valid csrf value in database.(laravel has a middleware for this)
x-xsrf-token
- This is also added to the request header for ajax requests.
- Popular libraries like angular and axios, automatically get value of this header from xsrf-token cookie and put it in every request header.
- To use it, we should create a cookie named xsrf-token in backend, then our front end framework that uses angular or axios will use it automatically.
- In Laravel: Because it's popular, laravel creates this cookie in each response. So when you're using for example axios or angular with laravel, you don't need to do anything. just log user in and 'auth' middleware will do the job.
- In Laravel: its a bigger string compared to x-csrf-token because cookies are encrypted in laravel.
스프링 시큐리티까지 공부를 해야하려나....
Spring Security CSRF Token
- CookieCsrfTokenRepository 클래스
- cookieHttpOnly
"An HttpOnly Cookie is a tag added to a browser cookie that prevents client-side scripts from accessing data.
It provides a gate that prevents the specialized cookie from being accessed by anything other than the server.
Using the HttpOnly tag when generating a cookie helps mitigate the risk of client-side scripts accessing the protected cookie, thus making these cookies more secure."
"HttpOnly Cookie는 클라이언트측 스크립트가 데이터에 접근하는 것을 방지하는 브라우저 쿠키에 추가된 태그입니다.
이는 서버 이외의 다른 사용자가 특수 쿠키에 접근하지 못하도록 하는 게이트를 제공합니다.
쿠키를 생성할 때 HttpOnly 태그를 사용하면
클라이언트 스크립트가 보호된 쿠키에 액세스하는 위험을 줄일 수 있으므로 쿠키의 보안을 강화할 수 있습니다."
HttpOnlyCookie 설정때문에 내가 헤더에 쿠키로 토큰값을 넣지 않으면 403 응답을 받았던거 같당
스프링 시큐리티 위에 내용 관련해서
더 자세히 알고싶으면 이분 블로그를 보심이....
=> https://zzang9ha.tistory.com/341
Spring Security - CSRF(Cross-Site Request Forgery)
• 안녕하세요~ 이전에 운영하던 블로그 및 GitHub, 공부 내용을 정리하는 Study-GitHub 가 있습니다! • 네이버 블로그 • GitHub • Study-GitHub • 🐔 📎 CSRF(Cross-Site Request Forgery) 안녕하세요, 이번에 정
zzang9ha.tistory.com
쉽지 않다
하지만 화이팅
😎