Skip to content

Commit 236a297

Browse files
committed
fix: Prevent local file access by default using the localUrlAccess: false option
BREAKING CHANGE: Prevent local file access by default to fix a security issue. Please provide the `localUrlAccess: true` option if you want to keep the old behavior but keep your system vulnerable to local file access.
1 parent 85e2470 commit 236a297

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,16 @@ config = {
125125
"zoomFactor": "1", // default is 1
126126

127127
// File options
128-
"type": "pdf", // allowed file types: png, jpeg, pdf
129-
"quality": "75", // only used for types png & jpeg
128+
"type": "pdf", // allowed file types: png, jpeg, pdf
129+
"quality": "75", // only used for types png & jpeg
130130

131131
// Script options
132132
"phantomPath": "./node_modules/phantomjs/bin/phantomjs", // PhantomJS binary which should get downloaded automatically
133133
"phantomArgs": [], // array of strings used as phantomjs args e.g. ["--ignore-ssl-errors=yes"]
134-
"script": '/url', // Absolute path to a custom phantomjs script, use the file in lib/scripts as example
135-
"timeout": 30000, // Timeout that will cancel phantomjs, in milliseconds
134+
"localUrlAccess": false, // Prevent local file:// access by passing '--local-url-access=false' to phantomjs
135+
// For security reasons you should keep the default value if you render arbritary html/js.
136+
"script": '/url', // Absolute path to a custom phantomjs script, use the file in lib/scripts as example
137+
"timeout": 30000, // Timeout that will cancel phantomjs, in milliseconds
136138

137139
// Time we should wait after window load
138140
// accepted values are 'manual', some delay in milliseconds or undefined to wait for a render event

lib/pdf.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ function PDF (html, options) {
3535
if (this.options.filename) this.options.filename = path.resolve(this.options.filename)
3636
if (!this.options.phantomPath) this.options.phantomPath = phantomjs && phantomjs.path
3737
this.options.phantomArgs = this.options.phantomArgs || []
38+
39+
if (this.options.localUrlAccess) this.options.phantomArgs.push('--local-url-access=false')
3840
assert(this.options.phantomPath, "html-pdf: Failed to load PhantomJS module. You have to set the path to the PhantomJS binary using 'options.phantomPath'")
3941
assert(typeof this.html === 'string' && this.html.length, "html-pdf: Can't create a pdf without an html string")
4042
this.options.timeout = parseInt(this.options.timeout, 10) || 30000

test/index.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,33 @@ test('load with cookies js', function (t) {
228228
})
229229
})
230230
})
231+
232+
test('allows local file access with localUrlAccess=true', function (t) {
233+
t.plan(2)
234+
235+
pdf.create(`
236+
<body>here is an iframe which receives the cookies
237+
<iframe src="file://${path.join(__dirname, 'multiple-pages.html')}" width="400" height="100"></iframe>
238+
</body>
239+
`, {localUrlAccess: true})
240+
.toBuffer(function (error, buffer) {
241+
t.error(error)
242+
const count = buffer.toString().match(/\/Type \/Page\n/g).length
243+
t.assert(count === 1, 'Renders a page with 1 page as the content is missing')
244+
})
245+
})
246+
247+
test('does not allow localUrlAccess by default', function (t) {
248+
t.plan(2)
249+
250+
pdf.create(`
251+
<body>here is an iframe which receives the cookies
252+
<iframe src="file://${path.join(__dirname, 'multiple-pages.html')}" width="400" height="100"></iframe>
253+
</body>
254+
`)
255+
.toBuffer(function (error, buffer) {
256+
t.error(error)
257+
const count = buffer.toString().match(/\/Type \/Page\n/g).length
258+
t.assert(count === 5, 'Renders a page 5 pages as the content is present')
259+
})
260+
})

0 commit comments

Comments
 (0)