마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

Rest api 보안에 대해서..

0 추천
Oauth, Restful, jwt를 며칠간 계속 알아보고 있는데요.. 흐름 자체는 이해가 가는데

 

보안에 관하여 이해가 아직도 해결이 되지 않네요..

 

궁금한점은,

 

id,pw등을 이용하여 api server에 로그인 후 token을 받아와서 sharedpreference에다가 저장 후 해당 토큰을 통해 api server로 호출을 하는 것까지는 이해가 가는데요.

 

문제는, 해당 api server의 url과 endpoint를 알면 기기가 아닌 브라우저나 어디서든지 접근이 가능하지 않습니까?

 

그렇다면, 만약 루팅된 폰에서 token값만 빼와서 해당 api server의 endpoint로 요청을 날리게 되면, 이거 보안에 심각한 문제인데요. (get이 아닌 정보 update와 관련된 endpoint같은 경우 등)

 

이것을 막는 방법이 도저히 떠오르지가 않네요.

제가 생각한 방법들은

 

1. 기기에서 요청한 것만 필터링한다. -> 기기에서 요청이 온것인지 서버로서는 알수가 없다.

2. token값을 ndk, 암호화등을 이용하여 클라이언트단에서 숨긴다 -> 어떻게든 알아낼 수 있을것이고, 몇개의 앱을 분석해본결과 token값을 숨기는 방법을 쓰지는 않는것 같습니다. 페이스북sdk 로그인도 access_token 을 그냥 sharedpreference에 그대로 저장하더군요.

3. secret key 또는 token값을 서버에서 받아온다? -> 서버에서 받아올때는 어떻게 인증을 해야 할까요? 해당 url로 접근하면 secret키를 그대로 보여준다? 이것도 결국 인증을 통한 api로 받아와야 하는데 현재 제가 이해한바로는 의미가 없는 방법인것 같습니다.

 

결론은, api server에 인증(로그인)을 하여 token값을 클라이언트에 받아왔어요.

api server에서는 이 token값으로만 사용자를 구별하죠?

문제는, api server의 POST, PUT등의 정보 update와 관련된 호출은 프로그램 로직상에서만 호출이되어야지 url과 token만 알아내어 임의로 호출하면 안되잖아요.

 

이 보안문제를 어떻게 해결해야 할까요 ㅜ ㅜ
콜로라도 (120 포인트) 님이 2017년 8월 25일 질문

2개의 답변

0 추천
아래와 같은 방법으로 해결 할 수 있을 듯 합니다.

앱단에서 앱을 실행 했을시 토큰 요청을 합니다.

서버는 토큰을 생성하여 저장하고 토큰을 보낼시 암호화를 하되 토큰 + 시간값 또는

매번 달라지는 값 포함하여 암호화 합니다.

위의 이유는 같은 토큰 값을 보낼때 매번 같은 값이 암호화 된 값을 가지게 되면 토큰을 가로채갈수 있기 때문입니다.

클라이언트는 수신 받은 값을 복호화 하여 불필요한 토큰 값을 제외하고 암호화 합니다.

이후 클라이언트에서 서버로 요청시 요청할 데이터 + 토큰 + 시간(또는 매번 변하는 값)을 암호화 하여 서버로 전송 합니다. (위와 설명한 대로 동일한 요청을 하더라도 매번 변하는 값으로 인해 암호화시에도 매번 같은 값이 전송되지 않습니다.)

서버도 동일하게 전송합니다.

앱 종료시에는 클라이언트에서는 서버단에 토큰 삭제 요청을 전송하고 자신의 단말에서도 삭제 합니다.

서버에서는 해당 토큰을 삭제 합니다.

 

대부분 SSL 통신을 하면 보안이 되나 조금더 강화 하고 싶은 경우 위와 같이 통신 하면 되지 않을까 합니다.

또한 토큰에 유효 시간을 포함 시켜 앱이 정상 종료가 아닌 강제 종료가 되었을 경우 처리를 해주면 될 것 같습니다.

토큰의 유효 시간이 지난경우 삭제 하는 방법과 같은......

 

다만 암호화 키가 탈취 당한 경우 이 경우는 막을 수 없습니다.
익명사용자 님이 2017년 8월 25일 답변
0 추천
보통은 서버에서 Session을 관리합니다.

서버 Session은 로그인을 통해서 생성되기 때문에,

만약에 다른 디바이스로 접속하게 되면 세션을 새롭게 발급받아야 하기 때문에, 새로운 접속에 대해서 로그인을 요구 할 수 있습니다.

그리고 사이트의 성향에 따라서 다릅니다.

예를들어, 페이스북은 해당 단말의 브라우저에서 한번 로그인하면 왠만해서는 토큰이 expired 안되기 때문에, 로그인이 자동으로 동작합니다. 해당 단말로 한번 로그인하면 이후에 그 단말은 그 사람 것으로 인정하는 것이죠.

그러나 뱅킹 서비스들은 세션 타임아웃이 되면 무조건 로그인을 수동으로 다시 해야 하죠.

저는 포탈들은 대부분 자동 로그인을 허용해도 된다고 생각합니다.

페이스북이 그렇게 해서 문제가 없었고,

개인정보를 보거나 수정할 때에 혹은 결재할 때, 로그인을 강제하면 문제가 없다고 생각합니다.

별도로 구글 처럼, 같자기 다른 나라에서 접속하는 경우, 완전히 새로운 단말에서 접근하거나, OS를 새로 설치해서 접근할 떄... 등등 그런 경우에 로그인을 다시 유도 하면 됩니다.

남들이 보거나 수정하면 안되는 화면들만 막고, 나머지는 다 오픈해도 크게 문제가 없다고 생각합니다.
Will Kim (43,170 포인트) 님이 2017년 8월 25일 답변
restful의 또다른 부분을 설명하신건지는 잘 모르겟지만, 서버에 session을 개입시키면 restful에 맞지 못한게 됩니다.
restful은 stateless로 하셔야 합니다만...
Restful 이라면 달라집니다. Restful 서비스에서 로그인은 보통 없을 것 같습니다. 로그인 부터는 Stateless가 아닌 것이죠. Token도 State로 볼 수 있다고 생각합니다.
로그인 전까지는 Restful 이었다가, 로그인을 하면서 일반적인 서비스로 바뀌어야 할 것 같습니다. 예를들어 쇼핑몰이라고 한다면, 로그인 없이 상품들이 다 보이죠. 그러나 로그인을 하면 장바구니 등 유저에 해당하는 상태가 보존되어야 하고, 다지 재 접속해도 그 상태는 남아있는 것이죠.
...