Please Review Vulnerability Escalation Procedures
See original GitHub issueHi there,
Let me begin by saying how much we love the nodejs community and how proactive you guys are in making sure our development environment is safe. The fact that github now warns us about packages with defects is really remarkable.
When we logged in yesterday morning we got the big warning:
We found a potential security vulnerability in one of your dependencies. A dependency defined in server/package.json has known security vulnerabilities and should be updated.
Needless to say, this raised alarms and we dropped what we were doing to investigate and get a fix out that patched the vulnerability. At a glance in github, it looked like this was a XSS vulnerability in the exceljs
package, so we knew we had to fix it very quickly.
After digging, we were linked to https://nvd.nist.gov/vuln/detail/CVE-2018-16459 which linked to https://hackerone.com/reports/356809
Unfortunately, this seems to be where we noticed that things had taken a wrong turn somewhere. Upon further introspection, it seemed super odd that a package such as exceljs
could possibly introduce an XSS vulnerability. There would be almost no reason to run exceljs
inside of a browser – it is almost exclusively a nodejs package… how could it possibly introduce cross-site scripting?
The VERY thorough ticket included this code snippet:
'use strict'
/*global console*/
const Excel = require('exceljs')
const http = require('http')
const port = 8080
const workbook = new Excel.Workbook()
const filename = 'testsheet.xlsx'
function createHTML(worksheet) {
let __html = `
<table>
<tr>
<td>${worksheet.getCell('A1').value}</td>
<td>${worksheet.getCell('A2').value}</td>
<td>${worksheet.getCell('A3').value}</td>
</tr>
<tr>
<td>${worksheet.getCell('B1').value}</td>
<td>${worksheet.getCell('B2').value}</td>
<td>${worksheet.getCell('B3').value}</td>
</tr>
</table>
`
return __html
}
const requestHandler = (request, response) => {
workbook.xlsx.readFile(filename)
.then(worksheets => {
worksheets.eachSheet(function(worksheet, sheetId) {
response.writeHeader(200, {
"Content-Type": "text/html"
})
response.write(createHTML(worksheet))
response.end()
});
});
}
const server = http.createServer(requestHandler)
server.listen(port, (err) => {
if (err) {
return console.log(err)
}
console.log(`server is listening on ${port}`)
})
The report is 100% correct. If you run that code and put HTML/javascript into your excel file, you will end up executing that script in a browser. Unfortunately, the vulnerability does not exist within the exceljs
package, it was introduced in the code sample provided.
Most engineers should know that the correct way to make sure you are protected from XSS is to sanitize everything going into your HTML. There are a LOT of ways to do this. Jade has a number of ways of escaping (td= a1
). Handlebars escapes all values unless you explicitly use three {{{a1}}}
. AngularJS does this automatically, unless you protect against it. React escapes everything unless you call dangerouslySetInnerHTML
(which is really great since it drives home how dangerous this is). In fact, because of XSS concerns, it is always recommended to not ever format HTML like this yourself.
An identical ticket could be filed against the nodejs package fs
:
'use strict'
/*global console*/
const Excel = require('fs')
const http = require('http')
const port = 8080
const filename = 'testsheet.xlsx'
function createHTML(fileContents) {
let __html = `
<table>
<tr>
<td>${fileContents}</td>
</tr>
</table>
`
return __html
}
const requestHandler = (request, response) => {
var fileContents = String(fs.readFileSync(filename));
response.writeHeader(200, {
"Content-Type": "text/html"
})
response.write(fileContents)
response.end()
}
const server = http.createServer(requestHandler)
server.listen(port, (err) => {
if (err) {
return console.log(err)
}
console.log(`server is listening on ${port}`)
})
We tried to raise this issue, and @lirantal said that he agreed the ticket was “debatable”. I very strongly disagree. If this package is debatable, then 90% of packages on npm are also debatable.
https://github.com/guyonroche/exceljs/issues/608#issuecomment-421210841 https://github.com/guyonroche/exceljs/commit/9066cd89a9fad055166b53ce9e75a42e7636bac1
The community as a whole would be more secure if they used specific packages that explicitly protected against script injection when formatting HTML. If we trust or expect all of our packages to protect against injection then one of them will get it wrong and we will possibly be exposed.
We really love an appreciate the security warnings, but they have to be properly vetted. If we start alerting and filing unnecessary CVEs, then the warnings start to mean less and will start to be ignored.
So this ticket is mostly asking how this “vulnerability” slipped through the system and what can be done to prevent these sorts of “vulnerabilities” from popping up again.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:5
- Comments:24 (20 by maintainers)
@jbreckman I couldn’t agree more and this was my intention on raising this concern. But I don’t think @lirantal ignored my comment. I didn’t make it clear enough or pushed on this point too much on my initial comment and unfortunately been a bit too busy to keep chasing that issue.
@vdeturckheim node.js security initiatives and this working group are doing amazing job I’d be happy to help where I can.
Mr. @lirantal!
I really hope I’m not coming off as too much of a jerk in these messages. It is totally not my intention. I just want what’s best for nodejs, and will do what I can to help.
With regards to the package maintainer, I’m not sure you appreciate how intimidating a message from the “Official NodeJS Security Working Group” is. A maintainer can either find a way to appease the request or fight back - and it is probably easier to just find a way to appease. Some people are less stubborn than me 😃
My big problem right now is that no one seems to be saying “The package maintainer should not have gotten involved and no changes should have been made to the package.”
Because of this, a not-that-great HTML escaping function was added to
exceljs
, which has now made that package less secure. By default, engineers should assume that their template/frontend package should escape the values, but now there is a perceived notion of security and if someone makes the mistake of using.html
from this package, their project will now be at risk.If you look at https://hackerone.com/reports/309367 - it looks like your gut instincts were right, but bl4de pressured you into moving forward with it. This is another ticket that should have been immediately closed.
This one didn’t result in a CVE, but is clearly just bad sample code (again): https://hackerone.com/reports/317125
Originally I thought all of bl4de’s submissions were totally bogus, but upon further inspection a lot of the code samples were from the package itself. It’s actually really hard to see and I totally see how you’d make that mistake (see this as a sample https://hackerone.com/reports/309648) Code samples from the package showing the vulnerability are obviously great to see - but at least 3 of these tickets have code sample vulnerabilities from a testbed app that bl4de wrote himself.
Anyway, I love what you guys are doing. We love security over here and really talk about it all the time. I’d love to get involved in some way but am not sure the best way to be effective. I got an invite to the public slack group and have been a fly on the wall for most of the day 😃
Josh