OAuth 2.0 implicit grant flow 를 인증에 사용하면, 차가 통과할 정도로 큰 보안 홀이 열려, 라고 하는, 존 브래들리씨에 의한 양 기사.코멘트도 읽어 응해 있습니다.
 
Facebook이나, 그 외 OAuth 로그인하고 있는 사이트는 모두 체크!

In some of the feedback I have gotten on the openID Connect spec, the statement is made that Connect is too complicated. That OAuth 2.0 is all you need to do authentication. Many point to Identity Pro…

 

영어를 읽고 싶지 않다는 사람을 위해 간단히 설명하면 ...

OAuth 2.0의 implicit flow를 사용하여 "인증"을 시도하면 매우 큰 구멍이 열립니다.

컷&페이스트택이 가능하기 때문입니다.

OAuth 인증? 는 그림 1과 같은 흐름이 됩니다.

그림 1 OAuth 인증? 흐름

겉으로보기에는 문제가없는 것처럼 보입니다. 그러나 모든 사이트가 "좋은 사이트"라면.

Site_A가 사실 나쁜 사이트라고 가정 해 봅시다. 그러면 Site_A 는 이 사용자가 되어 바뀌는 access_token 을 완전히 입수해 버린 것입니다.

Site_A는 이후이 사용자가 스푸핑하여 모든 "OAuth 인증?"을하는 사이트에 로그인 할 수 있습니다.

비 기술자를위한 OAuth 인증 (?)과 OpenID의 차이 시작 에도 썼습니다만, 목적지가 쓰지 않은 합키 건네 버려, 그것을 가지고 있는 사람은 누구라도 나의 분신이라고 말하고 있는 것이니까 당연하네요.

구체적으로 쓰면,

Site_A는 브라우저(User Agent) UA를 사용하여 Site_B에 가서 로그인하려고 하면 위와 동일한 절차에서 Site_B는 "인증"을 시도합니다. 이것을 Site_B에 전달하지 않고 이전에 얻은 사용자 (= 피해자)의 액세스 토큰 access_token_A를 대신 전달합니다.Site_B가 이 토큰이 사실 Site_A를 위한 것임을 인식할 수 있는 방법은 없습니다. 그러므로, 자신을 위한 것으로 받아 버립니다. 그리고, Site_B는 GraphAPI에 access_token을 던져 피해자의 email이나 user_id를 얻으려고합니다.GraphAPI가이 Site_A에 대한 토큰을 보내는 것이 Site_B라는 것을 인식 할 수있는 방법도 없습니다.따라서 GraphAPI는 Site_A가 요청한 것처럼 피해자의 이메일과 user_id를 다시 보냅니다.결과적으로 Site_B는 공격자를 피해자로 로그인시킵니다 [5].이 흐름이 그림 2입니다.

그림 2 OAuth의 access_token 대체 공격

이는 OAuth의 state 매개 변수를 사용하여 XSRF 대책을 수행하는 것을 방지하지 않습니다. 즉, OAuth 2.0 클라이언트는 해당 클라이언트(사이트)에 로그인한 모든 사용자가 스푸핑하고 다른 OAuth 지원 사이트에 로그인할 수 있습니다.

이것은 OAuth 문제가 아닙니다.

OAuth 는 Authorization Delegation Protocol = 인가를 델리게이션하기 위한 프로토콜이며, 사용자 인증을 위한 프로토콜이 아니기 때문입니다[5].

사실, Facebook도 이것을 알고 있고,signed_request 라는 API를 가지고 있습니다.이것은 대부분 OpenID Connect와 같습니다 [2]. client side flow (페이스 북의 기본값)을 인증 대신 잡아요? ! [7]

Google의 Identity Service 책임자 인 Eric Sachs의 John blog에 게시 된 게시물도이 중요성을 지적합니다.

OpenID Connect가 아닌 단순한 OAuth 을 인증에 사용하고 있는 IdP가 거대한 시큐리티 홀을 낳고 있다고 하는 것에 관한, 존 브래들리 씨에 의한 훌륭한 기사. 는 몇 줄의 코드를 케치했기 때문에 스스로의 보안을 망치고 있다는 것을 깨닫게 하기 위해서.

문제의 원인은 access_token의 audience가 resource endpoint인데, 인증에 사용하는 토큰의 audience는 client이어야 한다는 점에 있습니다. 도 마찬가지입니다.

제대로 치료해 주세요, 여러분.

큰 공수가 아니니까. 몇 줄을 아끼고 유저를 위험에 노출시키는[4][8]은, 꼭 그만두고 싶은 곳입니다.

 

[1] John Bradley. 미국 정부의 ICAM 속의 사람으로, IMI, OpenID, SAML 의 프로파일을 쓰고 있다 오픈 ID Foundation 이사.

[2] signed_request는 Facebook 자체 서명 방식을 취하고 있지만 OpenID Connect는 IETF JOSE WG로 표준화 된 JWS를 사용합니다. 사이트와의 호환성을 고려하여 외출하고 있습니다.

[3] 원문: Great post by John Bradley on the huge security hole many IDPs have created by using plain OAuth, instead of OpenIDConnect, for authentication. We need to keep hammering away on this point both so IDPs realize the security problems they are creating for their partners, and to get RPs to realize how easily they can compromise their own security just because of the lack of a few additional lines of code. Years ago when Google first launched its proprietary equivalent of OAuth, called AuthSub, we had a big section at the bottom warning people not to use it for authentication for exactly this reason. (source : https://plus.google.com/u/0/102425765611793764729/posts/UKcZQzuvosQ )

[4] 탈취되었다고 해도 아무 일도 일어나지 않는다면 좋지만, 유저의 개인정보를 모으거나 하면, 당연히 개인정보 유출 사건이 되는군요.

[5] 굵은 부분, 2/3 추가.

[6] (2/3 추기) 공격자인 Site_A가 자신의 access_token을 다른 사람에게 건네주는 것은, Site_A가 스스로 액세스한 결과를 건네주는 것과 얻을 수 있는 결과는 같습니다. Site_B가 사용하는 것은 별도로 위험이 증가하지 않습니다.

[7] (2/17 추기) 자전으로 코드를 쓰는 것이 아니라, Facebook 의 Javascript SDK 를 사용하는 경우, signed_request 를 사용하도록(듯이) 되어 있다. 을 사용해, 자전으로 코드를 쓰지 않는다고 하면, FB에 관해서는 피해는 그다지 아니다라고 하게 된다.

[8] (2/17 덧붙여) 원래, Javascript 등 클라이언트 디바이스상의 것에 건네주었다 access_token 을 서버 측에 건네줄 수는 없다. (https://developers.facebook.com/docs/authentication/) 등에서는, 서버에 보내도록(듯이) 그림이 쓰여 있다.