-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
2110 lines (1352 loc) · 117 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[OAuth.jp]]></title>
<link href="https://oauth.jp/atom.xml" rel="self"/>
<link href="https://oauth.jp/"/>
<updated>2020-10-28T23:34:29+09:00</updated>
<id>https://oauth.jp/</id>
<author>
<name><![CDATA[Nov Matake]]></name>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[Mix-up Attack は Per-AS redirect_uri では防げない]]></title>
<link href="https://oauth.jp/blog/2020/10/28/mix-up-cant-be-mitigated-by-per-as-redirect-uri/"/>
<updated>2020-10-28T23:05:00+09:00</updated>
<id>https://oauth.jp/blog/2020/10/28/mix-up-cant-be-mitigated-by-per-as-redirect-uri</id>
<content type="html"><![CDATA[<p>いままで Mix-up Attack は Client が AS 毎に redirect_uri を使い分けていれば防げると信じられてきましたが、それじゃ防げないケースもあるよってのが <a href="https://mailarchive.ietf.org/arch/msg/oauth/RjbSwFRmLsk0EgAY2Ter-nw66EY/">OAuth ML に投稿</a>されました。</p>
<p>細かい解説は英語読んでもらうとして、シーケンスにするとこういうことです。</p>
<p><img src="https://oauth.jp/images/posts/oauth-idp-mixup-rev2.png" alt="OAuth IdP Mix-Up Attack rev.2" /></p>
<p>Attacker AS が (Display Name やロゴ等を通じて) 一見 Honest Client に見えるような Client (Attacker Client) を Honest AS に登録しておく必要があります。</p>
<p>User が Attacker AS 選んでるのに Honest AS に飛んで Approve してしまってる部分も、<a href="https://oauth.jp/blog/2016/01/12/oauth-idp-mix-up-attack/">Attacker Proxy</a> が利用可能な状況 (e.g., Client が HTTP なエンドポイントで Honest AS のログインボタン等を表示している) であればもっと違和感のないフローになるでしょう。</p>
<p>で、解決策として AuthZ Response に “iss” を含めることが提案されているのですが、「<a href="https://oauth.jp/blog/2016/01/12/oauth-idp-mix-up-attack/">悪意のある可能性があるIdPを採用しない</a>」ってのが一番の解決策であることに代わりはありません。</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[ドコモ口座問題]]></title>
<link href="https://oauth.jp/blog/2020/09/30/docomo-kouza-kyc/"/>
<updated>2020-09-30T11:40:00+09:00</updated>
<id>https://oauth.jp/blog/2020/09/30/docomo-kouza-kyc</id>
<content type="html"><![CDATA[<p>忘れそうなので一旦メモ。</p>
<p>ドコモ口座の問題って、こういうことでしょ?</p>
<ol>
<li>銀行側のAALが1を満たさないので銀行側が銀行口座を保護できない</li>
<li>銀行側のAALが1を満たさないので「銀行にKYCを依拠する」というサービスのLoAが1を満たさずサービスとして成り立っていない
<ul>
<li>結果としてドコモ口座のIALは1 (= dアカウント登録直後と同等) のまま</li>
</ul>
</li>
<li>「銀行口座名義とドコモ口座名義の一致確認」と「銀行にKYCを依拠」が同時に発生してしまっている結果「銀行口座名義とドコモ口座名義の一致確認」が実質なされていない
<ul>
<li>参考) <a href="https://gist.github.com/nov/b8be7b50db48862784b470c1ae6c1718">https://gist.github.com/nov/b8be7b50db48862784b470c1ae6c1718</a></li>
</ul>
</li>
<li>口座の一致確認が行われていないためドコモも銀行口座を保護できない
<ul>
<li>ドコモ口座側のAALは1を満たすのでドコモがドコモ口座を保護することは可能</li>
</ul>
</li>
<li>結果として銀行口座は保護されない</li>
</ol>
<p>そして、責任分界点はこのあたりで、</p>
<ul>
<li>銀行預金に対する金銭被害の責任は銀行に帰し</li>
<li>その預金が反社に渡る責任はドコモに帰する</li>
</ul>
<p>eKYC文脈ではこのあたりが論点で、</p>
<ul>
<li>上記2をサービスとして成り立たせるためのAAL, FAL要件に関する合意</li>
<li>上記2がサービスとして成り立ったとしても上記3が実質なされていないことには代わりがないので、それを良しとするのかどうか</li>
</ul>
<p>金融文脈ではこの辺りが論点になるのかなと。</p>
<ul>
<li>銀行側のAALが1を満たさない場合でも規約上の免責事項に該当することを良しとするか</li>
<li>銀行側のAALが1を満たさない場合でも「送金先による口座名義確認とセットでは結果として銀行口座が保護される」ことを良しとするか</li>
</ul>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Zero-day in Sign in with Apple Deep-dive]]></title>
<link href="https://oauth.jp/blog/2020/06/02/zero-day-in-sign-in-with-apple-deep-dive/"/>
<updated>2020-06-02T12:22:00+09:00</updated>
<id>https://oauth.jp/blog/2020/06/02/zero-day-in-sign-in-with-apple-deep-dive</id>
<content type="html"><![CDATA[<p>先週末に <a href="https://bhavukjain.com/blog/2020/05/30/zeroday-signin-with-apple/">Zero-day in Sign in with Apple</a> とかいう記事が出ていました。</p>
<p>この記事ではいまいち詳細がわからないんで、ちょっと実際 Apple IdP の挙動調べてみたら、当該 Endpoint 発見しました。</p>
<h3>実際にどこが脆弱だったのか</h3>
<ol>
<li>非 Safari ブラウザで、適当な RP にアクセス
<ul>
<li>e.g.,) <a href="http://signin-with-apple.herokuapp.com/">http://signin-with-apple.herokuapp.com/</a> (Nov SIWA RP)</li>
<li>Safari だと OS の Native UI が出てきてブラウザ遷移しないので注意</li>
<li>既に連携済の RP の場合は一度連携解除しておくこと</li>
</ul>
</li>
<li>Sign in with Apple のボタンをクリックして Apple AuthZ Endpoint に遷移
<ul>
<li>AuthZ EP: <a href="https://appleid.apple.com/auth/authorize">https://appleid.apple.com/auth/authorize</a></li>
</ul>
</li>
<li>ログイン後、初回連携時にのみ出てくる同意画面 (メアド選択するところ) に到達
<ul>
<li><img src="https://oauth.jp/images/posts/apple/siwa-consent.png" width="500" alt="Sign in with Apple Consent Screen" /></li>
</ul>
</li>
<li>ここで「続ける」を押すと内部的に Ajax Call が実行される
<ul>
<li>Ajax API EP: <a href="https://appleid.apple.com/appleauth/auth/oauth/authorize">https://appleid.apple.com/appleauth/auth/oauth/authorize</a></li>
<li>選択されたメアドやその他の AuthZ Req Params が一通り JSON で POST される</li>
<li>レスポンスとしては <code>id_token</code> とか <code>code</code> なんかが含まれた JSON が返ってくる</li>
<li><img src="https://oauth.jp/images/posts/apple/siwa-consent-ajax-submit.png" width="500" alt="Sign in with Apple Consent Ajax Submit" /></li>
</ul>
</li>
</ol>
<p>で、問題は Step.4 で Submit されるメールアドレスが、実際当該 Apple ID に紐づいてないものでも OK だったということですね。</p>
<!-- more -->
<p><a href="https://aaronparecki.com/2020/05/31/30/the-real-cause-of-the-sign-in-with-apple-zero-day">The Real Cause of the Sign In with Apple Zero-Day</a> という解説記事では、メールアドレスの値そのものを POST するんではなく <code>real_email</code> / <code>proxy_email</code> という Flag 値のみを POST すべしとか書いてますが、実際には Apple ID には複数のメールアドレスが紐付き Sign in with Apple の同意画面でのメールアドレス選択肢も3つ以上になるケースがあるので、メールアドレスの値そのものを POST することは理にかなっています。</p>
<p>問題は、POST されたメールアドレスが当該アカウントと紐づいてるかを Apple IdP サーバーがチェックしてなかったという点だけですね。</p>
<p>現在はメールアドレスとアカウントの紐付けがサーバーサイドでチェックされているので、変なメールアドレスを投げるとちゃんと 400 が返ってきます。</p>
<!--
### Email 以外を書き換えるとどうなる?
ちなみにこの Ajax Call のタイミングで `client_id` & `redirect_uri` を通信途中で改竄してやると、別 Client 向けの Code が正規 Client の正規 Redirect URI に返されるなんていう挙動もあります。
具体的には、Nov SIWA RP でログイン開始して、Apple IdP の同意画面で実行される Ajax Call でだけ `client_id` & `redirect_uri` を以下のように書き換えてやると...
* client_id
* From: jp.yauth.signin.service3 (Nov SIWA RP)
* To: net.zexy.koimusubi.ios.signinwithapple (ゼクシィ恋結び)
* redirect_uri
* From: https://signin-with-apple.herokuapp.com/callback
* To: https://zexy-koimusubi.net/web/auth/apple_login/callback
ゼクシィ恋結び向けの `id_token` および `code` が Nov SIWA RP の Redirect URI に渡されてきます。
Submit された値に基づいてサーバーサイドで Auto-submit Form なりをレンダリングしてレスポンスを返すのではなく、既に同意画面中に仕込まれた JS とパラメーター値を使ってレスポンス返してるので、Ajax Call 中で書き換えられた `email` 以外の値はレスポンスを返すべきか否かの判断には使われていないのですね。
まぁそれ自体がそこまで大きな問題かというと、そんな気はしませんが。。。
ちょっと設計が微妙というか、フロントエンジニアが勝手に設計したらこうなっちゃった、みたいな雰囲気ですね。
ということで、まだ ID Token の `aud` は別の値にされる可能性は残っているのですが、まぁ普通に `code` 使ってバックチャネルで ID Token 取れば、`aud` が書き換えられた ID Token は発行されないんで、そうすればよいです。
Sign in with Apple のフロントチャネルで発行された ID Token は、ガン無視して捨ててやれば良いのです。あれにはまず使い道はありません。
ちなみに、既婚者はゼクシィ恋結びを利用してはなりませんし、嫁にゼクシィ恋結びと連携済の Apple IdP の画面なんかみられた日にゃ血の雨が降りますので、これを試したら即連携解除必須です。
-->
<h3>余談 : OAuth 2.0 WMRM 使われてる!</h3>
<p>Sign in with Apple には Popup Mode なるものがあります。</p>
<p>実際以下の URL にアクセスして黒い方のボタンをクリックするとそれが体験できます。<br/>
<a href="http://signin-with-apple.herokuapp.com/?popup=true">http://signin-with-apple.herokuapp.com/?popup=true</a></p>
<p>ここ、よく見ると OAuth 2.0 Web Message Response Mode (WMRM, <code>response_mode=web_message</code>) が使われています。</p>
<p>大昔、<a href="https://twitter.com/zigorou">@zigorou</a> さんと <a href="https://twitter.com/_nat">@_nat</a> さんとノリで Independent Draft まで書いて、その後放置してるやつですね。懐かしいですねぇ.. #遠い目</p>
<p><a href="https://tools.ietf.org/html/draft-sakimura-oauth-wmrm-00">OAuth 2.0 Web Message Response Mode</a></p>
<p>Apple さんは <code>redirect_uri</code> に Origin 指定したりとかはしてないんですけどね。</p>
<p>OAuth WMRM、実は Auth0 とか Okta とかも使ってるんですよね。Okta のはなんか変な Prefix ついてるけど。</p>
<ul>
<li><a href="https://auth0.com/docs/protocols/oauth2#how-response-mode-works">OAuth 2.0 Authorization Framework – Auth0</a></li>
<li><a href="https://developer.okta.com/docs/reference/api/oidc/#postmessage-data-object">OpenID Connect & OAuth 2.0 API – Okta</a></li>
</ul>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Nonce/PKCE Sidestep Attack]]></title>
<link href="https://oauth.jp/blog/2020/05/19/nonce-pkce-sidestep-attack/"/>
<updated>2020-05-19T13:06:00+09:00</updated>
<id>https://oauth.jp/blog/2020/05/19/nonce-pkce-sidestep-attack</id>
<content type="html"><![CDATA[<p>OAuth 2.1 で PKCE 必須にするしない議論が盛り上がっておりますが、今日そのスレで新しい攻撃パターンが議題に上がりました。<br/>
<a href="https://mailarchive.ietf.org/arch/msg/oauth/HZt851AobQlJMBVd6_p8iWSyRS8/">https://mailarchive.ietf.org/arch/msg/oauth/HZt851AobQlJMBVd6_p8iWSyRS8/</a></p>
<p>今のところ “Nonce/PKCE Sidestep Attack (仮” と名付けられたこの攻撃は、以下のようなシナリオで成立します。</p>
<h3>Nonce/PKCE Sidestep Attack (仮</h3>
<h4>[前提条件]</h4>
<p>ある Client に、アプリケーションコンテキストによって PKCE を使うコンテキストと Nonce を使うコンテキストが共存している。</p>
<h4>[攻撃シナリオ]</h4>
<p>以下、<a href="https://danielfett.de/2020/05/16/pkce-vs-nonce-equivalent-or-not/#noncepkce-sidestep-attack">原文</a> を要約。</p>
<ol>
<li>攻撃者は何らかの手段により Nonce に紐づいた (= PKCE code_challenge とは紐づいていない) 被害者の Code を詐取する。</li>
<li>攻撃者は PKCE を使うコンテキストにおいて自らのブラウザで Client に Authorization Request を実行させ、code_challenge だけを抜き去ったものを Authorization Server に送る。</li>
<li>攻撃者は受け取った Authorization Response 中の Code を Step.1 で取得した Code と差し替え Client に提示する。</li>
<li>Client は受け取った Code を Step.2 で生成した code_challenge に紐づいた code_verifier を付与して Token Request を実行する。</li>
<li>Authorization Server は code_challenge と紐づいていない Code を受け取ったので code_verifier は無視して Token Response を返す。</li>
<li>Client は Nonce を使うコンテキストでもないので Nonce のチェックも行わず、code_verifier が無視されたことも検知できないので成功裏に Token Response を受け取ってしまう。</li>
</ol>
<p>以上により Code 置換攻撃が成立する。</p>
<!-- more -->
<p>しかし、ここでひとつ疑問があります。</p>
<p>Authorization Server は、本当に code_challenge と紐づいていない Code を受け取った場合、それに添えられた code_verifier を無視するのでしょうか?</p>
<p>もし無視するとしたら、以下のような攻撃も成立してしまうのではないでしょうか?</p>
<h3>PKCE CSRF Protection Bypass (仮</h3>
<h4>[前提条件]</h4>
<p>ある Client は CSRF 攻撃対策として state ではなく PKCE を使っている。</p>
<h4>[攻撃シナリオ]</h4>
<ol>
<li>攻撃者は自身のブラウザで Client に Authorization Request を実行させ、code_challenge だけを抜き去ったものを Authorization Server に送る。</li>
<li>攻撃者は受け取った Authorization Response を一旦保存する。</li>
<li>攻撃者はフィッシングサイト等を介して被害者のブラウザで被害者に気づかれない形 (hidden iframe etc.) で Authorization Request を実行させつつ Step.2 で受け取った Authorization Response を被害者のブラウザに渡す。</li>
<li>被害者から Code を受け取った Client は、被害者のブラウザセッションに紐づいた code_verifier を付与して攻撃者の Code を Authorization Server に提示する。</li>
<li>Authorization Server は code_challenge と紐づいていない Code を受け取ったので code_verifier は無視して Token Response を返す。</li>
<li>Client は code_verifier が無視されたことも検知できないので成功裏に Token Response を受け取ってしまう。</li>
</ol>
<p>SameSite=Lax がデフォルトでないようなブラウザでは、上記のような攻撃は成立してしまうでしょう。</p>
<p>また以下のようなパターンもありえるかもしれません。</p>
<h3>PKCE Code Injection Protection Bypass (仮</h3>
<h4>[前提条件]</h4>
<p>ある Client は CSRF 攻撃対策としては state を、Code Injection 攻撃対策としては PKCE を使っている。</p>
<p>また Client は redirect_uri が HTTP であったりするなど、Code が漏洩しうる条件も持っている。</p>
<h4>[攻撃シナリオ]</h4>
<ol>
<li>攻撃者は自身のブラウザで Client に Authorization Request を実行させ、code_challenge だけを抜き去ったものを Authorization Server に送る。</li>
<li>攻撃者は Authorization Response を受け取り Code を一旦保存する。</li>
<li>攻撃者は被害者の Code が詐取できるポイントで、被害者の Code を詐取する代わりにそれを Step.2 で受け取った攻撃者の Code に置換する。</li>
<li>被害者から Code を受け取った Client は、被害者のブラウザセッションに紐づいた code_verifier を付与して攻撃者の Code を Authorization Server に提示する。</li>
<li>Authorization Server は code_challenge と紐づいていない Code を受け取ったので code_verifier は無視して Token Response を返す。</li>
<li>Client は code_verifier が無視されたことも検知できないので成功裏に Token Response を受け取ってしまう。</li>
</ol>
<p>う〜ん… <code>Authorization Server は code_challenge と紐づいていない Code を受け取ったので code_verifier は無視して Token Response を返す。</code> っていう挙動を許してしまうと、PKCE で対策されていたはずだった CSRF 攻撃も Code Injection 攻撃も防げなくなってしまいますね…</p>
<p>まぁそもそも被害者のブラウザ上で hidden iframe で Authorization Request を実行させたり Code を置換できたりするようなケースはほとんどないとは思いますが…</p>
<p>PKCE それでいんだっけ??</p>
<p>ということで、過去の僕の実装を見てみると…</p>
<p><a href="https://github.com/nov/rack-oauth2/blob/master/lib/rack/oauth2/server/extension/pkce.rb#L28">Rack::OAuth2 Server-side PKCE Implementation</a></p>
<p>やっぱ code_challenge に紐づいてない Code と code_verifier が渡されてきたら、ちゃんとエラーにしてますね。</p>
<p>じゃあ PKCE 採用 Authorization Server として最もメジャーな Google さんはどうでしょう…</p>
<p><a href="https://gist.github.com/nov/9feba86685bd3b18b4bf7bfb88022046">Google PKCE Client Sample</a></p>
<p>やっぱ code_challenge に紐づいてない Code と code_verifier が渡されてきたら、ちゃんとエラーにしてますね。</p>
<p>う〜ん、このケースでの挙動、<a href="https://tools.ietf.org/html/rfc7636">RFC 7636 – Proof Key for Code Exchange by OAuth Public Clients</a> では特に触れられてないんですけど、やっぱ普通に考えれば、code_challenge に紐づいてない Code と code_verifier が渡されてきたら、エラーですよね…</p>
<p>みなさんの実装はいかがでしょうか?</p>
<h3>追記</h3>
<p>上記 “PKCE CSRF Protection Bypass (仮” に関しては、以下の記事では “Downgrade Attack on PKCE” と名付けられたようです。<br/>
<a href="https://danielfett.de/2020/05/16/pkce-vs-nonce-equivalent-or-not/#downgrade-attack-on-pkce">https://danielfett.de/2020/05/16/pkce-vs-nonce-equivalent-or-not/#downgrade-attack-on-pkce</a></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Account Takeover Vulnerability in Microsoft Teams]]></title>
<link href="https://oauth.jp/blog/2020/04/28/account-takeover-vulnerability-in-microsoft-teams/"/>
<updated>2020-04-28T15:44:00+09:00</updated>
<id>https://oauth.jp/blog/2020/04/28/account-takeover-vulnerability-in-microsoft-teams</id>
<content type="html"><![CDATA[<p>約一年ぶりの記事ですね。<br/>
みなさん、三密避けて OAuth の勉強に勤しんでおられますでしょうか?<br/>
さて、今朝こんな記事が上がってました。</p>
<p><a href="https://www.itmedia.co.jp/enterprise/articles/2004/28/news056.html">「Microsoft Teams」にアカウント乗っ取りの脆弱性、画像表示だけで不正侵入 – ITmedia エンタープライズ</a></p>
<blockquote><p>今回の脆弱性は Teams のデスクトップ版と Web ブラウザ版の両方に影響する。攻撃者は狙った相手に GIF などの画像を送り付けて表示させ、画像が Web ブラウザに読み込まれる過程で認証トークンを盗み出す。被害者の画面には画像が表示されるだけなので、自分が攻撃されたことに気付かない。</p>
<p>攻撃者がこのユーザーになりすまして組織内の他の従業員に不正なGIFを送信すれば、ワームのような形で侵入を広げ、組織全体の Teams アカウントを乗っ取る可能性もある。そうなれば、社外秘情報や会議、カレンダー、パスワードといった重要情報が流出しかねない。</p></blockquote>
<p>GIF 画像貼り付けるだけで Teams アカウント乗っ取れるとか、こんなの読んだら恐ろしくて Teams なんて使えないですね。</p>
<p>この脆弱性が報告されたのが2020年3月20日ということなんですが、Teams の中の人はどんな気持ちで以下の記事を読んでいたのでしょうか。</p>
<p><a href="https://japan.zdnet.com/article/35152041/">マイクロソフト、「Teams」のセキュリティをアピール—「Zoom」に批判集まる中 – ZDNet Japan</a></p>
<p>で、ここから本題、今回の Teams の脆弱性の詳細についてです。英語ですが、こちらの記事に詳細が載ってます。</p>
<p><a href="https://www.cyberark.com/threat-research-blog/beware-of-the-gif-account-takeover-vulnerability-in-microsoft-teams/">Beware of the GIF: Account Takeover Vulnerability in Microsoft Teams | CyberArk</a></p>
<!-- more -->
<p>まず大前提として、Teams では以下のようなアクセスコントロールがなされていました。</p>
<ul>
<li>Teams は内部的に以下の2つの JWT Token を利用する。
<ul>
<li>OAuth2 Access Token
<ul>
<li>Issuer: “<a href="https://sts.windows.net/">https://sts.windows.net/</a><tenant-id>/”</li>
<li>Audience: “<a href="https://api.spaces.skype.com">https://api.spaces.skype.com</a>”</li>
<li>Scope: “user_impersonation”</li>
</ul>
</li>
<li>Skype Token
<ul>
<li>Skype ID (= End-user’s Object ID) を含んだ独自 JWT Token</li>
<li>Teams API にアクセスするためにはこちらの Token が必要</li>
<li>この Token は上記 Access Token を使って取得可能</li>
</ul>
</li>
</ul>
</li>
<li>Teams にアップロードされた画像はMSが管理するサーバーに置かれ、Teams にログイン中の状態でしか見れない。
<ul>
<li>この画像へのアクセスには “skypetoken_asm” という Cookie にセットされた “Skype Token” を利用</li>
</ul>
</li>
</ul>
<p>これだけ見ると、「GIF をアップロードしただけでアカウント乗っ取り可能」というほどクリティカルではなさそうに見えます。</p>
<p>でも、よくよく英語記事の方を読んでみると、以下の3つが組み合わさって、アカウント乗っ取りが可能になっていたようです。</p>
<ul>
<li>OAuth2 Access Token 自体が Cookie に以下の状態でセットされていた。
<ul>
<li>Key : “authtoken”</li>
<li>Domain : “*.teams.microsoft.com”</li>
</ul>
</li>
<li>以下2ドメインが Subdomain Takeover 可能であった。
<ul>
<li>aadsync-test.teams.microsoft.com</li>
<li>data-dev.teams.microsoft.com</li>
</ul>
</li>
<li>Giphy 投稿時の API Request に (Developer Console とか使えば) 任意の画像 URL を指定可能であった。</li>
</ul>
<p>うん、そりゃ Access Token ダダ漏れしますね。</p>
<p>画像ファイルのアップロード機能が問題だったわけではなく、GiphyコンテンツとしてPOSTされたコンテンツが問題だったのですね。</p>
<p>で、MS側は以下の対応を施した、と。</p>
<ul>
<li>Subdomain Takeover の脆弱性を修正</li>
<li>“authtoken” Cookie を “teams.microsoft.com” ドメインに限定</li>
</ul>
<p>これでひとまず脆弱性自体は修正されました。</p>
<p>でもそもそも、</p>
<ul>
<li>“user_impersonation” Scope さえ持ってれば全 API にアクセス可能可能で</li>
<li>そのトークンをいろんなサブドメインに投げまくる</li>
</ul>
<p>前提の設計って、どうなんでしょうね。。</p>
<p>Skype Token はいまだにいろんなドメインのいろんな API に以下のように統一感ない形で送られていて</p>
<ul>
<li>Authorization: skypetoken XXX</li>
<li>Authorization: skype_token XXX</li>
<li>x-skypetoken: XXX</li>
</ul>
<p>挙句には Cookie に</p>
<ul>
<li>“skypetoken_asm” という Key で</li>
<li>“*.asm.skype.com” ドメイン指定で</li>
</ul>
<p>セットされてますし</p>
<ul>
<li>この Token にも Scope という概念がない (“scp=780” 固定)</li>
</ul>
<p>ようですし。。</p>
<p>やはり僕らは</p>
<ul>
<li>Google Wave だか</li>
<li>Google Duo だか</li>
<li>Google Allo だか</li>
<li>Google Hangouts だか</li>
<li>Hangouts Meet だか</li>
<li>Google Meet だか</li>
</ul>
<p>とかいうコロコロ名前とかブランド変わってるのか別プロダクトなのかすらようわからんアレを使うしかないのでしょうか?</p>
<p>ps.<br/>
2020年4月現在、世界中コロナで大変な時期ですが、次の記事を書く頃には世の中落ち着いているでしょうか?
そしてそのころ Google のアレはなんていう名前になっているのでしょうか?</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Sign in With Apple の特徴分析 (2)]]></title>
<link href="https://oauth.jp/blog/2019/06/12/sign-in-with-apple-analysis-2/"/>
<updated>2019-06-12T15:14:00+09:00</updated>
<id>https://oauth.jp/blog/2019/06/12/sign-in-with-apple-analysis-2</id>
<content type="html"><![CDATA[<p><a href="https://oauth.jp/blog/2019/06/08/sign-in-with-apple-analysis/">Sign in With Apple の特徴分析 (1)</a> のつづき。</p>
<p>文章でつらつら書いても結局わかりづらいもんはわかりづらいんで、もう箇条書きで淡々と。</p>
<p>これだけそろってれば、あと最後の <strong><em>要調査</em></strong> ってとこを各自必要に応じて調べるなり、誰かがこの記事にコメントしてくれるなりすれば、一通りみなさんのサービスの設計に落とせるんでは無いかと思います。</p>
<p>※ 落とせない人は <a href="https://yauth.jp">僕 (= YAuth.jp 合同会社) に仕事を依頼する</a> という手もありますw</p>
<!-- more -->
<h2>各種 ID とその対象 (?) 範囲</h2>
<h3>Developer が使う IDs 等</h3>
<ul>
<li>Team ID
<ul>
<li>個人向け Apple Developer Account では Developer Account に1つ</li>
<li>Enterprise 向け Apple Developer Account での話はしらない</li>
</ul>
</li>
<li>App ID
<ul>
<li>App Store に並べるアプリ毎に1つ</li>
<li>MacOS App と iOS App では別 App ID</li>
<li>Native SDK で Sign in with Apple する場合の Client ID に相当</li>
<li>App ID に対して Sign in with Apple の設定をする際には以下が必要
<ul>
<li>Primary App ID の指定</li>
</ul>
</li>
<li>Sign in with Apple の設定を通じて Primary App ID に紐づく</li>
</ul>
</li>
<li>Service ID
<ul>
<li>App Store に並べるアプリには紐づかない ID</li>
<li>現状この Service ID を使ってできることは Sign in with Apple のみ</li>
<li>Service ID に対して Sign in with Apple の設定をする際には以下が必要
<ul>
<li>Primary App ID の指定</li>
<li>Web Domain の設定と Domain Verification</li>
<li>Return URIs (= redirect_uri) の指定
<ul>
<li>複数可</li>
<li>上記 Verified Domain 外の URL でも指定可
<ul>
<li>Domain Verification の存在意義は不明..</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>Native SDK の外で Sign in with Apple する場合の Client ID に相当</li>
<li>Sign in with Apple の設定を通じて Primary App ID に紐づく</li>
</ul>
</li>
<li>Primary App ID
<ul>
<li>App ID および Service ID に対して Sign in with Apple の設定をする際に指定</li>
<li>Primary App ID 単位で Key を発行</li>
<li>Primary App ID 単位で Client Access を Revoke</li>
<li>(たぶん) Primary App ID 単位で Private Email を発行</li>
</ul>
</li>
<li>Key
<ul>
<li>Client Secret に指定する JWT に署名するための EC 秘密鍵</li>
<li>Primary App ID に紐づく</li>
<li>1つの Primary App ID に複数の Key を発行可能</li>
</ul>
</li>
<li>Client Secret に指定する JWT
<ul>
<li>iss
<ul>
<li>Team ID</li>
</ul>
</li>
<li>aud
<ul>
<li>Apple IdP の Issuer Identifier</li>
</ul>
</li>
<li>sub
<ul>
<li>Native SDK で code を受け取った場合は当該アプリの App ID</li>
<li>Native SDK 以外で code を受け取った場合は当該サービスの Service ID</li>
<li>code を access_token と交換する役目を負う Backend Server の Client ID とは限らない点に注意</li>
</ul>
</li>
<li>iat
<ul>
<li>現在時刻 (UNIX Timestamp)</li>
</ul>
</li>
<li>exp
<ul>
<li>現在より未来かつ6ヶ月以内の時刻 (UNIX Timestamp)</li>
<li>通常は Token Request 毎に動的に JWT を生成し数分後くらいの exp を指定するものと思われる</li>
</ul>
</li>
<li>署名鍵
<ul>
<li>当該 Client に紐づく Primary App ID に紐づいた Key</li>
</ul>
</li>
</ul>
</li>
<li>Private Email Relay Service 設定
<ul>
<li>Team ID に紐づく</li>
<li>当該 Team ID 配下の全 App ID / Service ID に対して発行された Private Email Address にメール送信できる送信元ドメイン & メールアドレスを指定</li>
<li>10 ドメインまでしか登録できない
<ul>
<li>10+ サービスを同一 Team ID 配下に登録しつつサービス毎に送信元ドメイン変えるとかは無理かも</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>User に紐づく IDs 等</h2>
<ul>
<li>ID Token の sub
<ul>
<li>Team ID 単位で異なる PPID</li>
</ul>
</li>
<li>Private Email
<ul>
<li>現状これがどの単位で異なる値となるのか不明 (実機の iOS 13 beta も Simulator も挙動が不安定)
<ul>
<li>Team ID 単位?</li>
<li>Primary App ID 単位? <= Revoke 単位見る限りたぶんこれ</li>
<li>App ID 単位?</li>
<li>Primary App ID 単位?</li>
</ul>
</li>
<li>Revoke 毎に変わる
<ul>
<li>sub は Revoke 前後でも変わらないんだしメアドだけ変わる意味は無いのだが…</li>
</ul>
</li>
<li>当該アドレスに紐づく Team ID の Private Email Relay Service に登録された送信元ドメイン & メールアドレスからしかメールが届かない
<ul>
<li>Revoke 画面で Revoke はせずにメール転送を OFF にすることも可能</li>
</ul>
</li>
<li>単一 Team ID 内に複数の Primary App ID がある場合は単一 sub に複数 Private Email を紐づけて保存する必要あり
<ul>
<li>sub は Team ID 単位でメアドは Primary App ID 単位であることからくる現象
<ul>
<li>※ あくまで Private Email が Primary App ID 単位で発行されるという前提で話をしている</li>
</ul>
</li>
<li>Email の転送 ON/OFF 設定は Revocation 単位 (= Primary App ID 単位) なので、転送 OFF したつもりが別アプリ向けメアドにメール来たりすると問題</li>
</ul>
</li>
</ul>
</li>
<li>Client Access の Revocation
<ul>
<li>Primary App ID 単位</li>
</ul>
</li>
</ul>
<h2>その他調べるべき項目</h2>
<ul>
<li>Touch ID / Face ID 使えるパターン・使えないパターン
<ul>
<li>iOS
<ul>
<li>SDK (ASAuthorizationAppleID~) => 使える</li>
<li>ASWebAuthenticationSession => <strong><em>要調査</em></strong></li>
<li>SFAuthenticationSession => <strong><em>要調査</em></strong></li>
<li>SFSafariViewController => <strong><em>要調査</em></strong></li>
<li>WKWebView => <strong><em>要調査</em></strong></li>
<li>UIWebView => <strong><em>要調査</em></strong> でもまだこれいるの?</li>
</ul>
</li>
<li>MacOS
<ul>
<li>SDK (ASAuthorizationAppleID~) => <strong><em>要調査</em></strong> たぶん使える</li>
<li>ASWebAuthenticationSession => <strong><em>要調査</em></strong></li>
<li>WebView => <strong><em>要調査</em></strong> そもそも MacOS の場合の WebView とかさっぱりわからん</li>
</ul>
</li>
<li>Safari
<ul>
<li>w/ Apple JS SDK => 使える</li>
<li>w/o Apple JS SDK => 使えない
<ul>
<li>ただし近い将来 appleid.apple.com ドメイン全体で Touch ID / Face ID が使えるようになる兆しあり</li>
</ul>
</li>
</ul>
</li>
<li>Android => 使えない</li>
<li>Safari 以外のブラウザ => 使えない</li>
</ul>
</li>
</ul>
<p>ということで、要調査のところはそろそろめんどくさくなってきたんでわかった人教えていただけるとありがたいですw</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Sign in with Apple の特徴分析 (1)]]></title>
<link href="https://oauth.jp/blog/2019/06/08/sign-in-with-apple-analysis/"/>
<updated>2019-06-08T21:04:00+09:00</updated>
<id>https://oauth.jp/blog/2019/06/08/sign-in-with-apple-analysis</id>
<content type="html"><![CDATA[<p><a href="https://oauth.jp/blog/2019/06/04/sign-in-with-apple/">前記事</a> で書いたように、ここ数日 Sign in with Apple 用の RubyGem 作りながら、Sign in with Apple の特徴というか、他の IdP との違いみたいなところいろいろ調査したので、現時点での Sign in with Apple に対する雑感をまとめておきます。</p>
<h2>Client ID と Team ID および App ID との関係</h2>
<p>個人として Apple Developer Account 使ったことしかないんで、会社として Developer 登録してる時の Team の扱いとかよくわかってないんですが、Apple Developer Account 登録すると Team ID ってのが割り振られます。個人だと 1 Developer Account に 1 Team ID。</p>
<p>この1つの Team ID の下に、複数の子 App ID が登録可能です。1 iOS App についき 1 App ID。</p>
<p>さらに、App ID には “Primary” という概念もあり、1つの Primary App ID の下に複数の App ID を登録することができます。</p>
<p>ここまでは、お仕事で実際に iOS App 作ってる人たちにはきっと当たり前な話なんだと思います。</p>
<p>そして、Primary App ID の下に App ID の代わりに Service ID っていうのが登録できます。</p>
<p>Service ID っての設定画面には Sign in with Apple 関連の設定項目しかないから、これは今回初めて出てきたものなのかもしれませんね。</p>
<p>で、iOS App で Sign in with Apple 使う場合は App ID というのが OAuth Client に該当し、Web とか Android とかで Sign in with Apple 使う時は、 Service ID というのが OAuth Client に該当するようです。</p>
<p>1 Team ID の下に複数 App ID が登録され、1 App ID の下に複数の子 App ID と Service ID が登録され、iOS/Mac Native の世界では App ID が、それ以外では Service ID が OAuth Client となる。</p>
<p>ここまではいいですね?いや、正直間違ってるかもしれんけどw</p>
<p>そして、Client の鍵 (Client Secret を生成する為の秘密鍵、詳しくは後述) を別途生成するのですが、この鍵は Primary App ID 毎に登録することになります。</p>
<p>鍵は Key Rotation のことも考慮してか、1 Primary App ID に複数同時に登録できます。</p>
<p>ただ、1 OAuth Client に 1 Private Key、という単位ではないので、鍵管理のやり方は普通の OAuth Client の場合と異なるやり方が必要になる Developer さんもいるかもしれませんね。</p>
<!-- more -->
<h2>User ID の発行ルール</h2>
<p>Apple が発行する User ID (Subject Identifier) は PPID (Pairwise Pseudonymous Identifier) になっています。</p>
<p>通常の OIDC では、PPID は同一ユーザーでも Client ID が異なれば異なる値となり、複数 Client 間でユーザーの名寄せを防ぐ効果があります。</p>
<p>しかし Apple の場合は Web では Web の Service ID、iOS App では iOS App の App ID というように、同一サービスでも Client ID が異なるので、それらの間でユーザーの名寄せができないと困ってしまいます。</p>
<p>そのため、Apple は Team ID 単位で PPID を発行します。</p>
<p>同一ユーザーでも、User ID が渡されるアプリの Team ID が違えば User ID は異なるが、同一 Team ID 内では全ての App ID および Service ID にまたがって同一の User ID を受け取ることができます。</p>
<p>Primary App ID 単位で PPID 払い出す方が自然な気がしますが、まぁその辺は Apple Developer 経験無いんでよくわかりません。</p>
<h2>Email アドレスの発行ルール</h2>
<p>Native SDK 経由で Sign in with Apple 使った場合は、”email” scope を要求するとユーザーの Email アドレスを受け取ることができます。(現状では Web では同じ scope 要求しても Email を受け取る術はありません)</p>
<p>この Email アドレスは、当該 Apple ID に紐づいたメアド (複数存在することあり) を渡すか、Apple が発行するランダムなメアドを渡すかを、ユーザーが選ぶことができます。</p>
<p>ランダムなメアドを使った場合、そのメアドは当該 Client のアクセスを Revoke した時点で利用不可能となり、次回同一ユーザーが再度 Approve すると別のメアドが発行されることになります。</p>
<p>通常の Social Login では、初回登録時にメアドを取得したら、次回以降のログイン時には別メアドが渡されてきても無視していることが多いと思いますが、Sign in with Apple でランダムなメアド受け取っている場合には、次回以降のログイン時に別のランダムなメアド渡されると、古いメアドを新しいものに更新してやる必要があります。</p>
<p>なお、現状では Native SDK 以外では Email 受け取る術がないので、このままだと Web で Sign in with Apple で登録されてしまうと、登録時にはメアドが取れないことになります。Twitter ログインみたいですね。</p>
<h2>Client Secret の発行ルール</h2>
<p>Client Secret というのは通常固定値で、環境変数なりに入れておいてずっと同じ値を使い続けていると思いますが、Sign in with Apple では Client Secret として JWT を生成する必要があります。</p>
<p>詳しい Client Secret の生成方法は <a href="https://github.com/nov/apple_id/blob/05b06750b219080022191b6497b0bc768b2c0dd9/lib/apple_id/client.rb#L22">僕の RubyGem の当該部分</a> 見ていただくとお分かりかと思いますが、Issuer が Team ID で、Subject に Client ID を指定します。</p>
<p>なお、この JWT には Private Key 毎に Apple が割り振る Key ID を kid ヘッダーに指定することになっているのですが、どうもこの kid を指定しなくても動くようで、kid 指定してない記事がちらほら見受けられます。</p>
<p>Key Rotation 途中の複数鍵が存在するシチュエーションでだけエラーになるとかあるあるなんで、kid は指定するようにしましょうね。</p>
<h2>ID Token の発行ルール</h2>
<p>Native SDK や Apple が提供する JS SDK を使うと、フロントエンドで Authorization Code と同時に ID Token が受け取れます。</p>
<p>これには response_type=code+id_token を利用しています。</p>
<p>ただ、通常 OIDC ではフロントチャネルで発行された ID Token には nonce を含める必要があるのですが、Sign in with Apple では nonce 自体サポートされていません。</p>
<p>Replay 攻撃し放題ですね。</p>
<p>もし Replay 攻撃されて困るようであれば、フロントチャネルで受け取った ID Token は華麗にガン無視し、Authorization Code を使って Token Request を送り、バックチャネルで受け取った ID Token だけを利用するようにしましょう。</p>
<p>なおこの場合でも nonce がないのでいわゆる “Code Injection 攻撃” に対しては対処しようがありません。</p>
<p>現状 OAuth Client 側ができる対応としては、Authorization Code を漏らさないように頑張るくらいしかなさそうです。</p>
<p>てか、フロントチャネルで発行される ID Token って、使い道としては Detached Signature くらいしかないはずなんですけど、c_hash もなく nonce もない ID Token 発行する Apple さんは何考えているんでしょうか?</p>
<p>何の使い道もない ID Token を発行しないでください。バカが使って脆弱性を作ってしまうではないですか。</p>
<h2>UserInfo の取得方法</h2>
<p>既に述べましたが、Email (と Display Name) は Native SDK でしか取得できません。</p>
<p>Web で登録された時にメアド取れなくて困るってのもあるんですが、そもそもフロントチャネルで取得した UserInfo って、結局バックエンドに送るじゃないですか?</p>
<p>で、バックエンドへの通信って、Charles Proxy みたいないわゆる SSL Proxy 使うと、端末所有者からすれば割と簡単に書き換え可能じゃないですか?</p>
<p>でも、そのメアドは Apple さん的には Verify 済だとおっしゃるんですよ。だから疎通確認メールを各 Client が送信する必要はない、と。</p>
<p>いやいや、フロントチャネルでそんなメアド渡されたって、Verified な状態でそのままバックエンドに送るの大変ですから。</p>
<p>Native SDK では User ID までフロントチャネルで取れちゃうんで、アプリからバックエンドに Email と User ID 送りつけて、それ改ざんしたら他人のアカウントにログインできちゃう〜、みたないアプリが出てきそうなにおいがします。</p>
<h2>User 認証の UX</h2>
<p>Safari で Apple 公式 JS SDK を使った場合と Native SDK を使った場合は、OS ログイン時のパスワードとか FaceID / TouchID で認証することでユーザー認証が行えます。</p>
<p>これは UX 素晴らしいです。</p>
<p>UX 的にはほぼほぼ WebAuthn と同じであり、iOS Web では WebAuthn じゃなくて Sign in with Apple でいいんじゃね?みたいな気がしなくもないです。</p>
<p>が、それ以外の環境でのログイン UX は結構辛いものがあります。</p>
<p>Apple ID ってなんかやたら二段階認証設定させようとしてくるし、ついつい二段階認証有効にしてしまうじゃないですか?で、6桁 PIN が iPhone なり Mac に飛んできますよね?</p>
<p>あれを Android ユーザーが Web で使うことを考えてください。</p>
<p>その6桁 PIN が飛んでくる端末、きっとそん時そのユーザーの手元には…ないよねぇ〜。</p>
<p>まぁ SMS で PIN 送るオプションもあるんで、Android 単体で完結しなくもないですけど、ちょっと iOS から Android に乗り換えたユーザーのこと考えると、悪夢です。</p>
<h2>まだまだ続くかな?</h2>
<p>もうそろそろ疲れたので今日はこれくらいで。</p>
<p>もうちょい気になる点あるんだけど、それは (2) で書くかもですし、(2) は無いかもです。</p>
<p>あ、ヤフースコア取得用 Client ID が取得できたら、絶対 (2) も書いちゃうな〜。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">Y!J 社に大人な感じで「ヤフースコア確認サービス」という各ユーザーが自分のヤフースコアを確認できるサービスを作りたいから Client IDくれよって依頼を投げてみた。</p>— nov matake (@nov) <a href="https://twitter.com/nov/status/1135853530072305664?ref_src=twsrc%5Etfw">June 4, 2019</a></blockquote>
<p> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">Y!J 社に大人な感じで「ヤフースコア確認サービス」という各ユーザーが自分のヤフースコアを確認できるサービスを作りたいから Client IDくれよって依頼を投げてみた。</p>— nov matake (@nov) <a href="https://twitter.com/nov/status/1135853530072305664?ref_src=twsrc%5Etfw">June 4, 2019</a></blockquote>
<p> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">Y!J 社に大人な感じで「ヤフースコア確認サービス」という各ユーザーが自分のヤフースコアを確認できるサービスを作りたいから Client IDくれよって依頼を投げてみた。</p>— nov matake (@nov) <a href="https://twitter.com/nov/status/1135853530072305664?ref_src=twsrc%5Etfw">June 4, 2019</a></blockquote>
<p> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p>自分で OAuth Client 自作できるみなさんにはぜひ Yahoo! JAPAN にヤフースコア取得可能な Client ID 発行を依頼することをお勧めしますし、そうでないみなさんにはヤフースコアのオプトアウトをお勧めします。</p>
<p><a href="https://news.yahoo.co.jp/byline/fujisiro/20190604-00128752/">ユーザーの行動や消費を“格付け”「Yahoo!スコア」の作成・利用を拒否する方法</a></p>
<p>それではいい週末を。</p>
<p>追記)<br/>
<a href="https://oauth.jp/blog/2019/06/12/sign-in-with-apple-analysis-2/">Sign in With Apple の特徴分析 (2)</a> 書きました。</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Rubygem for Sign in with Apple & Rails Sample App]]></title>
<link href="https://oauth.jp/blog/2019/06/04/sign-in-with-apple/"/>
<updated>2019-06-04T22:38:00+09:00</updated>
<id>https://oauth.jp/blog/2019/06/04/sign-in-with-apple</id>
<content type="html"><![CDATA[<p>iOS App に Apple ID でログインできたらいいのになぁ〜と思い続けてはや数年、ついにそんな時代がやってきましたね!</p>
<p>ということで、FB Connect 登場時の fb_graph gem リリース以来のスピード感で、Sign in with Apple 用の ruby gem をリリースしてみました。</p>
<p><a href="https://github.com/nov/apple_id">github.com/nov/apple_id</a></p>
<p>ついでに Rails のサンプルアプリも。</p>
<p><a href="https://github.com/nov/signin-with-apple">github.com/nov/signin-with-apple</a></p>
<p>このサンプルアプリはこちらで動かしてるので、試したい方はどうぞ。</p>
<p><a href="https://signin-with-apple.herokuapp.com/">signin-with-apple.herokuapp.com</a></p>
<p>Sign in with Apple は OpenID Connect を採用してるんですが、現状では Native SDK でしか email や fullName は取れないようです。</p>
<p>そのうち UserInfo API が出てくると思うんで、出てきたら apple_id gem でもサポートしようかと思います。</p>
<p>ps.<br/>
とりあえず Terminal で動かすだけでいいよって方はこちらのサンプルをどうぞ。</p>
<p><a href="https://gist.github.com/nov/993a303aa6badd8447f7b96fb952088e">https://gist.github.com/nov/993a303aa6badd8447f7b96fb952088e</a></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Alexa と Nature Remo の Account Linking]]></title>
<link href="https://oauth.jp/blog/2018/03/09/alexa-and-nature-remo/"/>
<updated>2018-03-09T20:24:00+09:00</updated>
<id>https://oauth.jp/blog/2018/03/09/alexa-and-nature-remo</id>
<content type="html"><![CDATA[<p>ついに <a href="http://amzn.to/2HjU7Yp">Amazon Echo Plus</a> の購入券当選通知が来たので、Echo Plus と一緒に <a href="http://amzn.to/2oVl4Ls">Nature Remo</a> を買いました。</p>
<p><a href="https://www.amazon.co.jp/Nature-Inc-Remo-01-Remo/dp/B06XCQFP96/ref=as_li_ss_il?s=aps&ie=UTF8&qid=1520594772&sr=1-1-catcorr&keywords=nature+remo&linkCode=li3&tag=bianca0b-22&linkId=13d9bc61ca409c43ab2dc391c559aa12" target="_blank"><img border="0" src="https://oauth.jp//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B06XCQFP96&Format=_SL250_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=bianca0b-22" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=bianca0b-22&l=li3&o=9&a=B06XCQFP96" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
<p>エアコン推しですが、テレビのリモコン等、赤外線飛ばすリモコンならなんでも対応できる、素敵な「スマートリモコン」です。</p>
<p>Nature Remo アプリでセットアップして、アプリからリモコンつけたり消したりできるのも素敵ですし、アプリで設定しといたら iPhone が Nature Remo から 30m 以上離れたら自動でエアコン切るルールとか設定しとけるのも素敵です。</p>
<p>が、やはりここは</p>
<p><strong>「Alexa、エアコンをつけて」</strong></p>
<p>ってやりたいですよね。</p>
<!-- more -->
<p>そのためには、Alexa アプリで「Nature Remo Smart Home Skill」ってのをインストールして、アカウントリンキングを設定する必要があります。Nature Remo に紐づいた Nature Remo アカウントと、Alexa に紐づいた Amazon アカウントを紐づける処理ですね。</p>
<p>で、これ、Alexa アプリから OAuth Authorization Request をスタートさせて、Nature Remo 側の Authorization Server にログインして、Alexa アプリ (というか Alexa 側の Redirect URI) に戻ってくる必要があります。</p>
<p>ここで、Nature Remo 側で必ずエラーになります。</p>
<p>Nature Remo アカウントって、パスワードがなくて、毎回登録したメアドに送られてくるマジックリンクをクリックしてログインするんですよ。</p>
<p>でね、Alexa アプリの SafariViewController でメアド入力して、外部 Safari でメール中のリンククリックすると、両者のセッションがずれちゃうから、CSRF エラーかなんかになってるんですよ。</p>
<p>US の Alexa の場合は、Amazon.com サイトから Skill インストールできるから、PC/Mac で設定してやればうまくいくのかもしれませんが、日本の場合は Alexa アプリからアカウントリンクスタートするしかないんで、これ絶対にログイン成功しませんよね…</p>
<p>でもまぁ、僕はちょっと OAuth とか iOS とか詳しいんで、やってやりましたよ。</p>
<p>絶妙なタイミングで、SafariViewController の下の方にある外部 Safari 開くボタンを、押してやりましたよ。</p>
<p>そう、OAuth Authorization Request が Remo サーバーに届く前に、外部 Safari に遷移してしまうんです。</p>
<p>で、なんとかうまくいきました。</p>
<p><strong>これ一般ユーザーには無理ゲーすぎやろ。</strong></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[SAML Authentication Bypass Vulnerability]]></title>
<link href="https://oauth.jp/blog/2018/03/02/saml-authentication-bypass-vulnerability/"/>
<updated>2018-03-02T10:42:00+09:00</updated>
<id>https://oauth.jp/blog/2018/03/02/saml-authentication-bypass-vulnerability</id>
<content type="html"><![CDATA[<p>脆弱性の内容に関する <a href="http://idmlab.eidentity.jp/2018/03/saml-idp.html">日本語解説はこちら</a>。</p>
<p>で、実際に脆弱性が存在してた実装もみてみると、OneLogin 製の ruby-saml だと、該当の脆弱性はここで修正されてます。</p>
<p><a href="https://github.com/onelogin/ruby-saml/commit/048a544730930f86e46804387a6b6fad50d8176f">Fix vulnerability CVE-2017-11428. Process text of nodes properly, ign… · onelogin/ruby-saml@048a544</a></p>
<p><a href="https://github.com/onelogin/ruby-saml/commit/048a544730930f86e46804387a6b6fad50d8176f#diff-d3e2c1bdc6c1e8b207dd7ded3ae35320R288">この行</a> がまさにメインの修正箇所なんですが、いままで <code>REXML::Element#text</code> 呼んでいたものを、すべて <code>REXML::Element#texts</code> を <code>join</code> するように変更してますね。</p>
<p>でも、そもそもこれ署名検証の部分の修正が含まれてないのはなぜでしょう?</p>
<p><a href="https://github.com/onelogin/ruby-saml/blob/048a544730930f86e46804387a6b6fad50d8176f/lib/xml_security.rb#L271">署名検証してるのはここ</a> なんですが、これ、よくみると <code>REXML</code> じゃなくて <code>Nokogiri</code> 使ってますね。<code>REXML</code> には XML 正規化の機能がなかったから、その部分だけ <code>Nokogiri</code> 使ったんですかね。</p>
<p><strong>なら全部 <code>Nokogiri</code> 使えや。</strong></p>
<p>2つの XML Parser を1つの実装の中で混在させてる時点で、すごいやな香りしますよね。<code>ruby-saml</code> は今回の脆弱性修正でも、その状況は変わってないので、Ruby で SAML 実装するなら <code>libsaml</code> (<a href="https://github.com/digidentity/libsaml">digidentity/libsaml</a>) に移行した方が良さそうですね。</p>
<p>ちなみに、OpenID Connect ならそんなことないのかっていうと、当然あります。<code>ruby-jwt</code> と <code>json-jwt</code> を混在させてる <a href="https://github.com/18F/identity-openidconnect-sinatra/blob/master/Gemfile#L10">NIST の RP サンプル</a> とかね。</p>
<p><code>ruby-jwt</code> に JWK まわりの機能がないから <code>json-jwt</code> を JWK のためだけに使ってて、それ自体はまぁそんな悪い予感しないけど…</p>
<p><strong>なら全部 <code>json-jwt</code> 使えや。</strong></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Azure Portal 上の PowerShell から O365 SAML 設定]]></title>
<link href="https://oauth.jp/blog/2017/11/02/o365-saml-setting-via-in-browser-powershell/"/>
<updated>2017-11-02T15:22:00+09:00</updated>
<id>https://oauth.jp/blog/2017/11/02/o365-saml-setting-via-in-browser-powershell</id>
<content type="html"><![CDATA[<p>どうも、MS MVP (Enterprise Mobility) の Nov です。</p>
<p>普段もっぱら O365 の SAML 設定をいじって、自作 SAML IdP と Federation する毎日です。</p>
<p>いや、年に6回くらいかな。</p>
<p>で、毎回 PowerShell の使い方忘れるので、メモ代わりに過去にもこんな記事書いてきました。</p>
<ul>
<li><a href="https://oauth.jp/blog/2016/07/01/o365-saml-federation/">Office 365 と外部 SAML IdP との連携設定</a></li>