악용으로부터 보호

Jaewoo Back·2024년 7월 12일
0

Spring Security공부

목록 보기
4/13

권한 부여


권한 부여 : 특정 리소스에 액세스할 수 있는 사용자를 결정하는 것입니다.
Spring Security는 요청 기반 권한 부여 및 메서드 기반 권한 부여를 허용하여 심층 방어를 제공합니다.


악용으로부터 보호

교차 사이트 요청 위조 (CSRF)


Spring은 CSRF(Cross Site Request Forgery) 공격으로부터 보호하기 위한 포괄적인 지원을 제공합니다.

  • CSRF 공격이란?
  • CSRF 공격으로부터 보호
  • CSRF 고려 사항

CSRF 공격이란?

은행 웹 사이트에서 현재 로그인한 사용자의 돈을 다루는 은행계좌로 이체할 수 있는 양식을 제공한다고 가정합니다. 예를 들어 전송 양식은 다음과 같을 수 있다.

<form method="post" action="/transfer">
    <input type="text" name="amount"/>
    <input type="text" name="routingNumber"/>
    <input type="text" name="account"/>
    <input type="submit" value="Transfer"/>
</form>

HTTP 요청 전송

POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: JSESSIONID=randomid
Content-Type: application/x-www-form-urlencoded

amount=100.00&routingNumber=1234&account=9876


악용 양식

<form method="post" action="https://bank.example.com/transfer">
    <input type="hidden" name="amount" value="100.00"/>
    <input type="hidden" name="routingNumber"value="evilsRoutingNumber"/>
    <input type="hidden"name="account"value="evilsAccountNumber"/>
    <input type="submit"value="Win Money!"/>
</form>

이 과정에서 악의적인 사용자에게 돈이 이체됐습니다. 이 전체 프로세스가 JavaScript를 사용하여 자동화 될 수 있습니다. 즉, 버튼을 클릭할 필요조차 없습니다. 또한 XSS 공격의 피해자인 정직한 사이트를 방문할 때도 쉽게 발생할 수 있습니다.


CSRF 공격으로부터 보호

CSRF 공격이 가능한 이유는 피해자 웹 사이트의 HTTP 요청과 공격자 요청이 정확히 동일하기 때문입니다. 즉, 악의적인 웹 사이트에서 오는 요청과 은행 웹 사이트에서 오는 요청을 구분하여 허용할 수 있는 방법이 없기 떄문입니다.

Spring 은 CSRF 공격으로부터 보호하기 위해 두 가지 메커니즘을 제공

  • 동기화 장치 토큰 패턴
  • 세션 쿠키에 SameSite 특성 지정

동기화 장치 토큰 패턴
HTTP 요청에 세션 쿠키 외에도 CSRF 토큰이라는 안전한 무작위 생성 값이 HTTP 요청에 존재하도록 하는 것입니다.

HTTP 요청이 제출되면 서버는 예상 CSRF 토큰을 조회하고 HTTP 요청의 실제 CSRF 토큰과 비교해야합니다. 값이 일치하지 않으면 거부합니다.

예를 들어 HTTP 매개 변수 또는 HTTP 헤더에 실제 CSRF 토큰을 요구하면 CSRF 공격으로부터 보호할 수 있습니다.

(애플리케이션은 안전한 HTTP 메서드가 읽기 전용인지 확인해야 합니다.)

<form method="post" action="/transfer">
    <input type="hidden" name="_csrf" value="4bfd1575-3ad1-4d21-96c7-4ef2d9f86721"/>
    <input type="text" name="amount"/>
    <input type="text" name="routingNumber"/>
    <input type="hidden" name="account"/>
    <input type="submit" value="Transfer"/>
</form>

이제 양식에 CSRF 토큰 값이 있는 숨겨진 입력이 포함됩니다. 악의적인 사이트가 응답을 읽을 수 없으므로 외부사이트는 CSRF 토큰을 읽을 수 없습니다.


Synchronizer Token Pattern 토큰 요청

POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: JSESSIONID=randomid
Content-Type: application/x-www-form-urlencoded

amount=100.00&routingNumber=1234&account=9876&_csrf=4bfd1575-3ad1-4d21-96c7-4ef2d9f86721

이제 요청에 임의 값이 있는 매개변수가 포함되어 있습니다. 악의적인 웹 사이트는 매개 변수에 대한 올바른 값을 제공 할 수 없으며 서버가 실제 CSRF 토큰을 예상 CSRF 토큰과 비교할 때 전송이 실패합니다.

CSRF 보호를 사용하는 경우

일반 사용자가 브라우저에서 처리할 수 있는 모든 요청에 대해 CSRF 보호를 사용하는 것이 좋습니다. 브라우저가 아닌 클라이언트에서만 사용되는 서비스를 만드는 경우 CSRF 보호를 비활성화 할 수 있다.

CSRF 보호 및 JSON

"JavaScript에서 만든 JSON 요청을 보호해야 합니까?
의적인 사용자는 다음 양식을 사용하여 JSON으로 CSRF를 만들 수 있습니다.
JSON 양식이 있는 CSRF

<form action="https://bank.example.com/transfer" method="post" enctype="text/plain">
	<input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'>
	<input type="submit"
		value="Win Money!"/>
</form>

JSON 요청이 있는 CSRF

{ 
  "amount": 100,
  "routingNumber": "evilsRoutingNumber",
  "account": "evilsAccountNumber",
  "ignore_me": "=test"
}

응용 프로그램이 헤더의 유효성을 검사하지 않으면 이 악용에 노출됩니다.
다음과 같이 URL 접미사를 .json로 끝나도록 합니다.

<form action="https://bank.example.com/transfer.json" method="post" enctype="text/plain">
	<input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'>
	<input type="submit"
		value="Win Money!"/>
</form>

CSRF 고려 사항

로그인

로그인 요청 위조를 방지하려면 로그인 HTTP 요청을 CSRF 공격으로부터 보호해야 합니다.

로그아웃

로그아웃 요청 위조를 방지하려면 로그아웃 HTTP 요청을 CSRF 공격으로부터 보호해야 합니다.

CSRF 및 세션 시간 초과

애부분 CSRF 토큰이 세션에 저장됩니다. 즉, 세션이 만료되는 즉시 서버는 CSRF 토큰을 찾지 못하고 HTTP 요청을 거부합니다.

  • JavaScript를 사용하여 양식 제출 시 CSRF 토큰을 요청하여 업데이트 되고 제출
  • 사용자에게 세션이 곧 만료될 것임을 알려주는 JavaScript를 사용
  • 쿠키에 저장
profile
https://blog.naver.com/jaewoo2_25

0개의 댓글