GO言語 1.17 バージョンリリースとセキュリティイシュー

2021.09.12

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

初めに

8月16日にGO言語の1.17 バージョンリリースがありました。しかし、1.17バージョンにセキュリティイシューが発見され、9月9日に1.17.1のバージョンがリリースされました。既存の1.17バージョンを使っているユーザーは1.17.1のバージョンアップデートが必要になりました。 今回はリリースされた1.17バージョンとどのようなセキュリティイシューがあったのかについて簡単にみてみます。 GO言語セキュリティイシューのせいでバージョン変更が必要です。

1.17の変更事項

いくつかの変更事項について簡単にみていみます。

コンパイラー

1.17バージョンにはスタックの代わりにレジスターを使って関数の引数と結果を伝える新しい方法を実装しました。その結果、役5%のパフォーマンス向上や役2%のバイナリサイズの減少ができました。 これは現在、64ビットx86アーキテクチャ(linux/amd64、darwin/amd64、およびwindows/amd64ポート)のLinux、macOS、およびWindowsに対して有効になっています。

言語の変更

言語に関する三つの改善事項があります。

  •  sliceからarray pointerへの変換
    • []Tタイプのsをarray pointerタイプの*[N]Tで変換できます。aがこのような変換の結果である場合、範囲の中にある該当indexは同じ基本要素を参照します(&a[i] == &s[i] for 0 <= i < N)。しかし、len(s)がNより小さい場合はpanicになります。
  • unsafe.Add
    • unsafe.Add(ptr, len)は ptrにlenを追加し、アップデートされたpointerのunsafe.Pointer(uintptr(ptr) + uintptr(len))を返します。
  • unsafe.Slice
    • *Tタイプの表現式のptrの場合、unsafe.Slice(ptr, len)は基本arrayのptrから始め、長さとキャパシティがlenの[]Tタイプのsliceを返します。

 切り取るされたモジュールのグラフ

モジュールがgo1.17以降を指定している場合、モジュールグラフには、他のgo 1.17モジュールの直接の依存関係のみが含まれ、完全な推移的な依存関係は含まれません。 これで、go.modファイルをダウンロード・readする必要がなくなって開発の時間の短縮ができます。

ライブラリー

変更事項の中でよく使われるライブラリーを選んでみました。全体内容は参照リンクで確認してください。

  •  URLクエリパッシング
    • net/url及びnet/httpパッケージは「&」(アンパサンド)以外にもURLクエリのセッティングセパレーター(setting separator)として「;」(セミコロン)が使われます。もう、百分率(non-percent-encoded)でインコディングされてないセミコロンが含めている設定は断られ、net/httpサーバーはリクエストURLからServer.ErrorLogに警告を記録します。 例えば、1.17以前のURLクエリメソッドexample?a=1;b=2&c=3はmap[a:[1] b:[2] c:[3]]返しましたが、もうmap[c:[3]]を返します。
  • net/http
    • ReadRequest関数はリクエストに多数のHost headerがある場合、もうエラーを返します。
    • net/httpで処理する特定HTTP headerを扱う際、ASCIIじゃない文字はもう無視または拒否されます。
  • net/http/httptest
    •  提供されたコードが有効な3桁(Three digit)のHTTP status codeではない際、ResponseRecorder.WriteHeaderはpanicになります。これはnet/httpのResponseWriterの実装動作と一致します。
  • strconv
    • 浮動小数点数(floating point number)形式をフォーマッティングするためUlf AdamsのRyūアルゴリズムを使います。このアルゴリズムでパフォーマンスが向上されました。

1.17のセキュリティイシュー

この問題は、CIA3要素(confidentiality, integrity, availability)の可用性に関することで、深刻な問題になれます。pnicは思われなかった状態で発生、全体プロセスを終了させることができます。攻撃者がこのセキュリティの穴を活用して攻撃すると、データや販売の損失などビズネスに関する問題を起られるかもしれません。

この問題を解決した1.17.1と1.16.8バージョンがリリースされました。

既存の1.17 / 1.16バージョンを使っているユーザーは1.17.1と1.16.8バージョンへの変更が必要です。

最後に

1.17のアップデートで色々変更事項について見てみました。色々改善点があってGO言語の性能がもっと高くなったことが確認できました。しかし、もう改善されましたがセキュリティに関する問題も一緒にあリますので既存のバージョンを使っているユーザーは注意が必要だと思います。

参照リンク

1.17リリース

1.17バージョンの変更事項

セキュリティイシューに関するスレッド