サイドプロジェクトのセキュリティ監査を実施しました — 見つかった問題点について
最近、自分のサイドプロジェクトをすべて監査しました。FastAPIのバックエンド、Telegramボット、ウェブアプリをすべてチェックしました。自分では慎重に作っているつもりでした。
しかし、それは間違いでした。
実際に本番環境にデプロイしてしまっていた、本物のバグを見つけました。これらは理論上の問題ではなく、スピードを優先しようとして犯してしまったミスです。
見つかった主な問題点と、その修正方法を以下にまとめます。
- 条件付き認証 シークレットが存在する場合にのみAPIキーをチェックするコードを書いていました。環境変数にシークレットを設定し忘れると、チェックが完全にスキップされてしまいます。その結果、APIが誰にでも公開された状態になっていました。
- 修正方法: 認証を条件付きにしてはいけません。シークレットが欠落している場合は、アプリがエラーをスローして停止するようにすべきです。
- Git履歴へのキーの漏洩
Gitの履歴の中に、古いAPIキーを見つけました。後で
.envファイルに移動させてはいましたが、Gitはコードのすべての過去バージョンを永遠に保持します。
- 修正方法: Gitに一度でもコミットしたキーは、すべて漏洩したものとして扱ってください。すぐに無効化(Revoke)しましょう。
git-filter-repoのようなツールを使用して、履歴をクリーンアップしてください。
- デバッグ用エンドポイントの残存 本番環境に、データベースの設定やシステム設定を表示するエンドポイントを残したままにしていました。これらは開発中には便利ですが、公開環境では非常に危険です。
- 修正方法: デプロイのチェックリストに「デバッグ用エンドポイントの削除」を追加してください。
- 冗長なエラーメッセージ ユーザーに対して、生のシステムエラーを返していました。これらのエラーは、ファイルパス、データベースの種類、ライブラリのバージョンなどを露呈させてしまいます。攻撃者はこのデータを利用して、システムを標的にすることができます。
- 修正方法: 詳細なエラーは内部的にログとして記録してください。クライアントには、汎用的な「Internal Server Error」メッセージのみを返します。
- innerHTMLによるXSS
フロントエンドでユーザーデータをレンダリングするために
innerHTMLを使用していました。これにより、攻撃者がサイトにスクリプトを注入できてしまいます。
- 修正方法: 常にデータをサニタイズするか、
innerHTMLの代わりにtextContentを使用してください。
- レート制限の欠如 制限なしで高コストなAIモデルを呼び出すエンドポイントがありました。一人のユーザーが数分間で膨大な請求額を発生させてしまう可能性があります。
- 修正方法: 認証は未認証のユーザーを阻止するためのものです。レート制限は、認証済みのユーザーによるシステムの悪用を阻止するためのものです。両方が必要です。
- 寛容すぎるCORS設定
ミドルウェアで
allow_origins=["*"]を使用していました。これにより、あらゆるウェブサイトからあなたのAPIに対してリクエストを送ることができてしまいます。
- 修正方法: 本番環境では、特定のドメインのみを許可するようにしてください。
- ファイル漏洩 一時ファイルを作成するコードを書いたものの、プロセスがクラッシュした際にそれらを削除し忘れてしまいました。これらのファイルはサーバー上に永遠に残り続けます。
- 修正方法:
try-finallyブロックを使用して、エラーが発生した場合でも確実にファイルが削除されるようにします。
セキュリティ上の問題が意図的に引き起こされることはめったにありません。それらは「後で直しておこう」という言葉の結果として生まれます。しかし、「後で」は決して来ません。
初日からワークフローにセキュリティを組み込みましょう。コミットする前、そしてデプロイする前にコードをチェックしてください。
出典: https://dev.to/justjinoit/i-audited-my-own-side-projects-for-security-issues-heres-what-i-found-1ahb