Slide 1

Slide 1 text

クレジットマスターとの戦い PHPカンファレンス 2023/10/08 仲見川勝人@NakMeKtt

Slide 2

Slide 2 text

- 仲見川 勝人(@NakMeKtt) - 職業 - Software Engineer - Mobile App, Front End, Server Side - 所属 - 株式会社ホワイトプラス - 宅配クリーニング「リネット」の開発 - Tech lead - アプリ開発G Engineering Manager 2 自己紹介

Slide 3

Slide 3 text

- 後ほどforteeの本セッションproposalページにアップします - https://fortee.jp/phpcon-2023/proposal/da4ef7a1-3aa9-47a9-bd87-c1c03ac68b65 3 本日のスライド

Slide 4

Slide 4 text

- クレジットマスターとは? - クレジットマスター対策として私たちが行ったことについてLaravelの throttleを中心にお話 - throttleとは別に行った対策について軽くご紹介 4 本日の内容

Slide 5

Slide 5 text

5 クレジットマスターとは?

Slide 6

Slide 6 text

クレジットマスターとは、クレジットカード番号の規則性を悪用し、他人の カード番号を割り出す犯罪行為を指す言葉です。 聞き慣れない手口ですがその歴史は古く、アメリカでは1989年から、日本では 1999年から被害が確認されています。この手口により、カードそのものは手元 にありながらも知らないうちにクレジットカード番号が盗まれるといった被害 が相次いでいるのです。 6 クレジットマスターとは? 三井住友カードWebサイトより https://www.smbc-card.com/mem/hitotoki/solution/credit_master.jsp

Slide 7

Slide 7 text

クレジットカード番号の規則性(例) - 先頭数桁がIssuer(発行者)を示す - Visaは4始まり、MasterCardは51、55始まりなど - 16桁の数字である(Issuerによって15桁や14桁の場合も) - 0000-0000-000-000 - 最後の1桁は特定のアルゴリズムを用いたチェックサム 7 クレジットマスターとは?

Slide 8

Slide 8 text

有効期限やCVCなどもある為、カード番号が一致しても簡単に使 用することは出来ません、 これらの規則性に基づいた番号を使えるか確認する方法は? 8 クレジットマスターとは?

Slide 9

Slide 9 text

有効期限やCVCなどもある為、カード番号が一致しても簡単に使 用することは出来ません、 これらの規則性に基づいた番号を使えるか確認する方法は? 9 クレジットマスターとは? Issuerに決済出来るか問い合わせる

Slide 10

Slide 10 text

どのようにして? - 当然攻撃者がIssuerと契約を結んで行うことはない 10 クレジットマスターとは?

Slide 11

Slide 11 text

どのようにして? - 当然攻撃者がIssuerと契約を結んで行うことはない 11 クレジットマスターとは? ECショップなどでカード登録出来るか繰り返し試行する ↑これがクレジットマスター攻撃

Slide 12

Slide 12 text

12 弊社の事例

Slide 13

Slide 13 text

- 決済代行会社より同一顧客にて連続した多数の有効性確認があり不正ア タックの可能性があると連絡が入る - 調べたところクレジットカードの有効性を検証しているAPIでクレジットマ スターの対応が行われていないことが判明 - この際は、一次対応としてすぐにユーザーを特定しCSと連携しながら 通常の利用者ではないと判断し該当アカウントを停止 13 ある日......

Slide 14

Slide 14 text

- このAPIはユーザー情報が無いケース(新規ユーザー)の場合 もあることから処理時点では識別する情報を持っていない - なので、顧客ID単位などで制限をかけるだけではダメ 14

Slide 15

Slide 15 text

- Laravelのルーティングによるレート制限(以降throttle)を 行うのがよさそう - 認証している場合は顧客ID単位で制限可能 - 未認証の場合でもIPベースで同一のアクセスを制限可能 15

Slide 16

Slide 16 text

ルーティングにthrottleを導入すること自体はとても簡単で、最 小限だと以下のように記述出来ます。 これで、/example/validateは1分に10回の制限となります。 16

Slide 17

Slide 17 text

制限を超過すると429が返されます。 また、Response Headerに以下が載っているためどのような制限がかかってい るか知ることが出来ます。 - Retry-After(制限が解除される時間) - X-Ratelimit-Limit(レートリミットの閾値) - X-Ratelimit-Remaining(閾値までのカウントダウン) 17

Slide 18

Slide 18 text

- 実際に設定した物に近い設定内容 18

Slide 19

Slide 19 text

'throttle:10|20,30,throttle_id_1', 19 未認証での制限回数 (IPアドレス制限) 認証済での制限回数 (UserID制限) 範囲(分) throttleの単位(Key) ※弊社の環境(K8s[Ingress]→Nginx→php-fpm)ではユーザーのIPアドレスで制限がかかってることを確認

Slide 20

Slide 20 text

'throttle:10|20,30,throttle_id_1', 'throttle:5|10,1,throttle_id_2' 20 上記の定義は 未認証の場合30分に10回、認証済の場合は30分に20回の制限 または 未認証の場合1分に5回、認証済の場合は1分に10回の制限 となります。

Slide 21

Slide 21 text

ここまではLaravel7.xまでの書き方 (※10.xでも動きます) 8.x以降新しい書き方があります 21

Slide 22

Slide 22 text

8.x以降は(Routeは) こう書けます!すっきりしましたね! 22

Slide 23

Slide 23 text

はて? 何分に何回とか設定してなくない? 23

Slide 24

Slide 24 text

8.x以降は(Routeは) こう書けます!すっきりしましたね! 24

Slide 25

Slide 25 text

実体はRouteServiceProviderクラスのbootメソッドに置きま す。先ほどと同じ内容を設定した物がこちら 25

Slide 26

Slide 26 text

コード量は増えていますが、ロジックとして書けるため個人的に はこちらの書き方の方が好みです。 26

Slide 27

Slide 27 text

注意点というか個人的にハマったポイントとして、 Limit::perMinute()->by($key)の$key部分が他の制限と重複し ないようにしなければなりません。 keyの重複がある場合、時間制限は長い方、回数は少ない方が採 用されるなど意図しない動作となりました。 27 Limit::perMinute(5)   ->by('throttle_id_1_' . $request->ip()),

Slide 28

Slide 28 text

28 https://laravel.com/docs/10.x/routing#multiple-rate-limits ドキュメントにkeyについては説明があまりなく、どのように チェックしているかロジックと実際の振る舞いを検証したとこ ろ。 キャッシュのkeyとしてそのまま使用されているようでした。 そのため、同一keyに複数のRateLimitの時間や回数がアクセス を行い意図しない動作となっている事がわかりました。 ※正しくソースを読み切れているか自信が無いので詳しい方いたら是非教えてください

Slide 29

Slide 29 text

29 https://laravel.com/docs/10.x/routing#throttling-with-redis defaultはCacheファサード、Redisを明示的に指定も可能

Slide 30

Slide 30 text

throttleで試行回数の制限はできた 30

Slide 31

Slide 31 text

throttleしたからといって クレジットマスターに対して安全ではない 充分に有効だとは考えていますが、 あくまで試行回数を稼げないようにやりづらくしただけ 31

Slide 32

Slide 32 text

throttleの制限にかかった (攻撃を受けている) ことを検知したいですよね? 32

Slide 33

Slide 33 text

とは言え、発生都度Slack等に通知すると - 100回行われたら100回Slack通知が来 るとしんどい - なんならSlackのAPI制限で他の通知も 止まる巻き込み事故が起きかねない 33

Slide 34

Slide 34 text

なので特定のログが出力されたら 1時間1回だけ通知して欲しい 34

Slide 35

Slide 35 text

クラウドインフラとしてGoogle Cloudを利用しているためCloud Loggingの「ログベースのアラート」を使って通知することに。 一定期間内で閾値を越えたら発報するという定義が作れる。 この仕組みを使いSlack通知を構築。 「ログベースのアラート」ドキュメント https://cloud.google.com/logging/docs/alerting/log-based-alerts?hl=ja 35

Slide 36

Slide 36 text

まずはthrottleで制限がかかった際にログを 出力するようにします 36

Slide 37

Slide 37 text

制限がかかった場合 ThrottleRequestsExceptionが投げられる ためこれをハンドリングします 37

Slide 38

Slide 38 text

app/Exception/Handler.phpに記述を追加。 report()の方が目的には沿っているのですが、request内容がほ しかったのでrender()をオーバライドしています。 38

Slide 39

Slide 39 text

ログベースのアラートは ドキュメントを参考に構築 39

Slide 40

Slide 40 text

運用開始! 40

Slide 41

Slide 41 text

後日throttleの制限範囲で細々と続けられて いるケースを検知……ウセヤロ 41

Slide 42

Slide 42 text

検知する仕組みを入れておいて良かった 42

Slide 43

Slide 43 text

調査したところ、ゲストでは無く会員登録のあるユーザーで行わ れていた。 (新規会員登録の場合、全ての情報を入力しないとカード情報入 力にたどり着かないので効率が悪いのだと思われる) 43

Slide 44

Slide 44 text

- 打ち手 - 会員登録後に行われている事から会員IDが特定可能 - 一定期間内に閾値を超えたチャレンジがあった場合に該当 ユーザーからのクレジットカード登録を永久凍結 - 一般ユーザーが誤って凍結されてしまった場合はCS問合 せにて解除する 44

Slide 45

Slide 45 text

通常の機能開発と同様に開発 ※こちらの仕組みは最近の施策なので まだ成果は出ていません 45

Slide 46

Slide 46 text

まとめ 46

Slide 47

Slide 47 text

クレジットマスターなどの攻撃に対して - throttleは一定の効果があった - 流量制限の為の機能なので充分とは言えない - Laravelの標準機能なので導入が簡単なため取り急ぎの対 策としてはよかった - 状況に応じて次の手を打っていく事が大事 - そのために検知の仕組みも重要 47

Slide 48

Slide 48 text

俺たちの戦いはこれからだ! 48

Slide 49

Slide 49 text

ご静聴ありがとうございました 49

Slide 50

Slide 50 text

Appendix 50

Slide 51

Slide 51 text

他のクレジットマスター対策 51

Slide 52

Slide 52 text

- クレジットカード登録時にSMSやメールでの多要素認証を必 須として攻撃により手間がかかるようにする - reCAPTCHA v3などのスパム抑止サービスを導入する 52

Slide 53

Slide 53 text

- クレジットカード登録時にSMSやメールでの多要素認証を必 須として攻撃により手間がかかるようにする - reCAPTCHA v3などのスパム抑止サービスを導入する これらは通常利用してくれるユーザーにとっては手間が増えるため現状の対策 で問題が出た場合の対策として今後の状況により検討。 53

Slide 54

Slide 54 text

- WAF(Web Application Firewall) 54

Slide 55

Slide 55 text

- WAF(Web Application Firewall) クレジットカード登録のリクエスト自体は正規のリクエストとなるため、WAF で防げるのはDDoS攻撃と判断された場合と想定。その場合、今回行った throttleの対応で十分なためクレジットマスター対策としては除外。 55