SaaS運用に向けたセキュリティ強化として、フェーズ1(必須項目)の完了およびフェーズ2の主要項目を実装した。
1-1. HTTPS強制(フェーズ1)
iPadのChromeブラウザでログインフォーム送信時に「送信されている情報は保護されません」の警告が表示されていた。
XサーバのSSL化は設定済みだったが、LaravelのURL生成がHTTPになっていた。 ① `app/Providers/AppServiceProvider.php` に追記 “`php use Illuminate\Support\Facades\URL; public function boot(): void { if (!app()->environment(‘local’)) { URL::forceScheme(‘https’); } } ② `bootstrap/app.php` にTrustProxies設定を追加 “`php $middleware->trustProxies(at: ‘*’); “`
結果
iPadでの警告が解消された。
ローカル環境(HTTP)では適用しない条件分岐を追加し、ローカルの動作も正常化。
1-2. セッションのセキュア設定(フェーズ1)
本番・ローカル各.envに以下を追記:
項目 本番 ローカル SESSION_SECURE_COOKIE true false SESSION_ENCRYPT true true SESSION_SAME_SITE strict lax
結果
セッションCookieのHTTPS限定送信を設定。
セッションデータの暗号化を有効化。
既存ログインユーザーのセッションが一度無効化されたが、再ログインで正常動作を確認。
1-3. ログイン失敗のロック機構(フェーズ1)
app/Http/Requests/Auth/LoginRequest.php を確認した結果、Laravel標準のRateLimiterによる以下の機能がすでに実装済みであることを確認した。
5回失敗でアカウント一時ロック
メール+IPアドレスの組み合わせでカウント
時間経過で自動解除
Lockoutイベントの発火
結果
1-4. セキュリティヘッダーの実装(フェーズ2)
app/Http/Middleware/SecurityHeadersMiddleware.phpを新規作成し、bootstrap/app.php` に登録。
設定したヘッダー:
ヘッダー 設定値 効果 Strict-Transport-Security max-age=31536000 HTTPS強制をブラウザに記憶 X-Frame-Options DENY クリックジャッキング防止 X-Content-Type-Options nosniff MIMEタイプ誤判定防止 Referrer-Policy strict-origin-when-cross-origin URL漏洩防止 Content-Security-Policy self + unsafe-inline XSS対策
注意事項
ローカル環境(APP_ENV=local)では全ヘッダーをスキップする条件を追加。
TipTapエディタ・Axios使用のため、CSPは段階的に厳格化する方針とした。
1-4. セキュリティヘッダーの実装(フェーズ2)
app/Http/Middleware/SecurityHeadersMiddleware.hpを新規作成し、bootstrap/app.php` に登録。
設定したヘッダー:
ヘッダー 設定値 効果 Strict-Transport-Security max-age=31536000 HTTPS強制をブラウザに記憶 X-Frame-Options DENY クリックジャッキング防止 X-Content-Type-Options nosniff MIMEタイプ誤判定防止 Referrer-Policy strict-origin-when-cross-origin URL漏洩防止 Content-Security-Policy self + unsafe-inline XSS対策
注意事項
ローカル環境(APP_ENV=local)では全ヘッダーをスキップする条件を追加。
TipTapエディタ・Axios使用のため、CSPは段階的に厳格化する方針とした。
1-5. 不審ログイン通知メール(フェーズ2)
新しいIPアドレスからのログインを検知し、登録メールアドレスへ通知メールを自動送信する機能を実装。新規作成ファイル app/Mail/SuspiciousLoginMail.php resources/views/emails/suspicious_login.blade.php resources/views/emails/suspicious_login_text.blade.php(HTML/テキスト両形式対応)
修正ファイル app/Http/Controllers/Auth/AuthenticatedSessionController.php
検知ロジック:
$isNewIp = !LoginLog::where(‘user_id’, $user->id)
->where(‘ip_address’, $request->ip())
->where(‘id’, ‘!=’, $log->id)
->exists();
if ($isNewIp && $user->email) {
Mail::to($user->email)->send(
new SuspiciousLoginMail($user, $request->ip(), now()->format(‘Y年m月d日 H:i’))
);
}
メール設定
環境 設定 本番 Xサーバ SMTPサーバ(sv13426.xserver.jp:587) ローカル MAIL_MAILER=log(ログファイルに出力)
動作確認結果
Gmail:受信トレイに正常届を確認 ✅
MSN(Outlook):迷惑メールフォルダに届くことを確認 ✅
残課題
MSN/Outlookの迷惑メール判定を解消するため、DNSへのSPFレコード追加を推奨。 レコード種別:TXT 値:v=spf1 include:xserver.jp ~all
2.フェーズ別進捗
フェーズ1(必須・リリース前)
項目 状態 パスワードのハッシュ化(bcrypt) ✅ 完了(実装済み確認) HTTPS強制 ✅ 完了 セッションのセキュア設定 ✅ 完了 ログイン失敗のロック機構 ✅ 完了(実装済み確認)
フェーズ2(リリース後早めに)
項目 状態 セキュリティヘッダー(HSTS等) ✅ 完了 不審ログイン通知メール ✅ 完了 SPF・DKIMの設定 ⬜ 未対応(推奨) パスワードリセットフローの強化 ⬜ 未対応(次回