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

Corrupt PNG file (invalid chunk length) causes read error #391

Closed
popey456963 opened this issue Sep 12, 2020 · 8 comments · Fixed by #392
Closed

Corrupt PNG file (invalid chunk length) causes read error #391

popey456963 opened this issue Sep 12, 2020 · 8 comments · Fixed by #392
Assignees
Labels

Comments

@popey456963
Copy link

When processing some files as buffers this module seems to crash with out of bounds reads. An example file is the following slightly corrupted PNG:

https://femto.pw/dbxe.png

Most browsers will report this as an invalid image and not render it, that is expected. A minimal test case is this, which contains the first 4,100 bytes of that file:

const fileType = require('file-type')

const buffer = Buffer.from([137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,6,106,0,0,4,71,8,2,0,0,0,124,139,171,120,0,0,0,1,115,82,71,66,0,174,206,28,233,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,9,112,72,89,115,170,0,22,37,0,0,22,37,1,73,82,36,240,170,170,255,165,171,68,69,84,120,94,236,189,63,142,100,205,113,189,45,139,32,32,128,144,65,131,2,8,208,249,237,64,160,243,110,64,123,144,35,143,30,215,32,139,62,183,193,13,112,3,116,181,3,174,65,107,248,190,168,251,220,62,125,42,34,51,111,222,91,85,221,61,61,249,32,145,136,56,113,34,50,235,79,87,207,20,230,37,255,229,255,91,44,22,139,197,98,177,88,44,22,139,197,98,177,88,44,22,29,214,215,103,139,197,98,177,88,44,22,139,197,98,177,88,44,22,139,69,151,245,245,217,98,177,88,44,22,139,197,98,177,88,44,22,139,197,98,209,101,125,125,182,88,44,22,139,197,98,177,88,44,22,139,197,98,177,88,116,89,95,159,45,22,139,197,98,177,88,44,22,139,197,98,177,88,44,22,93,214,215,103,139,197,98,177,88,44,22,139,197,98,177,88,44,22,139,69,151,245,245,217,98,177,88,44,22,139,197,98,177,88,44,22,139,197,98,209,101,125,125,182,88,44,22,139,197,98,177,88,44,22,139,197,98,177,88,116,89,95,159,45,22,139,197,98,177,88,44,22,139,197,98,177,88,44,22,93,214,215,103,139,197,98,177,88,44,22,139,197,98,177,88,44,22,139,69,151,245,245,217,98,177,88,44,22,139,197,98,177,88,44,22,139,197,98,209,101,125,125,182,88,44,22,139,197,98,177,88,44,22,139,197,98,177,88,116,89,95,159,45,22,139,197,98,177,88,44,22,139,197,98,177,88,44,22,93,214,215,103,139,197,98,177,88,44,22,139,197,98,177,88,44,22,139,69,151,245,245,217,98,177,88,44,22,139,197,98,177,88,44,22,139,197,98,209,101,125,125,182,88,44,22,139,197,98,177,88,44,22,139,197,98,177,88,116,89,95,159,45,22,139,197,98,177,88,44,22,139,197,98,177,88,44,22,93,214,215,103,139,197,98,177,88,44,22,139,197,98,177,88,44,22,139,69,151,245,245,217,98,177,88,44,22,139,197,98,177,88,44,22,139,197,98,209,101,125,125,182,88,44,22,139,197,98,177,88,44,22,139,197,98,177,88,116,89,95,159,45,22,139,197,98,177,88,44,22,139,197,98,177,88,44,22,93,214,215,103,139,197,98,177,88,44,22,139,197,98,177,88,44,22,139,69,151,245,245,217,98,177,88,44,22,139,197,98,177,88,44,22,139,197,98,209,101,125,125,182,88,44,22,139,197,98,177,88,44,22,139,197,98,177,88,116,89,95,159,45,22,139,197,98,177,88,44,22,139,197,98,177,88,44,22,93,214,215,103,139,197,98,177,88,44,22,139,197,98,177,88,44,22,139,69,151,245,245,217,98,177,88,44,22,139,197,98,177,88,44,22,139,197,98,209,101,125,125,182,88,44,22,139,197,98,177,88,44,22,139,197,98,177,88,116,89,95,159,45,22,139,197,98,177,88,44,22,139,197,98,177,88,44,22,93,214,215,103,139,197,98,177,88,44,22,139,197,98,177,88,44,22,139,69,151,245,245,217,98,177,88,44,22,139,197,98,177,88,44,22,139,197,98,209,101,125,125,182,88,44,22,139,197,98,177,88,44,22,139,197,98,177,88,116,89,95,159,45,22,139,197,98,177,88,44,22,139,197,98,177,88,44,22,93,214,215,103,139,111,203,255,253,254,255,105,247,96,177,88,44,22,139,197,98,177,88,44,22,139,197,98,158,245,245,217,226,59,243,127,191,255,127,254,245,153,22,202,98,177,88,44,22,139,197,98,177,88,44,22,139,197,33,235,235,179,197,247,193,191,26,211,55,101,90,73,196,182,88,44,22,139,197,98,177,88,44,22,139,197,98,49,102,125,125,182,248,129,209,183,96,254,117,24,177,246,222,218,188,139,197,98,177,88,44,22,95,11,254,148,226,251,12,79,252,179,205,96,84,42,205,56,221,67,60,63,100,177,88,44,22,139,175,195,250,250,108,241,99,16,127,180,106,254,97,75,123,77,199,43,108,139,197,98,177,88,44,22,31,198,204,31,63,220,115,234,143,43,61,51,186,239,207,37,102,54,199,30,158,229,141,135,230,197,98,177,88,44,62,157,245,245,217,226,147,225,15,76,105,215,159,162,106,16,184,1,80,16,181,143,215,214,183,88,44,22,139,197,226,107,241,145,191,163,31,249,35,193,217,198,11,254,113,203,161,65,204,216,220,51,240,167,18,105,236,181,165,231,36,5,137,44,68,144,146,244,197,98,177,88,44,62,139,245,245,217,226,227,24,252,1,136,63,36,185,65,177,74,85,33,13,82,213,119,95,73,143,96,177,88,44,22,139,197,23,225,242,175,102,53,190,244,151,251,35,195,163,247,233,119,99,224,179,38,55,135,104,248,228,17,213,54,104,111,150,34,213,34,213,190,88,44,22,139,197,231,178,190,62,91,140,24,252,121,69,165,201,63,211,84,91,157,16,129,22,74,69,85,57,149,250,78,32,5,92,95,44,22,139,197,98,241,149,185,240,43,251,218,111,249,83,93,152,99,191,118,214,33,103,47,115,232,199,131,109,108,86,117,220,226,138,108,215,80,111,26,66,234,213,164,44,22,139,197,98,241,241,172,175,207,22,199,212,63,172,184,162,63,211,36,146,152,90,216,89,82,28,247,160,56,169,74,64,236,186,211,20,23,139,197,98,177,88,124,41,198,191,175,155,191,223,247,232,204,239,250,212,165,125,64,211,48,238,170,167,204,51,227,79,243,207,30,113,129,11,71,164,150,230,4,46,95,75,82,122,134,197,98,177,88,44,62,140,245,245,217,162,203,229,63,166,208,229,189,138,153,217,92,94,77,177,210,20,108,149,59,84,93,44,22,139,197,226,75,241,89,191,161,78,29,138,121,254,170,242,167,61,49,40,137,168,206,216,6,168,241,69,19,174,205,199,28,251,133,174,67,124,236,169,249,79,225,240,196,122,55,15,136,165,4,169,234,75,34,134,197,98,177,88,44,62,158,245,245,217,247,103,240,71,141,94,169,234,174,52,171,201,224,74,179,228,235,176,4,85,175,193,98,177,88,44,22,147,124,228,239,14,255,229,245,82,56,197,247,25,228,140,192,99,130,38,84,147,167,182,200,86,75,142,108,164,149,90,74,74,164,117,136,68,161,180,150,130,166,24,244,244,47,194,115,239,246,117,30,41,55,225,201,87,188,85,22,139,197,98,177,248,4,214,215,103,223,153,193,31,50,38,255,252,225,182,212,18,41,74,218,125,245,170,17,131,235,82,36,106,119,122,250,98,177,88,44,126,30,226,183,192,119,250,69,48,243,112,102,30,175,60,213,60,110,167,170,157,181,85,26,12,74,77,14,7,2,134,158,237,172,238,184,199,79,137,93,165,170,8,137,205,234,226,185,232,25,214,115,78,26,240,252,187,178,88,44,22,139,197,71,178,190,62,251,206,164,63,115,164,160,71,114,214,29,34,150,152,226,173,254,174,55,21,95,131,146,22,19,22,139,197,98,177,224,151,130,126,53,60,242,59,226,179,122,47,112,237,56,186,102,122,229,57,117,208,204,124,121,122,102,41,181,52,32,153,35,61,213,222,35,205,33,245,181,23,22,47,131,39,89,187,175,173,190,88,44,22,139,197,231,176,190,62,251,81,225,207,16,250,147,68,253,35,5,127,206,112,91,221,193,99,33,209,131,26,251,46,168,250,170,98,211,214,92,219,200,197,98,177,88,124,91,206,126,212,39,255,133,95,22,248,213,53,223,238,45,243,93,224,254,26,15,6,202,64,218,99,208,126,216,43,48,79,250,171,173,215,136,62,24,59,115,162,134,84,51,98,213,123,184,179,25,51,141,180,198,155,101,241,42,244,12,243,108,175,231,124,177,88,44,22,95,132,245,245,217,51,121,245,111,247,11,243,189,37,253,249,131,84,11,69,37,15,48,84,49,237,205,84,49,200,160,149,210,180,182,166,197,98,177,88,124,16,159,245,193,123,225,92,181,16,156,157,112,185,61,57,35,157,236,149,109,208,82,75,164,190,207,32,103,4,44,210,30,201,48,110,241,18,177,239,77,6,165,196,35,67,78,245,186,66,92,149,20,164,133,190,120,5,60,189,122,158,215,179,189,88,44,22,139,175,192,250,250,236,153,232,215,124,143,90,29,252,177,160,103,6,53,178,16,155,36,167,210,173,184,235,41,72,59,36,131,112,81,30,80,90,69,41,158,122,176,21,23,139,197,98,241,113,60,242,217,171,222,201,33,110,35,190,124,250,217,198,167,28,116,109,200,184,235,145,106,143,11,93,209,242,220,155,92,187,249,101,210,113,164,190,39,146,193,3,98,79,165,44,158,136,63,207,4,129,139,235,105,95,44,22,139,197,87,96,125,125,246,28,122,191,215,253,119,63,65,48,243,135,128,240,96,243,221,145,1,82,26,40,85,169,238,142,148,90,10,146,24,41,138,235,82,36,166,106,77,165,16,72,100,81,90,44,22,139,197,5,248,20,253,248,207,210,107,39,94,232,242,150,83,237,207,125,78,98,26,107,207,159,65,154,118,121,248,115,111,245,1,204,92,120,236,121,240,33,211,174,33,74,125,81,90,60,157,244,12,43,150,178,88,44,22,139,197,231,178,190,62,27,209,251,133,173,223,232,226,212,47,120,111,247,24,122,67,92,79,237,44,233,236,32,69,11,93,184,66,44,155,7,183,242,6,162,43,149,84,37,149,232,85,47,85,125,177,88,44,22,103,73,159,159,51,31,167,143,127,228,198,4,31,50,63,80,206,11,119,72,45,103,39,92,110,239,57,165,159,189,137,184,220,248,157,24,60,189,79,124,126,210,168,58,153,227,124,185,136,103,241,8,245,105,212,211,75,73,6,5,139,197,98,177,88,124,46,235,235,179,17,233,247,119,226,154,174,106,4,238,116,157,0,198,41,132,200,82,74,0,164,242,120,186,213,111,120,12,85,17,189,18,51,169,42,0,137,236,117,109,174,197,226,59,51,255,62,63,251,19,241,21,126,130,126,242,159,226,151,62,252,15,120,110,227,8,173,93,122,61,58,139,224,131,79,119,252,220,167,220,225,179,30,200,167,195,3,31,63,252,102,117,220,168,170,22,250,60,189,46,137,4,216,82,156,150,204,139,107,248,179,167,184,247,148,134,190,158,237,197,98,177,88,124,29,214,215,103,35,6,191,179,199,191,206,189,170,223,253,190,59,201,188,71,27,106,97,33,6,210,73,3,143,29,111,84,76,224,186,2,215,69,85,28,175,18,51,36,233,82,20,251,194,182,88,124,87,244,62,127,250,187,253,233,99,7,163,198,103,141,245,193,88,144,141,229,226,55,195,31,224,60,175,123,42,210,228,7,15,162,253,117,183,29,115,225,220,104,121,238,109,63,235,177,59,95,225,14,135,212,75,186,66,28,123,90,42,93,70,237,26,232,164,106,53,44,94,65,122,170,215,51,191,88,44,22,139,175,201,250,250,236,10,250,189,158,126,217,167,192,161,197,61,158,138,158,152,130,32,57,83,10,136,190,246,194,27,85,73,200,224,78,141,170,59,72,241,32,197,73,137,96,177,248,222,204,191,213,47,255,68,140,27,207,142,157,241,207,156,168,93,230,212,229,41,182,164,236,209,215,67,119,59,188,36,134,83,143,229,193,7,254,145,103,5,143,79,8,98,200,181,57,79,57,253,167,98,254,25,27,56,15,95,175,11,189,18,101,208,174,181,213,143,169,206,102,47,98,175,212,212,23,215,208,243,233,193,86,217,105,138,139,197,98,177,88,124,29,190,231,215,103,189,95,189,210,35,240,88,129,235,65,138,149,18,147,106,39,80,236,74,144,210,32,165,149,106,64,145,238,134,113,201,211,32,85,83,144,104,234,105,2,203,99,173,166,88,215,54,105,177,248,81,153,127,15,15,222,240,148,6,134,202,140,19,207,161,211,207,29,183,156,210,67,148,78,32,197,75,224,10,177,43,95,19,191,225,43,174,122,97,38,87,122,197,101,190,62,215,158,174,61,250,70,240,160,6,15,237,208,16,212,106,211,127,118,8,132,174,229,169,170,73,84,172,181,25,15,144,205,253,205,246,166,51,168,206,197,101,244,204,55,159,228,245,84,47,22,139,197,226,235,243,13,191,62,171,191,158,149,186,78,234,34,1,164,52,168,134,61,218,32,77,98,147,52,199,113,93,113,18,93,247,146,131,238,78,79,161,215,155,168,182,58,214,21,165,205,184,174,173,239,110,200,98,81,249,159,255,249,159,61,106,225,213,136,199,230,215,209,124,15,159,122,111,187,147,120,190,183,73,106,111,206,236,29,33,115,93,24,2,143,131,241,51,223,108,39,245,96,176,63,133,195,81,243,103,185,51,98,22,49,98,15,57,231,153,156,124,150,107,3,117,153,103,221,71,115,46,12,212,101,72,131,103,221,234,43,51,120,140,42,29,122,124,239,17,85,173,93,186,39,233,164,61,115,143,230,124,141,82,53,197,55,211,27,41,117,84,234,181,204,143,90,204,51,120,26,163,68,213,131,173,178,88,44,22,139,197,87,231,251,124,125,54,254,101,236,186,7,196,66,162,150,244,26,16,75,129,102,234,98,196,172,61,127,67,74,45,37,48,48,68,241,86,233,210,52,84,81,3,129,24,177,198,224,138,116,137,3,157,229,34,158,197,119,165,247,197,150,139,77,67,208,107,116,157,216,149,121,30,121,251,29,246,98,168,251,19,137,129,90,187,180,49,72,137,83,75,138,211,218,11,27,158,70,60,126,218,49,215,9,44,98,223,107,16,251,35,248,132,193,52,157,248,8,147,19,206,30,116,237,98,135,93,151,31,47,141,151,219,157,167,12,9,158,53,231,195,240,11,79,94,30,91,236,3,255,228,168,121,234,161,245,136,166,146,68,111,239,249,125,245,116,22,213,38,169,234,105,47,94,188,148,230,43,178,158,255,197,98,177,88,252,136,124,171,127,125,22,191,140,181,72,165,179,123,64,220,76,9,2,215,19,148,82,181,103,14,6,165,30,117,126,32,165,89,5,116,119,18,52,73,182,216,89,73,169,6,150,244,90,106,174,166,141,246,197,23,225,218,55,80,193,160,81,165,228,153,57,107,242,62,97,3,165,4,147,188,244,125,56,249,62,127,228,14,244,246,38,52,47,224,45,24,234,242,146,204,21,158,121,32,69,15,188,145,57,117,109,198,27,73,215,218,203,143,193,156,222,52,233,143,156,56,104,244,249,4,167,184,124,165,30,143,63,70,130,199,47,246,244,135,246,185,248,195,121,209,67,155,25,251,244,163,7,3,207,158,85,253,82,34,96,13,68,197,32,157,20,148,38,125,241,10,234,147,220,124,218,67,92,47,199,98,177,88,44,126,116,190,195,215,103,250,125,172,223,205,4,90,40,201,16,59,32,106,237,234,70,83,73,65,144,60,206,164,45,81,157,161,52,71,245,102,38,127,69,134,230,174,21,169,168,85,22,213,128,88,138,7,44,143,149,110,150,197,1,254,125,196,143,133,110,126,251,102,101,248,40,168,186,167,250,111,35,238,13,205,84,251,225,27,44,25,78,189,33,47,188,123,39,91,230,39,227,60,244,135,129,181,231,247,120,201,157,138,155,41,79,50,220,158,247,141,40,17,236,133,13,252,160,9,136,158,178,16,85,186,245,188,128,193,228,11,231,210,114,161,241,139,112,234,218,50,215,224,187,50,255,0,113,78,250,101,102,33,142,145,173,231,119,125,48,51,149,6,78,8,131,214,46,25,227,246,90,69,241,29,20,71,160,170,98,167,41,10,74,3,195,226,165,140,95,29,88,175,206,98,177,88,44,126,80,190,213,127,188,201,239,99,2,173,90,77,169,199,177,11,233,196,4,144,210,160,42,23,96,72,236,90,232,206,160,218,244,7,174,55,61,18,35,208,66,9])

;(async () => {
    const type = await fileType.fromBuffer(buffer)

    console.log(type)
})()
@popey456963
Copy link
Author

The error is this:

(node:1313) UnhandledPromiseRejectionWarning: RangeError [ERR_OUT_OF_RANGE]: The value of "offset" is out of range. It must be >= 0 and <= 3619. Received -1431633916
    at boundsError (internal/buffer.js:53:9)
    at Buffer.readInt32BE (internal/buffer.js:365:5)
    at Object.get (/home/codefined/femto/apps/web-file-uploader/node_modules/token-types/lib/index.js:216:20)
    at BufferTokenizer.peekToken (/home/codefined/femto/apps/web-file-uploader/node_modules/strtok3/lib/BufferTokenizer.js:94:22)
    at BufferTokenizer.readToken (/home/codefined/femto/apps/web-file-uploader/node_modules/strtok3/lib/BufferTokenizer.js:81:29)
    at readChunkHeader (/home/codefined/femto/apps/web-file-uploader/node_modules/file-type/core.js:964:29)
    at _fromTokenizer (/home/codefined/femto/apps/web-file-uploader/node_modules/file-type/core.js:970:24)
    at process._tickCallback (internal/process/next_tick.js:68:7)
    at Function.Module.runMain (internal/modules/cjs/loader.js:745:11)
    at startup (internal/bootstrap/node.js:283:19)

@Borewit
Copy link
Collaborator

Borewit commented Sep 13, 2020

I used the following code to reproduce the issue:

const FileType = require('file-type');
const path = require('path');

const fixture = path.join('fixture', 'c0rrupt.png');
(async () => {

  try {
    const fileType = await FileType.fromFile(fixture);
    console.log(fileType);
  } catch(err) {
    console.error(err);
  }
})();

The sample file is corrupt, it has a chunk which exceeds the maximum length of 2^31 - 1 bytes, ref.
That makes the "bug" label of this issue very arguable.

The issue is not related to buffered input.

We could return undefined if the PNG is corrupt: #392, or ignore the invalid length #393.

@Borewit Borewit changed the title Some buffered input can cause 'out of bounds' reads Corrupt PNG file (invalid chunk length) causes read error Sep 13, 2020
@Borewit
Copy link
Collaborator

Borewit commented Sep 15, 2020

Let us know if there are other cases you experience read errors @popey456963. If it is caused by a corrupt or manipulated sample, I will only address it if I believe we can improve our code (which was the case in this issue). Being able to deal with odd data, or validating files, is not goal by itself.

@popey456963
Copy link
Author

Hey! That was all fixed vastly quicker than I could have hoped for, thank you so much.

I agree that detecting the type of files like this is likely not important and shouldn't be added to this library (nor does our service want this functionality). My only desire would be for corrupted files to not crash the module.

@Borewit
Copy link
Collaborator

Borewit commented Sep 15, 2020

There will be cases left where an exception is thrown. I don't think that is the same as a crash. You can simply catch those and move on right?

@popey456963
Copy link
Author

Do now! But we didn't before, no. We had error handling around the endpoint but it simply killed the enrichments we were doing on it (thus eliminating all enrichments, not just file-type).

The README.md doesn't mention that it can crash given malformed inputs. I (incorrectly) assumed that I could throw random Buffers and as long as I ensured they had a length of >0 and <4100 no error would be thrown, it just might return undefined.

I think it might be a good idea to add that it can crash to the documentation.

I provide a file host service which allows anyone (even people with no account) to upload files to it. I then send those files to file-type and others in order to be enriched. Is it safe for me to send untrustworthy items to file-type?

@Borewit
Copy link
Collaborator

Borewit commented Sep 15, 2020

The 4100 sample size does not longer exist since version v14.0.0. The API changed drastically since then, but we desgined the .fromBuffer in such a way it provides backwards compatibility with the difference that any sample size will do. Best to provide the entire file. And as the README advises:

If file access is available, it is recommended to use FileType.fromFile() instead.

Reason for breaking with 4100 bytes sample size is that some file types could simply not determined with the first 4100 bytes, at least not for all files. The longer the sample you provide, the greater precision is since then to determine the file type. See also: #319 (comment).

Again, throwing an exception is in my opinion not the same as crashing. It is a way to express something unexpected has happened. Crashing in my view prevents further execution of your application. Maybe we should document the possibility of an exception, which is could be thrown underlying dependencies. Suppressing is also a possibility, I am personally not in favor of that unless we have clear reason to assume a specific exception could occur (which we already do). That way we also learn if our code can be improved like in this issue.

@Borewit
Copy link
Collaborator

Borewit commented Sep 15, 2020

Is it safe for me to send untrustworthy items to file-type?

I am not sure what that means, but as long as you don't harm third parties with that, taking privacy and copyright into account, I think it is fine. If it can potentially damage (software) systems, please warn to treat it with extreme caution and zip it with a password.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
2 participants