サガワドラゴン大量フォーム投稿対策:cakephpでGoogle reCaptchaを使う。
2019/07/07
2019/12/23
タグ: cakephp, GSuite, reCaptcha, サガワドラゴン, フォーム, 大量投稿, 対策
お客様でサガワドランゴン名乗るフォーム登録で多数の迷惑メールを短時間で700通弱送るトラブルがあった。この問題のおかげでGoogle G Suite
のアカウントが通数制限で送受信できなくなる問題が発生しフォームが使えなくなった。G SuiteやGmailは一日の通数制限があるのでスパマーが大量に送るとアカウントが一時的に送受信が凍結してしまう。但し一日立つと復活します。Gのメールフィルターはあまりよくない。それは、一度受信した上でフィルターをかけるため通数制限の問題に対して解決にならないのだ。
結局cakephpのバージョンが古くて2系であったためCaptchaプラグインが使えなくなっているものや、現代のSpam事情を考慮すると実装上の課題があるものが多いため、改めてGoogleのCaptchaを使うことにした。おそらく下手なcakephpプラグインを使うよりも実装は簡単で効果は高い。本音はWORDPRESSでフォームを作っていれば簡単にGoogle Captcha使えるのにね!と思います。まあ、フレームワークで作る場合は人それぞれの個性が出るので作り方のトレースをある程度行った上で導入が必要になる。
今回の環境はcakephpでしたがおそらくcakephpのどのバージョンでも使えると思う。まあ、参考にしてみてください。GoogleのreCaptchaを使うには予めユーザ登録とドメイン登録が必要。サイトキーやシークレットキーもここで取得します。やり方は過去記事のここを参考にしてみてください.Google reCaptcha
ヘッダに設置
1 2 3 4 5 |
<head> 途中省略 <script src="https://www.google.com/recaptcha/api.js" async defer></script> 途中省略 </head> |
フォームに設置
1 |
<div style="margin:20px;" class="g-recaptcha" data-sitekey="取得したサイトキー"></div> |
コントローラに設置
次のコードを適宜書き換えてフォームを表示する部分の処理において内容チェック処理を行う部分もしくはSubmitする直前に挿入してみてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//reCaptcha process start if (isset($this->request->data['g-recaptcha-response'])) { $captcha = $this->request->data['g-recaptcha-response']; } if (!$captcha) { $this->Session->setFlash(__('必要なチェックがされていません。'), 'flash_error'); $this->redirect(array('controller' => 'regist', 'action' => 'index')); //問題があれば適当なページへ飛ばす。 } $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=シークレットキー" . $captcha . "&remoteip=" . $_SERVER['REMOTE_ADDR']); if ($response . success == false) { $this->Session->setFlash(__('あなたはスパマーですね!消えください!'), 'flash_error'); $this->redirect(array('controller' => 'regist', 'action' => 'index')); //問題があれば適当なページへ飛ばす。 } //reCaptcha process end |
特定のヘッダ項目で比較チェック
※メールのヘッダ項目やBODYの内容で特徴あるパターンでトラップさせる。サンクスメールの送信前や確認表示の前に入っているバッファで 文字列比較すると良いと思います。文字列はUTF-8でエンコーディングという前提です。項目は攻撃を仕掛けられたサイト毎に異なるため、事前に届いている攻撃メールを調べて共通項を調べてみてください。意外とどのメールにも共通した文字列が潜んでいるものです。そこを文字列含む関数比較(preg_match)を使って検出すると良いです。後は問題あるものは適当なページへ飛ばす事です。
1 2 3 4 |
//佐川ドラゴンチェック if( preg_match("/サガワドラゴン/u",$mailbuff['Subject']) ) { $this->redirect(array('controller' => 'regist', 'action' => 'index')); //問題があれば適当なページへ飛ばす。 } |