restful api 구현시 살펴보아야 할 보안 처리 방법에 대해 정리해보았습니다. 출처의 문서를 참조하고, 재작성 하지만 스스로 놓칠 수 있는 다른 문제점을 추가해 두었습니다.
Session Management
RESTful API에는 username 이나 패스워드 token 또는 API key 는 URL 에 노출되지 않도록 해야 합니다. 해당 정보가 server log에 남을 수 있으며 그러한 경우 문제를 발생시킬 여지가 있습니다.
Anti-replay Attack
재전송 방지(Anti-replay), 공격자는 프로토콜 상 메시지를 복사한 후 재전송함으로써 승인된 사용자로 오인하게 만들어 공격하는 방법입니다.
이러한 경우를 방지하기 위해서는 아래의 방법을 사용합니다.
시간제약이 있는 암호화된 key를 사용합니다.
순서 번호(sequence number): 송신 메시지에 매회 1씩 증가하는 번호를 함께 전달합니다.
타임스탬프(timestamp) 사용: 송신 메시지에 현재 시각을 함께 전달합니다.
비표(nonce) 사용: 메시지를 수신하기에 앞서 일회용의 랜덤한 값(비표)를 수신한 뒤, 수신자는 송신자에게 받은 비표를 전달합니다.
비표(nonce) 사용 시나리오
Retry-After
비정상적인 방법(DoS, Brute-force attack)으로 API 서버를 이용하려는 경우 429 Too Many Requests 오류 응답과 함께 일정 시간 뒤 요청할 것을 나타낸다.
n 시간동안 n회만 요청 가능 : • 429 응답과 함께 Retry-After: n
n 회만 요청 가능
401 응답과 함께 해당 사용자(IP)는 더 이상 인증 관련 API를 사용할 수 없고 다시 요청하려면 특수한 절차가 필요하다는 메세지 응답
Access Control
access token 은 접근 제안 영역을 가지고 있어야 합니다. 즉 하나의 access token으로 모든 API 를 접근하지 못해야 합니다.
RESTful API에서는 GET(읽기), POST(생성), PUT(수정), DELETE(삭제) 4가지 기본 HTTP method를 사용합니다. API 생성시 해당 상황에 따라 4가지의 method를 제약을 가할 수 있는 구조로 설계되어야 합니다. 또한 동일자원(resource)에 대해서도 어떤 사용자인지 따라 HTTP method의 사용권한이 틀려져야 합니다.
access key 에 해단 정보 권한 제약을 판단할 수 있는 최소한 의 정보가 같이 포함되어 있어야 빠른 API 응답속도를 구현할 수 있습니다.
access key 에 이런 권한 정보가 포함되지 않는 다면 해당 정보의 access scope를 판단하기 위해 내부 권한 정보를 다시 조회하고 그에 따라 권한을 판단하는 로직이 구현되어야 하는데 이런 경우 큰 성능 부하를 야기할 수 있습니다.
OWASP 에서는 whitelist 기반의 method를 서비스 별 즉 API 별로 사용 가능한 whitelist의 method를 정의하여 API 사용제약을 정의하는 방법을 추천하지만 실제 API 사용시는 위와 같은 문제점으로 훨씬 복잡하게 구현되어야 하는 경우가 많습니다.
이용자는 해당정보를 보는 순간 해당 api 가 호출되면서 특정정보가 바뀌는 문제를 야기할 수 있습니다.
Spring Security 프레임워크는 기본적으로 CSRF 공격에 대한 방지를 수행합니다.
예전에 많이 사용했던 MVC 구조는 세션과 쿠키를 통해 사용자 인증을 수행했기 때문에 CSRF 공격에 취약합니다. Stateful 한 서비스를 제공하기 위해 인증된 사용자 정보를 세션에 저장하고, 세션 ID가 쿠키에 저장되기 때문에 문제가 발생합니다.
하지만 REST API는 stateless하기 때문에 쿠키와 세션에 의존하지 않습니다. 때문에 CSRF 공격에 대한 방어설정을 비활성화 시키는 경우가 많습니다. 하지만, CSRF 공격에 대한 방지를 disable 시키더라도 인터셉터 등에서 적절한 방어 코드를 통해 보안 수준을 높이는 것이 좋을 것 같습니다.
서버가 Stateful할 경우, CSRF 공격을 방어하기위해 아래의 방법을 사용합니다.
Referer Check : 도메인이 일치하는지 검증한다.
CSRF 토큰 사용 :
션에 임의의 난수값을 저장하고 사용자의 요청마다 해당 난수값을 포함시켜 전송. 이후 Back-end에서 요청을 받을 때마다 세션에 저장된 토큰값과 요청 파라미터에서 전달되는 토큰값이 같은지 검증하는 방법. 이 또한 XSS 취약점이 있는 경우 방어가 불가능해질 수 있음
Double Submit Cookie 검증 : 웹브라우저의 Same Origin 정책으로 인해 자바스크립트에서 타 도메인의 쿠키값을 확인, 수정하지 못한다는 것을 이용한 방어 기법입니다.
Spring Security를 이용
Insecure Direct Object References (IDOR)
개발자의 판단하에 상황에 따라 적절하게 사용하자.
인증과 인가(Authentication, Authorization)로 api를 적절히 보호한다. (전제조건)
유저 CI(주민번호, email)와 같은 정보는 절대 uri에 담지 않는다.
데이터베이스의 순차적인 PK를 URI에 담는 것을 최대한 지양한다.
순차적인 PK 대신 DB내 uuid 또는 짧은 고유식별자의 컬럼을 생성하여 이를 매칭한다.
순차적인 PK 대신, 공인된 encrypt 알고리즘, hash 된 값을 전달받아 매칭한다.
“uuid, encrypt, hashing 비용 vs 퍼포먼스” 에 적절히 타협하여 선택한다.
DB volumn을 유추할 수 있으니, 이 정보가 크리티컬하지 않은 경우에만 사용한다. (ex ‘데이터셋’, ‘유저 수’ 등과 같은 데이터 x)
API Access Control
이용자가 API 사용시 특정 사용횟수를 넘어서면 API 사용을 금지하도록 합니다. 특정사용자만 사용 가능한 API 인 경우 사용자 기반의 호출회수를 제한할 수 있지만 공개 API 인 경우는 IP 기반으로 제한할 수 밖에 없습니다. 또한 해킹 목적으로 대량의 API 처리 트래픽을 발생시킬 수 있는데 이런 경우를 대비하여 API 시스템에서 초당 Transaction 수에 제한을 두어 시스템을 보호해야 합니다.만약 이러한 트래픽 제한에 걸린 경우라면 429 - Too Many Request 라는 HTTP Error를 발생시켜야 합니다.
IP Basd Control
특정 접속 IP 에 대해 별다른 access key 나 session 정보없이 API사용을 허용하는 경우가 종종 있습니다. 하지만 일반 외부 인터넷 접속인 경우 IP를 변조하여 해킹하는 사례도 있기 때문에 이러한 경우는 내부 인터넷 망 또는 전용선이 구축된 경우에만 사용하는것이 좋습니다.
Input Validation
API 설계 시 데이터의 타입이나 값은 범위에 대한 입력 값을 검증이 필요합니다. 가령 입력값이 0이 되면 안 되는 경우 즉 특정 값을 해당 변수로 나누는 로직이 있는 경우 잘못된 수치 연산으로 인해 시스템에 악영향을 미칠 수 있습니다.따라서 해당 값이 허용되는 범위에 있는지 숫자를 입력해야 하는데, 문자값이 입력되어 있는지를 확인해야 합니다.
restful api 구현시 살펴보아야 할 보안 처리 방법에 대해 정리해보았습니다. 출처의 문서를 참조하고, 재작성 하지만 스스로 놓칠 수 있는 다른 문제점을 추가해 두었습니다.
Session Management
RESTful API에는 username 이나 패스워드 token 또는 API key 는 URL 에 노출되지 않도록 해야 합니다. 해당 정보가 server log에 남을 수 있으며 그러한 경우 문제를 발생시킬 여지가 있습니다.
Anti-replay Attack
재전송 방지(Anti-replay), 공격자는 프로토콜 상 메시지를 복사한 후 재전송함으로써 승인된 사용자로 오인하게 만들어 공격하는 방법입니다.
이러한 경우를 방지하기 위해서는 아래의 방법을 사용합니다.
시간제약이 있는 암호화된 key를 사용합니다.
순서 번호(sequence number): 송신 메시지에 매회 1씩 증가하는 번호를 함께 전달합니다.
타임스탬프(timestamp) 사용: 송신 메시지에 현재 시각을 함께 전달합니다.
비표(nonce) 사용: 메시지를 수신하기에 앞서 일회용의 랜덤한 값(비표)를 수신한 뒤, 수신자는 송신자에게 받은 비표를 전달합니다.
비표(nonce) 사용 시나리오
Retry-After
비정상적인 방법(DoS, Brute-force attack)으로 API 서버를 이용하려는 경우 429 Too Many Requests 오류 응답과 함께 일정 시간 뒤 요청할 것을 나타낸다.
n 시간동안 n회만 요청 가능 : • 429 응답과 함께 Retry-After: n
n 회만 요청 가능
401 응답과 함께 해당 사용자(IP)는 더 이상 인증 관련 API를 사용할 수 없고 다시 요청하려면 특수한 절차가 필요하다는 메세지 응답
Access Control
access token 은 접근 제안 영역을 가지고 있어야 합니다. 즉 하나의 access token으로 모든 API 를 접근하지 못해야 합니다.
RESTful API에서는 GET(읽기), POST(생성), PUT(수정), DELETE(삭제) 4가지 기본 HTTP method를 사용합니다. API 생성시 해당 상황에 따라 4가지의 method를 제약을 가할 수 있는 구조로 설계되어야 합니다. 또한 동일자원(resource)에 대해서도 어떤 사용자인지 따라 HTTP method의 사용권한이 틀려져야 합니다.
access key 에 해단 정보 권한 제약을 판단할 수 있는 최소한 의 정보가 같이 포함되어 있어야 빠른 API 응답속도를 구현할 수 있습니다.
access key 에 이런 권한 정보가 포함되지 않는 다면 해당 정보의 access scope를 판단하기 위해 내부 권한 정보를 다시 조회하고 그에 따라 권한을 판단하는 로직이 구현되어야 하는데 이런 경우 큰 성능 부하를 야기할 수 있습니다.
OWASP 에서는 whitelist 기반의 method를 서비스 별 즉 API 별로 사용 가능한 whitelist의 method를 정의하여 API 사용제약을 정의하는 방법을 추천하지만 실제 API 사용시는 위와 같은 문제점으로 훨씬 복잡하게 구현되어야 하는 경우가 많습니다.
이용자는 해당정보를 보는 순간 해당 api 가 호출되면서 특정정보가 바뀌는 문제를 야기할 수 있습니다.
Spring Security 프레임워크는 기본적으로 CSRF 공격에 대한 방지를 수행합니다.
예전에 많이 사용했던 MVC 구조는 세션과 쿠키를 통해 사용자 인증을 수행했기 때문에 CSRF 공격에 취약합니다. Stateful 한 서비스를 제공하기 위해 인증된 사용자 정보를 세션에 저장하고, 세션 ID가 쿠키에 저장되기 때문에 문제가 발생합니다.
하지만 REST API는 stateless하기 때문에 쿠키와 세션에 의존하지 않습니다. 때문에 CSRF 공격에 대한 방어설정을 비활성화 시키는 경우가 많습니다. 하지만, CSRF 공격에 대한 방지를 disable 시키더라도 인터셉터 등에서 적절한 방어 코드를 통해 보안 수준을 높이는 것이 좋을 것 같습니다.
서버가 Stateful할 경우, CSRF 공격을 방어하기위해 아래의 방법을 사용합니다.
Referer Check : 도메인이 일치하는지 검증한다.
CSRF 토큰 사용 :
션에 임의의 난수값을 저장하고 사용자의 요청마다 해당 난수값을 포함시켜 전송. 이후 Back-end에서 요청을 받을 때마다 세션에 저장된 토큰값과 요청 파라미터에서 전달되는 토큰값이 같은지 검증하는 방법. 이 또한 XSS 취약점이 있는 경우 방어가 불가능해질 수 있음
Double Submit Cookie 검증 : 웹브라우저의 Same Origin 정책으로 인해 자바스크립트에서 타 도메인의 쿠키값을 확인, 수정하지 못한다는 것을 이용한 방어 기법입니다.
Spring Security를 이용
Insecure Direct Object References (IDOR)
개발자의 판단하에 상황에 따라 적절하게 사용하자.
인증과 인가(Authentication, Authorization)로 api를 적절히 보호한다. (전제조건)
유저 CI(주민번호, email)와 같은 정보는 절대 uri에 담지 않는다.
데이터베이스의 순차적인 PK를 URI에 담는 것을 최대한 지양한다.
순차적인 PK 대신 DB내 uuid 또는 짧은 고유식별자의 컬럼을 생성하여 이를 매칭한다.
순차적인 PK 대신, 공인된 encrypt 알고리즘, hash 된 값을 전달받아 매칭한다.
“uuid, encrypt, hashing 비용 vs 퍼포먼스” 에 적절히 타협하여 선택한다.
DB volumn을 유추할 수 있으니, 이 정보가 크리티컬하지 않은 경우에만 사용한다. (ex ‘데이터셋’, ‘유저 수’ 등과 같은 데이터 x)
API Access Control
이용자가 API 사용시 특정 사용횟수를 넘어서면 API 사용을 금지하도록 합니다. 특정사용자만 사용 가능한 API 인 경우 사용자 기반의 호출회수를 제한할 수 있지만 공개 API 인 경우는 IP 기반으로 제한할 수 밖에 없습니다. 또한 해킹 목적으로 대량의 API 처리 트래픽을 발생시킬 수 있는데 이런 경우를 대비하여 API 시스템에서 초당 Transaction 수에 제한을 두어 시스템을 보호해야 합니다.만약 이러한 트래픽 제한에 걸린 경우라면 429 - Too Many Request 라는 HTTP Error를 발생시켜야 합니다.
IP Basd Control
특정 접속 IP 에 대해 별다른 access key 나 session 정보없이 API사용을 허용하는 경우가 종종 있습니다. 하지만 일반 외부 인터넷 접속인 경우 IP를 변조하여 해킹하는 사례도 있기 때문에 이러한 경우는 내부 인터넷 망 또는 전용선이 구축된 경우에만 사용하는것이 좋습니다.
Input Validation
API 설계 시 데이터의 타입이나 값은 범위에 대한 입력 값을 검증이 필요합니다. 가령 입력값이 0이 되면 안 되는 경우 즉 특정 값을 해당 변수로 나누는 로직이 있는 경우 잘못된 수치 연산으로 인해 시스템에 악영향을 미칠 수 있습니다.따라서 해당 값이 허용되는 범위에 있는지 숫자를 입력해야 하는데, 문자값이 입력되어 있는지를 확인해야 합니다.
restful api 구현시 살펴보아야 할 보안 처리 방법에 대해 정리해보았습니다. 출처의 문서를 참조하고, 재작성 하지만 스스로 놓칠 수 있는 다른 문제점을 추가해 두었습니다.
Session Management
RESTful API에는 username 이나 패스워드 token 또는 API key 는 URL 에 노출되지 않도록 해야 합니다. 해당 정보가 server log에 남을 수 있으며 그러한 경우 문제를 발생시킬 여지가 있습니다.
Anti-replay Attack
재전송 방지(Anti-replay), 공격자는 프로토콜 상 메시지를 복사한 후 재전송함으로써 승인된 사용자로 오인하게 만들어 공격하는 방법입니다.
이러한 경우를 방지하기 위해서는 아래의 방법을 사용합니다.
시간제약이 있는 암호화된 key를 사용합니다.
순서 번호(sequence number): 송신 메시지에 매회 1씩 증가하는 번호를 함께 전달합니다.
타임스탬프(timestamp) 사용: 송신 메시지에 현재 시각을 함께 전달합니다.
비표(nonce) 사용: 메시지를 수신하기에 앞서 일회용의 랜덤한 값(비표)를 수신한 뒤, 수신자는 송신자에게 받은 비표를 전달합니다.
비표(nonce) 사용 시나리오
Retry-After
비정상적인 방법(DoS, Brute-force attack)으로 API 서버를 이용하려는 경우 429 Too Many Requests 오류 응답과 함께 일정 시간 뒤 요청할 것을 나타낸다.
n 시간동안 n회만 요청 가능 : • 429 응답과 함께 Retry-After: n
n 회만 요청 가능
401 응답과 함께 해당 사용자(IP)는 더 이상 인증 관련 API를 사용할 수 없고 다시 요청하려면 특수한 절차가 필요하다는 메세지 응답
Access Control
access token 은 접근 제안 영역을 가지고 있어야 합니다. 즉 하나의 access token으로 모든 API 를 접근하지 못해야 합니다.
RESTful API에서는 GET(읽기), POST(생성), PUT(수정), DELETE(삭제) 4가지 기본 HTTP method를 사용합니다. API 생성시 해당 상황에 따라 4가지의 method를 제약을 가할 수 있는 구조로 설계되어야 합니다. 또한 동일자원(resource)에 대해서도 어떤 사용자인지 따라 HTTP method의 사용권한이 틀려져야 합니다.
access key 에 해단 정보 권한 제약을 판단할 수 있는 최소한 의 정보가 같이 포함되어 있어야 빠른 API 응답속도를 구현할 수 있습니다.
access key 에 이런 권한 정보가 포함되지 않는 다면 해당 정보의 access scope를 판단하기 위해 내부 권한 정보를 다시 조회하고 그에 따라 권한을 판단하는 로직이 구현되어야 하는데 이런 경우 큰 성능 부하를 야기할 수 있습니다.
OWASP 에서는 whitelist 기반의 method를 서비스 별 즉 API 별로 사용 가능한 whitelist의 method를 정의하여 API 사용제약을 정의하는 방법을 추천하지만 실제 API 사용시는 위와 같은 문제점으로 훨씬 복잡하게 구현되어야 하는 경우가 많습니다.
이용자는 해당정보를 보는 순간 해당 api 가 호출되면서 특정정보가 바뀌는 문제를 야기할 수 있습니다.
Spring Security 프레임워크는 기본적으로 CSRF 공격에 대한 방지를 수행합니다.
예전에 많이 사용했던 MVC 구조는 세션과 쿠키를 통해 사용자 인증을 수행했기 때문에 CSRF 공격에 취약합니다. Stateful 한 서비스를 제공하기 위해 인증된 사용자 정보를 세션에 저장하고, 세션 ID가 쿠키에 저장되기 때문에 문제가 발생합니다.
하지만 REST API는 stateless하기 때문에 쿠키와 세션에 의존하지 않습니다. 때문에 CSRF 공격에 대한 방어설정을 비활성화 시키는 경우가 많습니다. 하지만, CSRF 공격에 대한 방지를 disable 시키더라도 인터셉터 등에서 적절한 방어 코드를 통해 보안 수준을 높이는 것이 좋을 것 같습니다.
서버가 Stateful할 경우, CSRF 공격을 방어하기위해 아래의 방법을 사용합니다.
Referer Check : 도메인이 일치하는지 검증한다.
CSRF 토큰 사용 :
션에 임의의 난수값을 저장하고 사용자의 요청마다 해당 난수값을 포함시켜 전송. 이후 Back-end에서 요청을 받을 때마다 세션에 저장된 토큰값과 요청 파라미터에서 전달되는 토큰값이 같은지 검증하는 방법. 이 또한 XSS 취약점이 있는 경우 방어가 불가능해질 수 있음
Double Submit Cookie 검증 : 웹브라우저의 Same Origin 정책으로 인해 자바스크립트에서 타 도메인의 쿠키값을 확인, 수정하지 못한다는 것을 이용한 방어 기법입니다.
Spring Security를 이용
Insecure Direct Object References (IDOR)
개발자의 판단하에 상황에 따라 적절하게 사용하자.
인증과 인가(Authentication, Authorization)로 api를 적절히 보호한다. (전제조건)
유저 CI(주민번호, email)와 같은 정보는 절대 uri에 담지 않는다.
데이터베이스의 순차적인 PK를 URI에 담는 것을 최대한 지양한다.
순차적인 PK 대신 DB내 uuid 또는 짧은 고유식별자의 컬럼을 생성하여 이를 매칭한다.
순차적인 PK 대신, 공인된 encrypt 알고리즘, hash 된 값을 전달받아 매칭한다.
“uuid, encrypt, hashing 비용 vs 퍼포먼스” 에 적절히 타협하여 선택한다.
DB volumn을 유추할 수 있으니, 이 정보가 크리티컬하지 않은 경우에만 사용한다. (ex ‘데이터셋’, ‘유저 수’ 등과 같은 데이터 x)
API Access Control
이용자가 API 사용시 특정 사용횟수를 넘어서면 API 사용을 금지하도록 합니다. 특정사용자만 사용 가능한 API 인 경우 사용자 기반의 호출회수를 제한할 수 있지만 공개 API 인 경우는 IP 기반으로 제한할 수 밖에 없습니다. 또한 해킹 목적으로 대량의 API 처리 트래픽을 발생시킬 수 있는데 이런 경우를 대비하여 API 시스템에서 초당 Transaction 수에 제한을 두어 시스템을 보호해야 합니다.만약 이러한 트래픽 제한에 걸린 경우라면 429 - Too Many Request 라는 HTTP Error를 발생시켜야 합니다.
IP Basd Control
특정 접속 IP 에 대해 별다른 access key 나 session 정보없이 API사용을 허용하는 경우가 종종 있습니다. 하지만 일반 외부 인터넷 접속인 경우 IP를 변조하여 해킹하는 사례도 있기 때문에 이러한 경우는 내부 인터넷 망 또는 전용선이 구축된 경우에만 사용하는것이 좋습니다.
Input Validation
API 설계 시 데이터의 타입이나 값은 범위에 대한 입력 값을 검증이 필요합니다. 가령 입력값이 0이 되면 안 되는 경우 즉 특정 값을 해당 변수로 나누는 로직이 있는 경우 잘못된 수치 연산으로 인해 시스템에 악영향을 미칠 수 있습니다.따라서 해당 값이 허용되는 범위에 있는지 숫자를 입력해야 하는데, 문자값이 입력되어 있는지를 확인해야 합니다.