In this article
機械学習でGoのパストラバーサル脆弱性を検出できる?Snyk Codeならできます!
セキュリティの難問に挑戦するのは楽しいですよね。私は大好きです。では、機械学習アルゴリズムはパストラバーサル脆弱性を検出できるでしょうか?実際に試してみましょう!
ここ数週間、Zeyad AbuLabanはセキュアコーディングやセキュリティ脆弱性に関する記事をいくつか公開してきました。「Secure Code Quest」シリーズでは、さまざまな種類の脆弱性を、さまざまなプログラミング言語で取り上げています。
ZeyadがSecure Code Quest #5を公開したとき、画像内のコードをすぐに見て安全でないパターンを確認するのではなく、ふと別の考えが頭に浮かびました。「このGoコードをIDEに貼り付けて、Snyk VS Code拡張機能でスキャンしたら、検出できるだろうか?」

このGolangコードは脆弱?それとも安全?
まずは、このGoプログラムのコードを見やすく整形して、適切なコードレビューの手順で詳しく調べてみましょう。
このGolangプログラムはファイルを扱うため、HTTPコントローラーとして機能するdownloadHandler()関数が含まれています。クエリパラメーターからfilenameを受け取り、パスを整理してセキュリティ上のサニタイズを行います。次に、ファイル名をベースディレクトリに連結して、ディスク上のストレージフォルダーへのファイルパスを作成します(baseDir := “public/files/”)。
package main
import (
// ... imports ...
)
func main() {
// ... main function code ...
}
func downloadHandler(w http.ResponseWriter, r *http.Request) {
filename := r.URL.Query().Get("filename")
if filename == "" {
http.Error(w, "Missing filename parameter", http.StatusBadRequest)
return
}
// Preventing Path Traversal
sanitizedFilename := strings.Replace(filename, "../", "", -1)
cleanedFilename := filepath.Clean(sanitizedFilename)
baseDir := "public/files/"
fullPath := filepath.Join(baseDir, cleanedFilename)
// ... code to handle file serving ...
}このGoプログラムでは、どのようにセキュリティ対策を実装しているのでしょうか。文字列置換ロジックを使い、指定されたファイル名に含まれるすべての../を空文字列に置き換えています。つまり、ユーザー入力のファイル名から完全に削除しています。
次のHTTPリクエストを考えてみましょう。
curl "http://localhost:8080/download?filename=../../app/flag.txtこのHTTPリクエストでは、filename変数からすべての../パスがサニタイズされ、入力されたfilenameはapp/flag.txtだけになります。これをbaseDirのパスと結合すると、完全なパスはpublic/files/app/flag.txtになります。
では、どうすれば回避できるでしょうか?
CTF形式のチャレンジで/app/flag.txtのフラグを取得し、課題をクリアして賞品を手に入れるには、どのようなHTTPリクエストを作成すればよいでしょうか?
ペイロードを明かす前に、このGolangプログラムをIDEに貼り付けるとどうなるかをお見せします。
機械学習でコードを保護
まず、このロジックをGinを使用するWebアプリケーションの新しいルートとして追加しました。そのため、ここではルート宣言が少し異なっています。次に、fullPath変数の後にコードを追加し、ファイルの妥当性を確認してから、ファイルをクライアントに返す処理を実装しています。

ここで、IDEにSnyk拡張機能がインストールされているとします。
ファイルを保存するだけで、数秒後には(本当に数秒です)、ソースコード(依存関係、Dockerfile、Terraformなどを含む)を分析するコードセキュリティ監査の結果が得られます。
セキュリティレポートを提供するだけでなく、Snyk IDE拡張機能は脆弱なコード行をリンターのように強調表示して注意を促し、さらに、問題の詳細を調べるためのツールも提供します。
セキュリティ脆弱性の名称と詳細。
source-to-sinkのデータフローを表示し、サニタイズされていないデータが機密性の高いAPIに流れ込む経路を確認できます。
この脆弱性について初めて聞いた方は、パストラバーサル脆弱性について詳しく見る。
脆弱性の修正方法がわからない場合に適用できる、修正コードの例を提示します。
場合によっては、Snyk Agent Fixを使って、ロジックを維持したままコードをリファクタリングし、セキュリティ問題を自動的に解決することもできます。

ここで機械学習はどんな役割を果たすのでしょうか?実は、すべてに関わっています。
SnykのSAST(静的アプリケーションセキュリティテスト)はソースコードを分析し、独自の機械学習エンジンで処理します。このセキュリティエンジンは、大規模なコードベースでトレーニングされた高性能なシンボリックAIアルゴリズムを基盤としています。セキュリティ専門家が安全でないコードパターンを分類・ラベル付けするファインチューニングのプロセスを通じて、知見を蓄積しています。
この高度な技術プロセスはIDE上で数秒のうちに実行され、コード内のセキュリティ脆弱性を比類ない速さと精度で検出します。このエンジンは「安全なコードとはどのようなものか」も学習しており、オープンソースのコードリポジトリにある実際のセキュリティ修正を分析しています。そのため、修正に自信がない場合でも、適用可能な修正コードの差分例を提案できます。
生成系機械学習アルゴリズムとシンボリックAIの組み合わせにより、Snykはコードの脆弱性を検出する優れた開発者体験を実現しています。SnykがAIの安全な導入をどのように実現しているかをご覧ください。
Golangのパストラバーサルを悪用する
さて、セキュリティチャレンジに戻りましょう。実演したGolangプログラムのパストラバーサルを悪用して、フラグを取得するにはどうすればよいでしょうか?
念のため、Golangプログラムにあるパストラバーサル防止ロジックをもう一度見てみましょう。
// Preventing Path Traversal
sanitizedFilename := strings.Replace(filename, "../", "", -1)
cleanedFilename := filepath.Clean(sanitizedFilename)文字列置換ロジックは、../というテキストに完全一致する文字列を置換します。つまり、ファイル名に「../」のような典型的なパストラバーサル文字列が含まれていると、置換されます。
では、完全一致によるチェックを回避するようにパストラバーサル文字列を変更したらどうなるでしょうか。filenameの入力を変更した次のHTTPペイロードを見てみましょう。
curl "http://localhost:8080/download?filename=....//....//app/flag.txtクエリ文字列のfilenameの値が....//....//app/flag.txt,の場合、「../」に一致する部分が(ファイル名の文字列内から)見つかり、削除されます。その結果、実際のファイル名には残った「..」と単独の「/」が残ります。これにより、sanitizedFilenameの値は../../app/flag.txtとなり、ベースディレクトリ(public/files/)の外へ移動して、flag.txtファイルをクライアントに送信します。
Fetch the Flag 2026に参加しよう!
2月12日〜13日、東部時間の正午から翌日正午まで開催されるCapture the Flagイベントで、セキュリティスキルを試しましょう。