
こんにちは、エーピーコミュニケーションズ ACS事業部の福井です。
以前「なぜ OWASP なのか」「GHAS で AI アプリの脆弱性を検出してみた」という記事を書きました。
今回はその続編として、OWASP Top 10 の2025年改訂版を題材に、GitHub Advanced Security(GHAS)の各機能がどのカテゴリに対応できるのかを、実際にデモコードを書いてスキャンした結果とともに整理してみます。
「GHASを導入するとどんな脅威に対処できるの?」という問いへの、私なりの一次情報ベースの回答です。
近年、国内の企業をはじめとする多くの組織において、「GitHubの認証情報が漏洩し、ソースコードなどのリポジトリが不正にコピーされる」といったインシデントが散見されます。
報道では「GitHub」の名前が主語になっており、「GitHubを使っているから危ない」という印象を持つ方もいるかもしれません。しかし本質は認証情報の管理方法の問題であり、GitHub自体の脆弱性ではありません。
適切な設定とGHASの保護機能があれば、こうしたリスクを大幅に低減できます。その具体的な内容を、このマッピング記事の中で整理していきます。
- OWASP Top 10、2021→2025 で何が変わったか
- GHAS の3機能、おさらい
- OWASP Top 10 (2025) × GHAS マッピング
- 実測: デモリポで動かしてみた
- GHASが「届かない」領域を正直に書く
- AISVS記事との比較: 「従来の Web 脅威」と「AI特有の脅威」
- まとめ
- ツールを「入れた」で終わりにしないために
- お知らせ
- ACS 事業部のご紹介
OWASP Top 10、2021→2025 で何が変わったか
まず前提として、OWASP Top 10 の 2025 版は 2021 版から構成が変わっています。
大きな変更点は2つです。
新設カテゴリ: - A03: Software Supply Chain Failures(旧 A06「Vulnerable and Outdated Components」を拡張。依存ライブラリだけでなく、CI/CD・ビルドプロセス・配布インフラまで含むサプライチェーン全体へ) - A10: Mishandling of Exceptional Conditions(不適切なエラーハンドリング・例外処理を独立カテゴリに昇格)
統合・移動: - 旧 A10「SSRF」→ A01「Broken Access Control」に吸収(アクセス制御の欠如の一形態として再定義) - 順位の入れ替えあり(A01 Broken Access Control は引き続き1位)
この変化は「コードの脆弱性」から「設計・運用・プロセス全体のリスク」へという視点の広がりを反映していると私は感じています。
単体テストで潰せる問題から、アーキテクチャレベルで対処すべき問題へ。
GHAS の3機能、おさらい
記事中で繰り返し登場するので先に整理します。
| GHAS 機能 | 役割 | 動くタイミング |
|---|---|---|
| CodeQL(Code Scanning) | 静的解析(SAST)。コードの意味・データフローを追跡し脆弱なパターンを検知 | push / pull_request 時 |
| Dependabot(SCA) | 依存ライブラリの既知脆弱性を検知し、自動で修正 PR を作成 | 定期スキャン / push 時 |
| Secret Scanning / Push Protection | APIキー等の認証情報がコードに混入するのを検知・ブロック | push の瞬間(Push Protection)— コミット前にブロックするため「そもそもリポジトリに入れない」を実現 |
3機能ともパブリックリポジトリなら無料で使えます。
OWASP Top 10 (2025) × GHAS マッピング
結論から先に出します。今回のデモ検証をもとに作ったマッピングテーブルです。
| OWASP 2025 | GHAS 機能 | 検知できるか | 備考 |
|---|---|---|---|
| A01: Broken Access Control | CodeQL | ✅ | パストラバーサル(py/path-injection, High)、SSRF(py/full-ssrf, Critical)を検知 |
| A02: Security Misconfiguration | CodeQL | ✅ | debug=True(py/flask-debug, High)を検知。CORS全開は未検知(IaC系はサードパーティAction要) |
| A03: Supply Chain Failures | Dependabot | ✅ | Flask/requests/Werkzeug の旧バージョンに対して自動修正 PR 3件 |
| A04: Cryptographic Failures | CodeQL + Secret Scanning | ✅ | MD5パスワードハッシュ(py/weak-sensitive-data-hashing, High)、ハードコードAPIキーを検知 |
| A05: Injection | CodeQL | ✅ | SQLi(py/sql-injection, High)、XSS(py/reflective-xss, High × 7件)を検知 |
| A06: Insecure Design | ❌ | - | 設計レベルの欠陥はツールで検知不可。脅威モデリング・設計レビューで対処 |
| A07: Authentication Failures | Secret Scanning | △ | 認証情報のハードコードは検知・Push Protectionでコミット前にブロック可能。GitHubトークンなど主要なシークレット形式は自動認識される。ただし認証フローの設計ミス(例: セッション管理の欠陥)は検知不可 |
| A08: Software/Data Integrity Failures | Dependabot + Dependency Review | △ | ライブラリの信頼性確認は可能。コード署名・整合性チェックは別途必要 |
| A09: Security Logging & Alerting Failures | Security Overview | △ | アラートの集約・可視化はできるが、アプリのロギング実装は検知外 |
| A10: Exceptional Conditions | CodeQL | ✅ | スタックトレース漏洩(py/stack-trace-exposure, Medium × 5件)を検知 |
✅ = 自動検知できる / △ = 一部のみ / ❌ = 検知不可
実測: デモリポで動かしてみた
上記のマッピングは「ドキュメントに書いてあるから」ではなく、実際にデモコードを書いて push して確認したものです。
Python(Flask)の Web アプリを題材に、OWASP Top 10 の各カテゴリに対応する脆弱なコードを意図的に実装し、GHAS の各機能が動作することを確認しました。
デモに仕込んだ脆弱性
Python(Flask)で書いた Web アプリに、OWASP Top 10 の各カテゴリに対応する脆弱なコードを意図的に実装しました。
| エンドポイント | 脆弱性 | 対応 OWASP 2025 |
|---|---|---|
/fetch |
SSRF(URL バリデーションなし) | A01 |
/download |
パストラバーサル(ファイルパス未サニタイズ) | A01 |
/preview |
XSS(innerHTML に未サニタイズ出力) | A05 |
/user |
SQL インジェクション(文字列結合 SQL) | A05 |
/register |
MD5 パスワードハッシュ | A04 |
/fetch エラー処理 |
traceback.format_exc() をレスポンスに返す |
A10 |
main.py |
ハードコード API キー | A04(Secret Scanning) |
main.py |
debug=True / CORS 全開 |
A02 |
requirements.txt |
Flask 2.0.0、Werkzeug 2.0.0 等(旧バージョン) | A03 |
CodeQL のアラート結果
push 後に gh CLI でアラートを取得しました。
gh api repos/{owner}/{repo}/code-scanning/alerts \
--jq '[.[] | {number: .number, rule_id: .rule.id, severity: .rule.security_severity_level, message: .most_recent_instance.message.text}]'
実測で確認できたアラートは以下の通りです。(2026-05-01 スキャン結果)
| Rule ID | 深刻度 | 件数 | OWASP 2025 対応 |
|---|---|---|---|
py/full-ssrf |
Critical | 2 | A01: Broken Access Control(SSRF) |
py/flask-debug |
High | 1 | A02: Security Misconfiguration(debug=True) |
py/weak-sensitive-data-hashing |
High | 1 | A04: Cryptographic Failures(MD5 パスワードハッシュ) |
py/sql-injection |
High | 1 | A05: Injection(SQLi) |
py/reflective-xss |
High | 7 | A05: Injection(XSS) |
py/path-injection |
High | 1 | A01: Broken Access Control(パストラバーサル) |
py/stack-trace-exposure |
Medium | 5 | A10: Exceptional Conditions(スタックトレース漏洩) |
合計 18 件のアラートが自動検出されました。
「ツールに検知されるコードを自分で書く」という作業は、ある種のリバースエンジニアリングで、単純に面白かったです。
「どう書けば脆弱か」を理解することが、「どう書けば安全か」の理解に直結します。
Secret Scanning の検知
ハードコードした API キーは Push Protection でブロックされ、コミット後のスキャンでも検出されました。
一方、ダミー文字列(低エントロピー)はスルーされました(これは前回記事でも確認済みです)。
実際のインシデントで考える: 「そもそも Push させない」という発想
直近でも、国内の企業が「GitHubの認証情報漏洩によるリポジトリ不正コピー」を発表していました。
認証情報がどのルートで漏洩したかは公表情報の範囲では不明ですが、仮にアクセストークンや認証キーがコードに混入していた(または混入しうる状態だった)としたら、GHAS は以下のように作用します。
- Push Protection(push の瞬間): 認証情報がコードに書かれた状態で
git pushしようとすると、その場でブロックされリモートに届きません。リポジトリに「そもそも入らない」状態を作れます - Secret Scanning(push後・既存コード): すでにリポジトリ内に存在する認証情報を検知・アラートします。混入済みのシークレットを発見し、失効・再発行のアクションにつなげられます
「GitHubを使っているから情報が漏れる」という話ではありません。
適切に GHAS を設定した GitHub リポジトリは、認証情報の混入を自動でブロック・検知できる仕組みを持っています。
今回のようなインシデントは、その仕組みが未設定・未運用であることのほうが問題の根本です。GitHubという管理基盤を使うことと、セキュアに使えているかどうかは、別の話です。
ただし、今回のインシデントで「流出した可能性のある個人情報」として挙げられたカード保持者名(アルファベット)とカード番号下4桁については、Secret Scanning では検知できない可能性が高いことも正直に書いておきます。
- カード番号下4桁: ただの4桁の数字列であり、エントロピーも低く、既知のシークレットパターンに合致しない。誤検知を抑えながら検知する正規表現を書くことは現実的ではありません
- 保持者名(アルファベット):
JOHN DOEやYAMADA TAROのような文字列にはパターン的な特徴がなく、自動検知はほぼ不可能です
こうした個人情報(PII)はそもそもソースコードやリポジトリに入れないことが前提であり、それはアーキテクチャレベルの設計で担保するものです。テストデータのマスキング、本番データとの分離、PII を扱う箇所のコードレビュー強制(Branch Protection + Required Reviewers)——これらが GHAS の外側の防御層として必要になります。
Dependabot の検知
requirements.txt に旧バージョンを指定しておいたところ、既知 CVE に対する修正 PR が自動で届きました。
特に Werkzeug 2.0.0 は複数の CVE が登録されており、修正 PR のタイトルにそのまま CVE 番号が入っていました。
GHASが「届かない」領域を正直に書く
ここが、この記事で私が最も伝えたい部分です。
PII(個人情報)の混入
Secret Scanning が検知できるのは高エントロピーな認証情報(APIキー、トークン類)です。
個人名・電話番号・クレジットカード番号の下4桁のような低エントロピーの個人情報は、パターンの特徴が薄いため自動検知できません。
フルのカード番号(16桁)はLUHNアルゴリズムのパターンでカスタムルールを書けば検知の可能性がありますが、部分的な数字列やアルファベット氏名はほぼ不可能です。
こうした PII はそもそもリポジトリに入れない設計が根本対策です。具体的には:
- テストデータは必ずマスキング・匿名化する
- 本番データと開発環境を分離する
- PII を扱うコードの変更には Branch Protection + Required Reviewers を設定し、レビュー漏れを防ぐ
GHAS はあくまで「コードに混入した認証情報」を止める層です。PII の取り扱いルールを設計レベルで決めることは、人間が担う仕事です。
A06: Insecure Design(設計の欠陥)
GHASはコードを静的に解析しますが、「なぜそう設計したか」は見ません。
たとえば「認証をバイパスできる設計になっている」「権限の分離ができていない」といった設計レベルの欠陥は、コードに脆弱性のパターンが現れなければ検知できません。
A06 への対処は、脅威モデリング(Threat Modeling)や設計レビューで人間が担う領域です。
A09: Security Logging & Alerting Failures
GHAS の Security Overview はアラートを集約して可視化してくれますが、それは「GHASが見つけた問題の可視化」であって、「アプリ自体がログを適切に出しているか」は別の話です。
logger.info() が書かれているかどうか、攻撃の痕跡がログに残る設計かどうか——これらは GHAS では見えません。
SIEM やアプリケーション監視(Azure Monitor、Datadog 等)との組み合わせが必要です。
A02: Security Misconfiguration の一部
debug=True や CORS の全開放は CodeQL で検知できないケースがあります。
IaC(Terraform、Bicep)のセキュリティミスは、Checkov や Trivy を GitHub Actions のサードパーティ Action として組み込むことで対処できます。
AISVS記事との比較: 「従来の Web 脅威」と「AI特有の脅威」
私はこれまでに OWASP AISVS(AI Security Verification Standard)× GHAS の記事も書きました。
整理すると、こんな関係になっています。
| 観点 | 本記事(OWASP Top 10) | AISVS記事 |
|---|---|---|
| 対象 | 従来のWebアプリ全般 | LLM/AI連携アプリ |
| GHAS の強み | SQLi、XSS、SSRF など「コードパターン」系は高精度で検知 | Prompt Injection 混入箇所の特定、LLM依存ライブラリの更新 |
| GHASの限界 | 設計欠陥・ロギング実装 | AI固有の脅威(データポイズニング、モデル漏洩)は手動検証が必要 |
どちらの記事も「GHASは何でもできる銀の弾丸ではない」という結論は同じです。
ただ、その「できること」の範囲を実測で把握しておくことには価値があると思っています。
まとめ
OWASP Top 10 (2025) の全10カテゴリに対して GHAS を使って実測した結果、次のことが分かりました。
- ✅ 検知できた: A01, A02, A03, A04, A05, A10(計6カテゴリ)
- △ 一部のみ: A07, A08, A09(計3カテゴリ)
- ❌ 検知不可: A06(設計レベルの欠陥)
特に意外だったのが A02(Security Misconfiguration) で、debug=True は py/flask-debug として High 深刻度で検知されました。
また A04(Cryptographic Failures) も、MD5 によるパスワードハッシュを py/weak-sensitive-data-hashing として High で検知——単なる「弱い暗号」ではなく「パスワードに使っている」という文脈まで判断していました。
CodeQL の解析精度は、触ってみて初めて実感できるものだと思います。
「GHAS を入れれば安全」でも「GHAS じゃ全部はカバーできないから入れても意味ない」でもない。
「GHASが守れる範囲を正確に知って、残りを補完する設計をする」——それが実態だと思います。
今回の記事を書いていたタイミングで起きたリポジトリ不正アクセスのインシデントも、「GitHubが危ない」ではなく「保護の仕組みを適切に動かせていたか」という問いに帰着します。A07(Authentication Failures)への対処として、Secret Scanning と Push Protection は明確な答えを持っています。使えるものを使わない理由はありません。
同じ構成を自分のリポジトリで試してみると、より理解が深まるはずです。
脆弱なコードを意図的に書いて push する——この「リバースエンジニアリング的な検証」は、GHASの感度を体感するのに最も効果的な方法だと思います。
ツールを「入れた」で終わりにしないために
GHAS の導入を検討・決定する立場の方に向けて、少し視点を変えて書いておきます。
「GHAS を入れればセキュリティ対策が完了する」という期待を持つマネージャー層の方は多いと思います。その期待は理解できますし、導入すること自体は間違いなく価値があります。ただ、この記事で実測してきたとおり、GHAS が守れる範囲と守れない範囲は明確に存在します。
Gemini との対話でこんな比喩が生まれました。
「GHASは、家が燃えない(脆弱性)ための火災報知器です。しかし、家が住みやすいか(設計)、将来増築できるか(拡張性)は、最新の重機(Copilot)を使いこなす大工(エンジニア)の腕にかかっています。ツールを入れるだけでなく、これらを使いこなす『エンジニアのスキルアップ』への投資がセットで必要です。」
少し補足すると、GHAS の Push Protection は「火が出る前に引火物をドアで止める」機能で、単なる報知器以上のものです。ただ、「家の設計が根本的に火事になりやすい」(A06: Insecure Design)や「誰かが個人情報をメモに書いて壁に貼る」(PII in code)は、どれだけ優れた報知器でも止められません。
つまり、ツールとエンジニアのスキルと運用プロセスは三位一体です。導入後に「アラートが出た。どう対応する?」「この検知は誤検知か?」「カバーできない領域はどう補う?」を判断できるエンジニアがいなければ、GHAS は鳴り続ける報知器になってしまいます。
「何を防いで、何を防がないか」を正しく理解した上で導入する——それが、ツール投資を活かすかどうかの分岐点です。
お知らせ
ACS 事業部のご紹介
私の所属する ACS 事業部では、開発者ポータル Backstage、Azure AI Service などを活用し、Platform Engineering + AI の推進・内製化を支援しています。
www.ap-com.co.jp www.ap-com.co.jp www.ap-com.co.jp
また、GitHub パートナーとして GHAS の導入支援を行っています。
「導入して完了」ではなく、何を検知でき・何を検知できないかを実測ベースで把握した上で、運用プロセスや補完策まで含めてご支援します。
GitHub Copilot などのトレーニングも行っておりますので、ご興味を持っていただけましたらぜひお声がけいただけますと幸いです。
一緒に働いていただける仲間も募集中です! ご興味持っていただけましたらぜひお声がけください。 ※求人名の冒頭に【ACSD】と入っている求人が当事業部の求人です。