Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

image/jpeg: excessive memory usage #10532

Closed
dvyukov opened this issue Apr 22, 2015 · 5 comments
Closed

image/jpeg: excessive memory usage #10532

dvyukov opened this issue Apr 22, 2015 · 5 comments
Milestone

Comments

@dvyukov
Copy link
Member

dvyukov commented Apr 22, 2015

The following program consumes 1.3GB of memory to produce:
decode failed: invalid JPEG format: bad Huffman code
Not sure whether it is OK or not, since the format is compressed probably the image bounds are large. But still it is suspicious for the tiny input file.

package main

import (
    "bytes"
    "encoding/hex"
    "fmt"
    "image/jpeg"
)

func main() {
    data, _ := hex.DecodeString(input)
    img, err := jpeg.Decode(bytes.NewReader(data))
    if err != nil {
        fmt.Printf("decode failed: %v\n", err)
        return
    }
    fmt.Printf("bounds: %+v\n", img.Bounds())
    var w bytes.Buffer
    err = jpeg.Encode(&w, img, nil)
    if err != nil {
        panic(err)
    }
}

var input = "ffd8ffe000104a46494600010100000100010000ffdb004300100b0c0e0c0a10" +
    "0e0d0e121110131828de1816161834363125000000fe3c3c3933383440485c4e" +
    "17116df646ddaa1cd09c404457453738506d51575f626768673e4d7179706478" +
    "5c656763ffc2000b08ff80fe9501011100ffc4001a0000020301010000000000" +
    "00000000000003040102050006ffda00080101000000011badd2b348270c4c0c" +
    "3c2232968cf52a22aa801c6415211cb2ef440c4100000064a18f7f424ea33141" +
    "2f2aa1a26caaaf11bda026af5028b19365cec317116df646ddaa1cd09cc952bd" +
    "5882346354852873acc677067ae20e80236cddcb32a9427124aeac67eca68ec9" +
    "42551460c5e81674c53759f8eb03"

go version devel +87054c4 Wed Apr 22 02:50:48 2015 +0000 linux/amd64

@dvyukov dvyukov added this to the Go1.5 milestone Apr 22, 2015
@nigeltao
Copy link
Contributor

The image bounds are large. The fragment "ffc2000b08ff80fe95" means a Start-Of-Frame marker "ffc2" whose height and width are 0xff80 and 0xfe95. In other words, the image claims to be 65173 x 65408, or over 4 billion pixels.

See also issue #5050.

Closing as WAI.

@roustem
Copy link

roustem commented May 6, 2016

I am very sad that this issue is not taken seriously and closed as WAI. It is a real security threat and can easily be used for DoS attacks. For example, https://hackerone.com/reports/390

I understand that the API cannot distinguish between a legitimate or malicious image in this case. There should be an option to pass the max image dimensions or max memory size to prevent DoS attacks.

As it stands now, we have no way of protecting our servers against malicious images.

@bradfitz
Copy link
Contributor

bradfitz commented May 6, 2016

As it stands now, we have no way of protecting our servers against malicious images.

@roustem, yes you do: https://golang.org/pkg/image/jpeg/#DecodeConfig

Read the header to calculate its dimensions first. Use a https://golang.org/pkg/io/#TeeReader to save the bytes read into a https://golang.org/pkg/bytes/#Buffer and then if you're happy with the dimensions, use https://golang.org/pkg/io/#MultiReader to stitch together the saved header buffer with the remaining jpeg io.Reader. It all takes a few lines and is the natural Go composable way. See Camlistore's codebase for an example.

@bradfitz
Copy link
Contributor

bradfitz commented May 6, 2016

(Of course, that's only necessary if you can't rewind the stream. If it's just a file or something, you can seek back to the beginning)

@roustem
Copy link

roustem commented May 6, 2016

That will work. Thank you, @bradfitz !

@golang golang locked and limited conversation to collaborators May 6, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants