SASTスキャン
依存関係監査はインポートしたコードをカバーしますが、SASTはあなた自身が書いたコードをカバーします。パターンマッチング(およびテイントモードではデータフローの追跡)により、典型的な脆弱性(コマンドインジェクション、SQLインジェクション、パストラバーサル、安全でないデシリアライゼーション、信頼できない入力に対するeval/動的実行、ハードコードされた暗号、認可チェックの欠落)を検出します。誤検知率が高いのは本質的な性質です — 対処法は到達可能性によるトリアージであり、まとめて無視することではありません。
実行すべきタイミング
- リリース前(差分またはツリー全体に対して)
- 信頼できない入力を扱うコード(新しいツール、エンドポイント、パーサー、シェルアウトなど)を追加したとき
- CI上でPRに対して(差分スコープで高速、新しい問題のみを検出)
実行方法
# semgrep — セキュリティルールセット。`auto`は検出された言語に基づいてルールを選択します。
semgrep scan --config auto --error .
# より焦点を絞った高シグナルルールセット(autoよりノイズが少ない):
semgrep scan --config p/security-audit --config p/secrets --config p/command-injection .
# 差分のみ(CI上のPR — 高速で新しい発見のみ):
semgrep scan --config auto --baseline-commit origin/main .
より深いデータフロー分析(信頼できない入力が実際にシンクに到達するか?)には、CodeQLの方が強力ですが、より重いです:
codeql database create db --language=javascript # または rust, python, …
codeql database analyze db --format=sarif-latest --output=results.sarif \
codeql/javascript-queries:codeql-suites/javascript-security-extended.qls
トリアージ — 却下せずに追跡する
各検出結果について、ソース → シンクのパスを追跡します:
- 入力は攻撃者が制御可能か? ハードコードされた定数に対する
child_process.execは問題ありませんが、リクエストパラメータに対するものはコマンドインジェクションのバグです。semgrepはシンクをフラグしますが、あなたがソースを確認します。 - その間にサニタイザーはあるか? 値がシンクに到達する前に検証/エスケープされている場合(zodスキーマ、許可リスト、パラメータ化クエリ)は、誤検知です — 理由を一行添えて
# nosemgrep: <rule-id>とマークしてください(単なる無視は不可)。 - 本当のバグ? 警告を抑制するのではなく、ソース(入力の検証/エスケープ)またはシンク(パラメータ化、安全なAPIの使用)で修正します。
ルールを無効にして警告を消すことは絶対にしないでください — ノイズの中の本当のヒットを抑圧してしまいます。行単位で理由を付けて抑制してください。
実際に修正すべきもの(優先度順)
- インジェクション(コマンド/SQL/テンプレート) — ユーザーが到達可能なパス上では、最も深刻で悪用される脆弱性です。
- パストラバーサル — 検証されていないパスがファイル読み取り/書き込みに到達する場合(ファイルを書き込むエージェントはまさにこのリスクがあります;スコープチェックでゲートしてください)。
- 動的文字列の安全でないexec/eval。
- セキュリティコンテキストにおけるハードコードされた暗号/脆弱な乱数。
限界
SASTは単一リポジトリのソースを静的に分析します — ランタイム設定、環境変数駆動のコードパス、サービス境界をまたいで初めて現れる脆弱性は見えません。これは実際の脅威モデルや[[dependency-audit]]を補完するものであって、決して置き換えるものではありません。エージェント/ツールランタイムにおいて、最も強力な制御は多くの場合、アーキテクチャ上のもの(すべてのアクションをゲートするカーネル)であり、行単位のチェックではありません — SASTはその境界周辺のコードを検証します。[[security-preflight]]に組み込んでください。