10 ポイント 投稿者 GN⁺ 2024-11-05 | 1件のコメント | WhatsAppで共有
  • Goコードを書く際にセキュリティを考慮するのは複雑な作業
  • いくつかの具体的な実践方法を示し、継続的に適用することで、堅牢で安全かつ高性能なコードを書けるよう支援する

Goバージョンを最新に保つ

  • プロジェクトで使用するGoのバージョンを最新に保つ必要がある
  • 最新の言語機能を使わなくても、Goのバージョンを上げれば、発見済みの脆弱性に対するすべてのセキュリティパッチを受け取れる
  • 新しいGoバージョンは、最新の依存関係との互換性も保証する
  • Goのリリース履歴サイトで、どのGoリリースでどのセキュリティ問題やCVEが解決されたかを確認し、プロジェクトの go.mod ファイルで最新バージョンに更新できる
  • Goバージョンをアップグレードした後は、互換性や依存関係の問題が発生していないか確認する必要がある
  • 静的コードアナライザーを使ってコード品質とセキュリティを評価できる

vet

  • Go標準の go vet コマンドでGoコードを解析できる
  • go vet コマンドは引数なしで実行すると、デフォルトで許可されているすべてのオプションで実行される
  • ソースコードをスキャンし、潜在的な問題を報告する
  • よくある問題には、goroutineのミス、未使用の変数、到達不能なコード領域などがある

staticcheck

  • サードパーティ製リンターのStaticcheckは、バグを見つけ、パフォーマンス上の問題を検出し、Go言語のスタイルも適用する
  • 見つかった問題を説明し、例とともに修正案を提示する
  • CIパイプラインで実行するだけでなく、スタンドアロン実行ファイルとしてインストールしてローカルでコードをスキャンできる
  • インストールしたバージョンを確認し、スキャンを実行する準備ができているか確認する
  • 引数なしで実行すると、デフォルトですべてのコードアナライザーを呼び出す
  • NGINX Agent のGitHubリポジトリで何が見つかるかの例を見る
  • スキャン結果は、deprecatedなパッケージ/メソッド/関数、未使用の変数/フィールド、コード品質に関する問題など、3つに分類できる

golangci-lint

  • golangci-lintgo install コマンドでインストールできる
  • インストールが正常に行われたかバージョンを確認する
  • 引数なしで呼び出すと、すべてのリンターが実行される
  • 先ほどクローンした agent リポジトリで、どのような警告や提案が表示されるか確認する
  • リンターは正確なファイルと行を示してくれる
  • コードを評価して変更した後、リンターを再実行し、すべての単体テストを実行する
  • テストが通ったら、更新したコードをコミットしてリモートへpushする

競合状態(Race Condition)の検出

  • 複数のgoroutineが同時にリソースへアクセスしようとすると、競合状態が発生する可能性がある
  • 少なくとも1つのgoroutineがそのリソースを変更しようとすると検出される
  • Goは -race 引数付きの test ツールを使って、こうした状態をテストすることを標準でサポートしている
  • Race Detectorは実行されたコードだけを評価し、実行されないコードパスは無視するため、デッドコードがないことを確認するために、まず静的コードアナライザーを実行する必要がある
  • テストを並列実行すると、並行性の問題を検出できる可能性が高まる

脆弱性のソースコードスキャン

govulncheck

  • CVEs データベースに掲載されている既知の脆弱性に対してコードベースをスキャンするツール
  • Goチームが開発しており、Go脆弱性専用データベースがスキャナーに情報を提供する
  • 最新版をインストールした後、基本機能を試す
  • habit リポジトリをクローンし、ルートディレクトリでツールを実行する
  • 脆弱性は見つからない
  • バイナリをスキャンすると別の脆弱性が見つかる可能性がある
  • Goのバージョンを最新にアップグレードし、依存関係を取得したうえで、ソフトウェアと依存関係にCVEがないか確認する

gosec

  • 安全でないコード構成を見つけるのに役立つ静的コードアナライザー
  • ローカルシステムでも、GitHub ActionとしてCIパイプラインでも実行できる
  • スキャン設定のためのオプションやルール一覧が豊富に用意されている
  • スキャン対象のGoコードがあるGitHubリポジトリをクローンし、ルートディレクトリでスキャンを開始する
  • スキャンレポートでは、重大度と信頼度で並べ替えられた潜在的な問題の一覧を確認できる
  • 報告されたCWEを確認し、列挙された弱点の詳細を学ぶ

ファジング

  • コード品質を確認し、脆弱性を発見するための最後の方法
  • コードテストのカバレッジを使って、ランダムに生成された入力データを操作する自動化された特殊なテスト
  • バッファオーバーフロー、SQLインジェクション、DoS攻撃、XSS攻撃などの潜在的なセキュリティ欠陥を見つけるのに非常に有用
  • 多数の入力組み合わせが自動生成されるため、開発者が何百、何千もの入力データの組み合わせを手作業で考える必要がない

1件のコメント

 
GN⁺ 2024-11-05
Hacker Newsの意見
  • govulncheckは、脆弱なコードに実際に到達可能かどうかを確認するツールであり、プログラムの依存関係を点検するより有用である
  • Googleのcapslockプロジェクトも忘れずに参考にする必要がある
  • go vetgo test -raceに関する有用なヒントが含まれている
  • Goはメモリ安全ではないが、他の言語より安全にコーディングしやすい
    • Goの明快な構文のおかげで、関数の動作やデータ構造を容易に理解できる
    • AIツールがGoとうまく相性が良いのは、関数内の文脈が明確だからである
  • Semgrepは、静的解析によって言語や一般的なフレームワークに対する検査を行う優れたツールである
    • SemgrepのオープンルールはGitHubで確認できる
  • Goのセキュリティ上の評判に疑問が呈されている
    • Goは一般に安全で安定していると考えられており、.NETのような他のツールと同程度である
  • gosecについて新たに知った
  • 9年間Goアプリを保守してきたが、Goのバージョンとモジュールを簡単にアップグレードできた
    • GitHubが自動的に脆弱性を知らせてくれ、99%のケースで変更なしに動作する
  • Goは実際にはメモリ安全ではない
    • アトミック性が保証されるのはワードサイズの値だけであり、インターフェースポインタやスライスのようなダブルワード値は並行処理においてメモリ安全性を損なう可能性がある
  • Goは良いが、最近はジェネリクスの使用が増えており、コードの可読性が低下している
    • 以前の、ジェネリクスをほとんど使わなかったGoコードより読みにくくなっている