説明
長さに対する算術演算の結果をそのまま割り当てサイズに使うと、整数オーバーフローやラップアラウンドが起こる可能性があります。
想定される影響
- 想定より小さいバッファーが作られたり、実行時にパニックが発生したりするおそれがあります。
- 入力サイズを悪用され、サービス拒否につながる可能性があります。
対処方法
- 演算の前に、入力の長さと乗算の各オペランドに上限を設けてください。
- 計算結果が型の最大値を超えないことを確認してください。
例
変更前
go
func allocateImage(width, height int) []byte {
return make([]byte, width*height)
}
変更後
go
func allocateImage(width, height int) []byte {
const maxBufferBytes = 64 * 1024 * 1024
if width <= 0 || height <= 0 || width > maxBufferBytes/height {
return nil
}
size := width * height
return make([]byte, size)
}
解説:
- 変更前: 入力された幅と高さを検証せずに掛け合わせるため、割り当て前にオーバーフローやラップアラウンドが起こる可能性があります。
- 変更後: 最初に0以下の値を拒否して除算のエラーを防ぎ、乗算前にサービスのバッファー上限を確認します。上限が
intの範囲内なので、検証を通った乗算はオーバーフローしません。整数の範囲内でも過大な割り当ては拒否します。