API Security - (RESTful) API 구현시 보안처리 방법

보안은 IT시스템 구축 시 지금까지 그랬고 앞으로도 가장 주요한 분야입니다. 아무리 새롭고 편한 아키텍쳐 및 솔루션이라고 하더라도 보안이 문제가 있다면 기업에 적용 이유는 사라집니다.

이번에는 API기반의 서비스 구축 시 고려되어야 할  API 보안관련 내용을 정리해 보았습니다.

OWASP의 REST Security Cheat Sheet 를 참조하지만 해당 내용이 현실적인 문제점을 놓치는 부분이 많아서 추가적이 사례를 정리해 보았습니다.

 


Session management

RESTful web services (API Service)는 API Key 또는 POST 방식의 body 영역에 포함된 cookie를 통해 필요 시 session 관리를 해야 합니다.

또한 username 이나 패스워드 token 또는 API key 는 URL 에 노출되지 않도록 해야 합니다. 해당 정보가 web server log에 남을 수 있으며 그러한 경우 문제를 발생시킬 여지가 있습니다.

 

올바른 호출

  https://test.service.com/resourceCollection/<id>/action

  https://twitter.com/vanderaj/lists

 잘못된 호출

  https://test.service.com/controller/<id>/action?apiKey=a53f435643de32 (API Key in URL)

  http://example.com/controller/<id>/action?apiKey=a53f435643de32 (transaction not protected by TLS; API Key in URL)

 

Protocol for Authentication and Authorization

인증 및 권한 부여에 관련 Protocol 입니다. OPEN API  방식으로 API 에 대한 권한 및 사용을 제한하기 위해서는 가장 많이 사용되는 Oauth 2.0 을 사용하여야 하지만, Private API나 다른 특수한 경우라면 보안에 더 유리한 방식으로 구현하여도 상관없습니다.

  

Protect Session State

많은 웹서비스들은 무상태(Stateless)가 가능하도록 되어 있습니다. 주요 거래의 특정 부분 전송이 가능하므로 상태 처리의 문제점을 야기시킬 수 있습니다.

  •  session token 및 API key 는 사용자의 상태를 인지하는 목적으로만 사용이 고려되어야 합니다.session 상태를 보호하는 것은 일반적이 웹 어플리케이션에서도 동일하므로 Restful API에서도 다르지 않습니다.

  •  재전송 방지(Anti-replay),공격자는 보통 데이터를 cut & pate 방식으로 기본 데이터를 다시 보내는 공격을 할 수 있습니다.

  • 이러한 경우를 방지하기 위해서는 시간제약이 있는 암호화된 key를 이용해야 합니다. session token 또는 생성된 시간정보 및 IP 정보를 조합한 인증토큰을 생성합니다. 일반적으로  인증 토큰을 로컬 사용자 저장소를 통해 보호하여서 anti-replay 공격에 대비하여야 합니다.

  • session token의 생존주기는 보통 2시간로 정도 짧게 설정하여야 합니다. 

  • access token 은 접근 제안 영역을 가지고 있어야 합니다. 즉 하나의 access token으로 모든 API 를 접근하지 못해야 합니다.

종합적으로 URL 이나 전송되는 값에 상태를 의미하는 값을 전송하면 안됩니다. 그런 경우가 많지 않을 것 같지만 생각보다 그런 실수를 하는 경우가 종종 있습니다.

ex) https://test.com/board/list?id=BX421&isAdmin=true

와 같이 admin 권한인 경우 게시판 리스트를 가져오는 올 때 위와 같이 상태 값을 parameter로 받는 방식으로 처리하면 문제가 생기는 경우가 있습니다.

  

Anti-farming 

 anti-farming 에 대하 이해하려면 우선 farming 방식의 해킹을 이해해야 합니다. farming 농사를 짓듯이 특정데이터를 가져오기 위해 농사 짓듯이 조금씩 조금씩 데이터를 조회하고 가져와서 결국에는 방대한 데이터를 획득하는 방법입니다. 

이러한 경우 직접 사람이 데이터를 조회해서 가져오지 않고 robot이나 프로그램 작성을 통해 하루에 조금씩 일정량을 데이터를 조회하도록 하고 며칠이 걸려 수집된 데이터는 결국 대량 데이터를 취득하게 되는 방법입니다.

 물론 공개된 데이터에 대해 조회를 하거나 그 해당 API에 대한 권한을 가지고 있는 경우라면 크게 문제가 생기지 않을 수도 있지만 robot 이나 다른 API 에 의해 지속적으로 수집되는 데이터는 데이터의 악용등 우려가 생길 수 있습니다.

 사실 이러한 경우 기술적인 방지 대책은 없으며 대량 데이터 추출에 대한 business model 을 통한 해결방법, 즉 사용요금의 과금과 같은 방식으로 처리해야 합니다.

또한 계약상 특정 횟수 이상의 조회인 경우는 CAPTCHA 와 같이 반복적 기계작업을 막기 위한 방법을 쓸 수 있지만 API가 대부분의 사람에 의해 발생되지 않는 경우가 대부분이기 때문에 anti-farming을 처리하기는 쉽지 않습니다.

 따라서 해당 API 사용에 대한 계약 정보를 명확히 기술하고 공개 API 라도 특정 트래픽 이상 사용하지 못하도록 제약을 거는 것이 필요합니다.

 

 Protect HTTP Methods

 RESTful API에서는 GET(읽기), POST(생성), PUT(수정), DELETE(삭제) 4가지 기본  HTTP method를 사용합니다. API 생성시 해당 상황에 따라 4가지의 method를 제약을 가할 수 있는 구조로 설계되어야 합니다. 또한 동일자원(resource)에 대해서도 어떤 사용자인지 따라 HTTP method의 사용권한이 틀려져야 합니다.

 이러한 부분은 API 설계 및 구현 시 어려운 부분입니다. 실제 access key 기반으로 동작되는 API라고 한다면 access key 에 해단 정보 권한 제약을 판단할 수 있는 최소한 의 정보가 같이 포함되어 있어야 빠른 API 응답속도를 구현할 수 있습니다.

access key 에 이런 권한 정보가 포함되지 않는 다면 해당 정보의 access scope를 판단하기 위해 내부 권한 정보를 다시 조회하고 그에 따라 권한을 판단하는 로직이 구현되어야 하는데 이런 경우 큰 성능 부하를 야기할 수 있습니다.

 OWASP 에서는 whitelist 기반의 method를 서비스 별 즉 API 별로 사용 가능한 whitelist의 method를 정의하여 API 사용제약을 정의하는 방법을 추천하지만 실제 API 사용시는 위와 같은 문제점으로 훨씬 복잡하게 구현되어야 하는 경우가 많습니다.

 

 Cross-site Request Forgery (CSRF) 대책

 CSRF또는 XSRF 라고 하는 크로스 사이트 요청 위조는 예전 Auction에서 발생한 개인정보 유출사건에서 사용된 공격방식 중 하나입니다.

이용자(해킹피해자)가 웹페이지에서 정상적으로 로그인한 상태로 가정하고 

공격자는 이용자에게 이메일이나 특정 경로를 통해 웹페이지 URL를 보냅니다. 해당 웹페이지에는 아래 내용을 감추고 보냅니다.

 <img src="https://hacking.service.com/api/order_update?id=234234&dest=china"/>

 이용자는 해당정보를 보는 순간 해당 api 가 호출되면서 특정정보가 바뀌는 문제를 야기할 수 있습니다.

 RESTful API 상에서는 위와 같은 문제점으로 session 기반으로만 API 를 통제하는 것은 위험할 수있습니다.  따라서 내부 resource의 상태변경이 일어날 수 있는 API에 대해서는 Access key또는 CSRF Token 과 같은 특정시점만 사용 가능한 key 를 통해 통제하는 것이 안정한 CSRF 를 대응하기 위한 방법입니다.

 API 경우는 아니지만 일반적인 CSRF를  대응하기 위한 자세한 사항은 아래 URL을 참조하면 되겠습니다.

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

  

Insecure direct object references

 예를 들어 어떤 이용자가 다른 이용자의 계좌에 돈을 이체하는 API가 있다고 가정합니다.

 

http://example.service.com/api/tranfer?amount=1000&from_account=1252345&to_account=52352363 


 위와 경우에서 from_account 정보와 to_account 정보가 실제 계좌 번호라면 대단히 위험한 API 설계가 아닐 수 없습니다.

 이런 변수값들은 임시 token 형태로 변경되어야 합니다.


 http://example.service.com/api/tranfer?amount=1000&from_account=fedsd4fagsr4f&to_account=nkjdk4jsdt84

 와 같은 식으로 실제 값과  mapping을 통하여 외부로 노출되는 변수값은 역으로 유추가 불가한 값 형태로 이용하여야 합니다.

 하지만 실제 app 이나 사용자 계좌정보가 넘어가야 될 수 밖에 없는 경우라면 어떻게 해야 할까요?

 사용자가 app 에서 계좌정보를 입력 시 각 은행이나 서비스 제공자 측에서 모든 매핑정보를 가지고 있는 것은 불가능합니다.

이러한 경우라면 실제 계좌정보는 다음과 같은 방법으로 보내야 합니다.

 

1) 특정 parameter 값 정보는 암호화하여 보낸다. (ex from_account, to_account)

2) 암호화 방식은 AES256 과 같은 공인된 암호화 로직을 사용하고 대칭키 암화화 방식인 경우 키교환 API 를 통해 각자 암호화 대칭키를 보관하여 사용한다.

3) 해당 정보를 변조를 방지하기 위하여 모든 파라미터 값에 대한 hash 코드를 생성하여 값이 전송한다.




API Access Control

이용자가 API 사용시 특정 사용횟수를 넘어서면 API 사용을 금지하도록 합니다.  특정사용자만 사용 가능한 API 인 경우 사용자 기반의 호출회수를 제한할 수 있지만 공개 API 인 경우는 IP 기반으로 제한할 수 밖에 없습니다.

 

또한 해킹 목적으로 대량의 API 처리 트래픽을 발생시킬 수 있는데 이런 경우를 대비하여 API 시스템에서 초당 Transaction 수에 제한을 두어 시스템을 보호해야 합니다.

만약 이러한 트래픽 제한에 걸린 경우라면

 429 - Too Many Request 라는 HTTP Error를 발생시켜야 합니다. 또는 일반적은 500 Server Error 를 발생해도 무방합니다.

 

IP Basd Control

 특정 접속 IP 에 대해 별다른 access key 나 session 정보없이 API사용을 허용하는 경우가 종종 있습니다. 하지만 일반 외부 인터넷 접속인 경우 IP를 변조하여 해킹하는 사례도 있기 때문에 이러한 경우는 내부 인터넷 망 또는 전용선이 구축된 경우에만 사용하는것이 좋습니다.



Input Validation

API 설계 시 데이터의 타입이나 값은 범위에 대한 입력 값을 검증이 필요합니다.  가령 입력값이 0이 되면 안 되는 경우 즉 특정 값을 해당 변수로 나누는 로직이 있는 경우 잘못된 수치 연산으로 인해 시스템에 악영향을 미칠 수 있습니다.

따라서 해당 값이 허용되는 범위에 있는지 숫자를 입력해야 하는데, 문자값이 입력되어 있는지를 확인해야 합니다.

  

기타 입력 형태 검증

API 호출시 입력데이터는 JSON 형태 또는 XML 형태도 될 수 있습니다. 이러한 경우 각 입력 데이터 형태 표준을 준수하는지 검사를 해야 합니다. 보통 이러한 경우 각각의 데이터 Parser 가 내부 데이터 Model로 처리하면서 문제가 생기면 에러가 발생하기 때문에 자체 검증이 되지만 만약 에러처리가 잘 되어있지 않다면 다른 시스템 문제를 야기할 수 있으므로 주의하여야 합니다.

 

Output encoding process

 악의 적인 목적으로 잘못된 데이터를 입력하고 그 데이터가 JSON이나 XML형태로 출력될때 API 서비스가 문제가 발생하도록 하는 해킹방법도 존재한다. 주로 JSON 이나 XML 로 출력  encoding 처리나 schema 구조를 지키지 않아 API 를 이용하는 서비스 측에서 에러를 발생하여 문제를 일으키는 방법인데, 이런한 경우는 API 출력값이 JSON이나 XML기반의 SOAP 프로토콜등 변환에 문제가 없도록 해야한다. 또한 이러한 데이터 형태 변환시 API 가 실패 error code 를 반환할 수 있도록 처리하여야 추후 발생되는 문제를 최소화 할 수 있다.


HTTP Return Code

위의 문제 상황에 대해서 최종적으로 API는 올바른 반환코드를 API 이용자에게 전달해야 합니다.

 

·         200 OK - Response to a successful REST API action. The HTTP method can be GET, POST, PUT, PATCH or DELETE.

·         400 Bad Request - The request is malformed, such as message body format error.

·         401 Unauthorized - Wrong or no authencation ID/password provided.

·         403 Forbidden - It's used when the authentication succeeded but authenticated user doesn't have permission to the request resource

·         404 Not Found - When a non-existent resource is requested

·         405 Method Not Allowed - The error checking for unexpected HTTP method. For example, the RestAPI is expecting HTTP GET, but HTTP PUT is used.

·         429 Too Many Requests - The error is used when there may be DOS attack detected or the request is rejected due to rate limiting


참고 제품

DBridge API Server : http://www.cyber-i.com/CMS/dbridge.htm


New Multi-Channel Dynamic CMS