[HN Gopher] Npm Audit: broken by design? ___________________________________________________________________ Npm Audit: broken by design? Author : wongmjane Score : 725 points Date : 2021-07-07 14:13 UTC (8 hours ago) (HTM) web link (overreacted.io) (TXT) w3m dump (overreacted.io) | nalekberov wrote: | > It makes beginners miserable | | Can we please tell beginners not to start programming with | node.js? | | Teaching beginners to start with "go-to" technologies became | industry standard already as it helps corporations to become more | and more monopolist and dictate new industry standards. | thereddaikon wrote: | Anyone else read the title to mean the author had audited Npm and | found the whole thing was broken by design? | | Because I've felt that way for years. | quintex wrote: | As someone who only had just gotten into front end programming | after years of backend work, npm has been a nightmare. I haven't | experienced the same level of frustration with other package | managers (pip, cargo, go mod, etc) as I have with npm. | | Is yarn the better option? What is our path forward? | protonimitate wrote: | I've been having a good experience with pnpm lately. It's not a | silver bullet but it addresses some pain points with npm/yarn. | nih0 wrote: | same xd, npm even managed to make me appreciate maven and | gradle | vbezhenar wrote: | I think that there's difference between Java and JS | landscapes. | | Java has rich standard library. Some would say - too rich. | But anyway - very few people would need customized | collections, standard library covers all the needs. And where | it does not cover all the needs, there are few commonly | accepted additions like apache-commons or google guava. So | that one solves `leftpad`-like issues. | | Another difference is that Java is old. Most needs were | covered by many libraries and few libraries survived which | are good enough. It's again some commonly accepted wisdom, so | you don't really need to search for many options. You have | one good enough option that you'll use and move on. | | So it's not about maven/gradle vs npm, it's more about | ecosystems. I don't think that porting maven to JS world | would change anything. | SahAssar wrote: | I think the problem is not really NPM it's the way that | mainstream frontend development requires very wide and deep | dependencies. If you stick to using smaller frameworks and | libraries without heavy build tools then it's not much of a | problem. | mrweasel wrote: | I basically do no frontend development, partly due to tools npm | and the current frameworks, I simply cannot wrap my head around | it. I do help run a few modern javascript application however. | Even a minimal app will pull in 1000+ dependecies, and I think | that's the problem. | | It simply don't happen in Python, Go or Rust (or even Java) | because the languages comes with a rich standard library. | Javascript comes with just the basics, everything else is a | dependency. It's not uncommon for people to audit their | dependencies in Python or Go, but you pull in maybe 10 or 20. A | basic Javascript app easily pull in 100 times that, how are you | suppose to deal with that? | bscphil wrote: | > Rust | | This has not been my experience at all. Most Rust developers | unfortunately seem quite happy to adopt modern programming | bad practices. (There are many exceptions, of course.) | | Example: I went with the first Rust program I could find | installed on my computer, tealdeer. It's a dead simple | program: run `tldr progname` and it will print a handful of | examples of how to run `progname` in your terminal. Run `tldr | --update` and it will download the latest version of the | database containing these examples from a web server. | | To build this extremely basic CLI program, I need ONE HUNDRED | AND NINETEEN distinct crates. | zkldi wrote: | PNPM[1] has became a must-use for me in every node project I | work on now. | | [1]: https://pnpm.io/ | esens wrote: | I found that much of the underlying cause is those mass reporting | regex denial of services as being high severity bugs. | | So many people are reporting these in tons of different projects: | https://github.com/search?q=regex+denial+of+service&type=iss... | | Anyhow it is just annoying and they broke NPM Audit based on | these reports. | | It is good to fix all possible bugs, but many of these are not | anywhere close to the level of bad that the reports are making | them to be. | | But maybe this is needed to just get rid of these issues in | genera? So a wave of regex vulnerability reports and then we | build this type of checking into prettier or similar and we do | not have these in the future? | | EDIT: It appears there as a project that found 100s of CVE | reported Regex vulnerabilities in npm projects -- this is maybe | one of the sources of mass reports. See the bottom of this | resume: https://yetingli.github.io | danabramov wrote: | Hmm. This actually sounds really plausible. I wonder if there's | any way to check that. | junon wrote: | I'm a maintainer of a few of the larger packages on npm. This | is generally pretty accurate. Snyk Security seems only to find | regex DoS bugs and I'm a bit disappointed in them being | classified as high severity, and they're the only ones | submitting reports right now. | | They seem pretty adamant on filing CVEs despite what the owner | says (It's normally fine but these DoS vulns require very large | input to be handed into the function by untrusted sources, | which given how these libraries work isn't going to be very | common). | | Now, I have people yelling at me about dependent packages not | being updated because they don't understand version ranges, or | because some audit states they are high vulns, or whatever. | | Super broken, everything related to npm's package lock stuff is | broken by design. I've been saying it for years now and it | seems people still cling to blindly trusting what corporations | say. | zelphirkalt wrote: | The more I work with parsing, parser combinators and writing | grammars for little languages, the less often I find myself | using or wanting to use any regex at all. When I do, I always | feel like there should be a better way, perhaps a type safe way | of accessing the info I need and so on. It feels "Ugh, there | should be a better way to do this." Especially in JavaScript, | regexes blow in comparison to languages with named matching | groups and all that. In JS regex really feels horrible, even | more cryptic than in other languages. | | I think regexes are often used as a quick and dirty solution to | problems, which should be solved differently. But once the | regex "works" and is in place, others begin to rely on that | output. Over time cruft begins to accumulate and the regex is | forgotten or at least never replaced with anything more | appropriate. | sqrt17 wrote: | > The more I work with parsing, parser combinators and | writing grammars for little languages, the less often I find | myself using or wanting to use any regex at all. | | Surprise: The most common parser combinator libraries do | backtracking. That's exactly the problem. Any solution as | widely used (if not overused) as regular expressions ends up | exposing a number of dark corners where the design isn't as | clean and tight as you would want it. There are lots of | better ways, but most of them are specialized and are totally | unsuited for significant areas where people need something. | | That said: yes I've used LR(1) parsing (not LALR) using a | library that uses parser combinators with a good interface, | and it's more powerful than regex and worth it for the right | usecase. | svieira wrote: | > Especially in JavaScript, regexes blow in comparison to | languages with named matching groups and all that | | Good news (well, probably). JavaScript (ECMAScript 2018+) now | supports named matching groups. | | https://developer.mozilla.org/en- | US/docs/Web/JavaScript/Guid... | JonathonW wrote: | A regex "denial of service" "vulnerability" _could_ be | important, if it shows up in code that processes untrusted | input from end users. | | But NPM Audit has no idea of context-- a "critical" bug in | `browserlist`, which, in this context, is never used outside | the development process and never takes input outside of what's | in my package.json, gets the same prominence (or more so, since | it's early in alphabetical order) as a "critical" bug in | Express, potentially allowing my server to be compromised. | | I'm not really sure what the solution is here; NPM's just a | package manager and doesn't know _how_ you 're using a given | package. A simple heuristic distinguishing development | dependencies and runtime dependencies in NPM Audit might be a | start, but that doesn't help with situations like create-react- | app's react-scripts where _everything_ , runtime or dev | dependency, is a transitive dependency of one package declared | as a runtime dependency. | twistedpair wrote: | Would be nice if package.json had a flag to indicate the | runtime would be either Node.js or a browser. So many of | these "bugs" have no bearing in a browser context. | [deleted] | nkozyra wrote: | > A regex "denial of service" "vulnerability" could be | important, if it shows up in code that processes untrusted | input from end users. | | But in this context what's the end result? Chrome locking up | on the end user's (attacker's) machine? Again, an "attacker" | doesn't have access to the source code for distribution. By | inputting bad regexp data they're only DOSin themselves, no? | Avamander wrote: | StackOverflow and Cloudflare have both self-DoSed | themselves with such flaws, causing downtime. | esens wrote: | Could be in a service on a server, which in this case a | RegEx DOS could lock the server for all users. | [deleted] | JonathonW wrote: | Or if a JS frontend takes in input that comes from other | users-- something like forum post titles or content. | | That's "just" a browser freeze for end users, but still a | potential DOS vulnerability if it's in the application's | critical path. | nkozyra wrote: | Right, but that's why I wrote "context," and seems to be | the primary complaint in this article. | IggleSniggle wrote: | Agreed! | | A "Critical" bug in a dev context should mean something very | different from a "Critical" bug in a prod context. A | "Critical" devDependency bug should be either a direct threat | to the developer's context, either by infecting the dev | machine or by injecting a supply-chain problem, worming it's | way into downstream contexts. | | npm audit is just not granular OR careful enough to address | these issues appropriately. | Angius wrote: | IMHO one solution would be to categorize vulnerabilities | separately for prod dependencies and dev dependencies, and | bubble that categorization up. | | For example, a RegEx DDoS vulnerability in Express would show | up as high severity, while the same would not show in the | bundler you use, or any package that your bundler has in its | dependency tree. | cratermoon wrote: | This kind of nonsense really goes back to the broken CVE | process. https://opensourcesecurity.io/2021/03/30/its-time-to- | fix-cve... | | Linux kernel maintainer Greg Kroah-Hartman has a similar | opinion. https://github.com/gregkh/presentation-cve-is- | dead/blob/mast... | | Edit: LWN mention https://lwn.net/Articles/801157/ | twistedpair wrote: | I had a researcher contact me about a "vuln" in an OSS effort | of mine once. The vuln made no sense w/ how the tool was | used, but they published and I earned a CVE scarlet letter | nonetheless. I finally "fixed" it, but IMHO, nothing was ever | broken or vulnerable. | jrockway wrote: | I wouldn't call a CVE a scarlet letter. Given the current | state of software engineering, it's more like "my project | is valuable enough to be used by someone that cares about | security". You fixed it, one less bug to worry about. No | doubt there are many less popular products with many worse | vulnerabilities that don't have a CVE. | | Even OpenBSD had to change their tagline to "Only two | remote holes in the default install, in a heck of a long | time!" (from "Five years without a remote hole in the | default install!") Still a pretty impressive track record. | DaiPlusPlus wrote: | > You fixed it, one less bug to worry about. | | Those "bugs" can be features though - or the work | involved to fix the bug meant that high-impact feature | work - or other bugfixes, had to be postponed or even | cancelled. | | Our SaaS frequently gets security "researchers" (read: | people running online scanners) submitting emails through | our contact-form informing us about click-jacking attacks | on our login-page - the problem for us is that we have a | lot of second-party and third-party integrations on | unbounded origins that offer access to our application, | and by extension our login-screen through an <iframe> on | their own origin, which is sometimes even an on-prem LAN | web-server accessed through embedded devices where we | can't use popups to do it properly - let alone switch to | a more robust OIDC system - so there is no easy solution | that makes the "I ran a tool, gimme $100" people go-away | without causing a much bigger problem to now exist. | jrockway wrote: | > there is no easy solution that makes the "I ran a tool, | gimme $100" people go-away | | I use the "mark as spam" button :) | staticassertion wrote: | > so there is no easy solution that makes the "I ran a | tool, gimme $100" people go-away without causing a much | bigger problem to now exist. | | Maybe consider setting up a free-tier HackerOne bounty | program? I think they triage to some degree on your | behalf. | zinekeller wrote: | The view of SQLite developers on CVEs is also dim: | https://www.sqlite.org/cves.html | cratermoon wrote: | Beautifully succinct. This quote: "Grey-hat hackers are | rewarded based on the number and severity of CVEs that they | write. This results in a proliferation of CVEs that have | minor impact, or no impact at all, but which make | exaggerated impact claims." Alignment of incentives is | messed up. Goodhart-Strathern's and Campbell's laws apply. | G3rn0ti wrote: | Maybe then writing and submitting a CVE should cost some | money that's payed back together with the reward if the | vulnerability is found to be ,,reasonable" upon review? | cratermoon wrote: | I'm always suspicious of just throwing money at a | problem, particularly in things like open source where | money isn't always the motivator and can often be a | corrupting influence. In some cases this will reduce the | ability of genuinely well-intentioned people to | participate, simply because they don't have the money up | front, and for well-funded organizations the money would | have to be quite a lot. | | I'd like to ask what, other than money _directly_ | motivates people? Is it prestige? A line on their resume? | A requirement for a bootcamp class? In addition, we | should re-evaluate the difficulty of submitting a CVE. Is | it too easy? The story about a mass of "hey your regex | parser could choke on this weird expression[1]" reports | suggest that perhaps so. What can we do to make it so | that CVEs and equivalents are truly meaningful? Also, | just the fact that CVE reports are given a great deal of | respect could be the problem, although at this point that | seems to be self-correcting. | | [1] Some classes of regex parsers are known to be | vulnerable by nature, those that do backtracking for | example, because their worst-case runtime grows | exponentially and can run in unbounded time. This has | been known since at least 2009. There are other | implementations with better worst-case runtimes, but | worse performance in typical cases. The fact that it's | trivially easy to look at a regex parser to see if it | does backtracking and construct an "evil" expression that | breaks it means it's trivially easy to file a DOS report | against any such parser. | px43 wrote: | Believe me, 90% of people who find bugs for a living are | perfectly content with keeping them to themselves and/or | selling them privately. | smsm42 wrote: | AFAIK MITRE has a process for an organization to register | as vendor, and then it would accept CVEs for their | products only from the vendor, not from random people. Of | course this has an opposite failure mode that may have | unscrupulous vendors hide issues or just be lazy in | issuing CVEs for existing bugs, but it eliminates the | problem of random people issuing a ton of CVEs for non- | issue bugs. | cratermoon wrote: | I'm pretty sure CVEs and the like came about _because_ | vendors were choosing to hide or deny security | vulnerabilities. Vulnerability disclosure policies are a | whole different kettle of worms. | trey-jones wrote: | Maybe, but you risk swinging too far in the opposite | direction into under-reporting of vulnerabilities. | BeFlatXIII wrote: | Sounds like academic research publications. Sure, that | will totally be a key step toward cancer therapy or | better biofuels (realistically, the PI gets his jollies | by shoving aldehyde groups onto random molecules) | staticassertion wrote: | I wouldn't take Greg's opinions on security too seriously. | | Spender has a much more nuanced, informed view. I think it | covers the issues of the CVE process well, but doesn't make | the same mistakes that Greg does. | | https://www.grsecurity.com/reports_of_cves_death_greatly_exa. | .. | apayan wrote: | Here's the video of the talk that goes with Greg Kroah- | Hartman's slides: https://www.youtube.com/watch?v=HeeoTE9jLjM | thomascgalvin wrote: | We got bit by this last week; our scans were suddenly all red, | and nobody could deploy to production. We had to write an | analysis of why this wasn't actually dangerous to us in order | to get security to suppress the findings. | paulddraper wrote: | Add prototype pollution and you've covered 90% of all | "vulnerabilities" | zerkten wrote: | Isn't this an area where gamification and machine learning | could actually be useful, if applied carefully? | | If people are competing for CVEs, then why not work out a way | to better differentiate them them through scoring and make this | visible. The goal would be for attention to shift to the | scoring instead of only a CVE count. Offer both views of the | world, so tools could still fall back on the problematic | listings they get today. | | Apply machine learning to classify CVEs based on the reputation | of the reporter, blast radius, or other criteria. Use that to | drive community review and scoring. | | I would not see this a panacea because it brings a lot of | challenges (a la StackOverflow), but it would be much better | than what we have today. | indigochill wrote: | We're kind of already doing scoring in that CVEs are usually | graded on severity, but researchers are motivated to inflate | the severity of CVEs they find. So the question you'd need to | tackle is how does one apply a universal standard to measure | the real impact of a CVE? | | I suspect it's an impossible challenge, but I only dip into | this domain casually so maybe someone has better ideas. | AaronFriel wrote: | For those hoping to run npm audit in your CI/CD pipeline, I | recommend this tool from IBM: https://github.com/IBM/audit-ci | | In highly regulated industries, shipping code flagged as having a | vuln without a manual approval could be a liability. | | This wrapper around npm takes an allowlist argument, and our | procedure is for an engineer to review the failing build, | determine if the vulnerability (ugh, usually regex ddos or | prototype pollution) is present in code that runs only at build | time with trusted inputs, only on the client which is by | definition untrusted, or in our webserver which takes in | untrusted input. | | As long as it's either of the first two, we document it in a | commit and comment and redeploy. It's annoying, but it's far | better than npm audit forcing a fix. | esprehn wrote: | Dan isn't the first person to notice: | | https://www.voitanos.io/blog/don-t-be-alarmed-by-vulnerabili... | | We disable [1] audit entirely because it's not a good default | behavior within a monorepo. It spams the hundreds of developers | with the list of "vulnerabilities" on every install, but only a | few folks should really be upgrading packages. | | We then run audit in non-blocking CI and track the total number | of issues and mostly focus on critical ones. | | [1] https://docs.npmjs.com/cli/v7/using-npm/config#audit | prionassembly wrote: | Having hundreds of developers work on the same code repository | seems insanely complicated. What are the advantages? Where can | I read more about monorepos? | SOLAR_FIELDS wrote: | Google is probably the most (in?)famous example of monorepo. | All of their code is in a single monorepo. | | You can read a bit about the approach's benefits and | drawbacks from someone at Google here: | https://medium.com/@Jakeherringbone/you-too-can-love-the- | mon... | x86_64Ubuntu wrote: | Does monorepo mean that if I checkout Google Wave, I also | checkout the GMail source too? | esprehn wrote: | Sort of, the google3 monorepo is so large that all | checkouts are sparse checkouts. So you have a virtual | checkout of everything but specify the subset you | actually need. | | Once you have the tooling to do this you can use the | monorepo to store all kinds of interesting things, like | built artifacts or the contents of the CDN, since it's | basically just a giant hierarchical KV store with a | global version. | spullara wrote: | Yes. And if you improve something used by both of them | and have to refactor across the source tree you can do | that in a single commit. | | https://cacm.acm.org/magazines/2016/7/204032-why-google- | stor... | suhas_rd wrote: | yes | mulcahey wrote: | Monorepos are pretty common nowadays, arguably popularized by | Google | | https://research.google/pubs/pub45424/ | | That said (1) "you are not Google" as the saying goes (2) | Google built their VCS from scratch in house for scale. | | However it's not tops hard to do this with just git and some | rules/patterns for organization. | marcosdumay wrote: | They do not use an usual git repository. Companies using | monorepos have tools to restrict people's access to parts of | it, and filter log noise. | | Or, in other words, it's not that insanely complicated, | because they have tools that make it look a lot like multiple | repositories. And the large companies using multiple | repositories have tools that make them look just like those | monoreps. And HN has all those interesting threads full of | people saying why one is better than the other. | gervwyk wrote: | We are just 2 devs at the moment and we've setup Lowdefy with | a monorepo and yarn 2 and I can add that even for small | projects a monorepo is just bliss especially with yarn 2 and | lerna! | | We come from separate repos on past versions of the code and | the monorepo setup has sped dev up dramatically, even for a | team of 2. Having the docs next to our code and autogen some | of it from the source code, all is the same repo is just one | advantage. | | It's a small project but you can view the setup here: | https://github.com/lowdefy/lowdefy | x0x0 wrote: | We also wanted to use npm audit in our CI process so, instead | of humans being careful, we could assert any known CVE stops a | staging or prod deploy. Very annoyingly, npm audit doesn't have | ignore functionality, at least when I was last forced to use | it. I had to hack something together with bash scripts. | | For vulnerabilities that we determined weren't an issue ever | (vuln in frontend framework we didn't use), or weren't high | priority enough to P0 through, we needed some way to ignore | either permanently or temporarily specific vulnerabilities. | | Given the enormous dependency sets eg react create, you'd think | the tools would be better at managing them. | dane-pgp wrote: | > Very annoyingly, npm audit doesn't have ignore | functionality | | I can't believe no one here has mentioned the fantastic tool | "better-npm-audit" which can be included as an npm | dependency[0] and lets you add specific vulnerabilities to an | ignore list. | | The ignore list is actually a JSON config file stored | alongside package.json in the repo, so only one developer | ever needs to see the npm audit warning and can mute it for | everyone else (after getting their PR approved). | | Even better, the config file lets you specify an expiry date | for each entry in the ignore list, and provide a note, such | as a link to the upstream issue being worked on, so that you | can periodically be reminded to go back and check if a new | version is available which can give more confidence that your | code really isn't affected. | | I think that developers might have to be instructed to use | the "--no-audit" option to "npm install" if they don't want | to see the (false positive) warnings that the default | behaviour produces, and that's a bad habit to learn if not | all projects they work on are using "better-npm-audit". I | don't know if there is a way to make that option the default | on a per-project basis. | | [0] https://www.npmjs.com/package/better-npm-audit | x0x0 wrote: | Thank you! | | edit: we're going to move to this. My implementation is a | is a file with cve to ignore | reason | jira ticket but I | think we can slam all that in there. And our expiry is | manually checked monthly, so this is a big improvement. | underwater wrote: | Wouldn't you want to only stop a deploy if the commit | introduced the vulnerability (i.e. the deploy changed the | dependency tree). | | From my experience most audit flags happen because a new | vulnerability is discovered, which means stopping a deploy | doesn't actually do anything helpful. | x0x0 wrote: | we do daily deploys, so we're mostly using this as a way to | check cves across rails and react in a way that fails | loudly and doesn't require anyone to step outside their | standard workflow. Regardless of whether the new commits | introduced the cve or not. | richardwhiuk wrote: | I think they are just saying that context matters in security | vulnerabilities, and npm audit doesn't have that context. | | Well yes, correct, well done. By this metric, every security tool | ever written is probably pointless. | danabramov wrote: | Note that `npm audit` runs _during every install_ so people who | use it don't necessarily consciously understand what's | happening. Many of them are beginners and have never used a | security tool before (or even want to use it). | trunnell wrote: | How much of the problem here is that npm audit is a little | annoying and creates problems unrelated to security? | | Or do commenters here actually believe that npm audit should | treat a DoS of a development machine as a non-vulnerability? | | (Please tell me it's the former) | scottlamb wrote: | > Or do commenters here actually believe that npm audit should | treat a DoS of a development machine as a non-vulnerability? | | I believe that npm audit should treat a DoS of a development | machine _by a trusted developer_ as a non-vulnerability. "Code | I (or a fellow committer) wrote uses a lot of CPU" isn't a | vulnerability. If I care to prevent this, I should run said | code within a cgroup with limited resources, not panic about | theoretical expense in one part of the codebase while | necessarily allowing arbitrary execution elsewhere. "npm audit" | is crying wolf, just as the author said. | | I like the proposal [1] near the end: "If I own an npm package | I need to be able to tag a certain transitive vulnerability | category as not affecting _my_ usage of that transitive | package. " This is particularly important for npm given things | like create-react-app but would also be a good idea for "cargo | audit" and such. | | [1] https://twitter.com/dan_abramov/status/1412380714012594178 | jgerrish wrote: | Correct me if I'm wrong. | | But, one of the goals in software engineering right now is | reproducible builds. This means building from source. And of | course we'll want to automate that. We've already made inroads | with CI | | So, correct me if I'm wrong, these are still vulnerabilities. | | Tragedy of the commons stuff. | | This article might be honest. But I hope in the future we don't | need devil's advocate arguments. | jgerrish wrote: | Still, the original post might inspire realignment of bug | fixing incentives. | gentleman11 wrote: | npm is a bit nuts on its own. I started learning react this year | and the course I'm taking had me install that create react app | module or similar. It dragged in 1700 dependencies, and the | folder for a hello world app was almost 90mb iirc. How can you | possibly pretend you have any control over your app or it's | security in that situation? | ratww wrote: | Yeah, that's the biggest issue, IMO. | | Even a simple app with only React as a production requirement | will have dozens of issues a month. | | There are some packages that don't have as many dependencies | such as Typescript or Prettier, but that's not enough, since | the most popular bundlers have hundreds of of dependencies. | | No matter how careful you are, you get flooded by security | issues. | TechBro8615 wrote: | The reason it's so big is because it's your build chain. I've | always found this criticism of JS annoying - you've also got to | pull in a few hundred MB of tooling for C++, Java, or Rust -- | it's just that in the JS case, the "compiler" is usually per | project. | hsbauauvhabzb wrote: | That's hardly true. Some standard libs are smaller, but in | most other languages I can think of there isn't the complete | dependency hell. I want to install _one_ package, the 50 | dependencies or their ancestors create an audit he'll (is the | package secure, so I trust the developer to not inject | malware, abandon the package, or add _more_ dependencies), | etc. | TechBro8615 wrote: | My point was that if you're comparing JS dependencies to | other languages, you need to include their compilers too, | since e.g. TypeScript projects depend on `tsc`. If you | include the size of C/C++/Rust/Java/etc. compilers, I'm | sure you'll find 50mb+ of dependencies. You're right that | it's self-contained though (to be fair, so is `tsc` - most | projects could shed a lot of dependencies by abandoning | Babel in favor of `tsc` or esbuild). | hsbauauvhabzb wrote: | Sure but gcc, clang and python have had a substantial | amount of review. There's no assurance that similar | occurs in the non ecosystem. | username90 wrote: | Other libraries are usually self contained though, unlike JS | libraries which contains dependencies and then those | dependencies has dependencies etc. Probably has to do with JS | lacking a standard library so it is a pain to do anything | without including dependencies. | bhl wrote: | Just curious, have you tried vite with react? It uses esbuild, | which might result in a heavier dependency folder, but I also | wonder if getting rid of webpack removes a lot of the CRA | dependencies. | catears wrote: | So I don't work as a security professional but what I remember | from IT-sec class in uni is that in order to craft an exploit you | need to be vulnerable and the vulnerability needs to be | exploitable. | | If I put a database with default credentials on the internet, | there is both a vulnerability and it is exploitable. Bad. If I | run a database with default credentials on my dev machine, it is | vulnerable, but not exploitable. Perfectly fine. | | For real security work you also need to think about impact. | Hacker dropping production database = we all lose our jobs. Co- | worker connecting to my computer and dropping database as a joke | = no real harm done. | | So three things to think about: - Vulnerability - Exploitability | - Impact | | What I really don't like about npm audit is how it presents | itself as "security tool" and how vulnerabilities are presented. | "6 critical, 10 high vulnerabilities" with a red color screams | "fix me now!!!". This is not fair to users because npm has no | idea of either the exploitability or the impact of the | vulnerability. | | Why present users with a prompt "please fix me now!!" and not | even mention that exploitability and impact need to be measured | first? Seems like they forgot that prompt... | Ayesh wrote: | Vulnerabilities reported to CVE carry a risk score (CVSS) that | conveys this information in standard way. | genezeta wrote: | The title is "Broken by Design". Then the author proceeds to | explain how the design is actually reasonable and meant to work | ok, and how the problem lies in the relevance and context of the | vulnerabilities reported. | | That doesn't seem to be the meaning of "broken by design". | cphoover wrote: | So currently the algorithm is... check (dev)Dependencies and | descendent/transient dependencies to see if they exist in a | security advisory database if they do, highlight and surface them | to the user. | | What are alternatives? A way to ignore or mark a dependency as | safe? Could this be abused if an author can just mark a | dependency as safe? | | Or perhaps, actually analyze syntax with a tool like ESLint | (parse -> AST -> validate) to check that dangerous parts of | libraries are not in use? This solution comes with it's own | complications. Who is authoring these validations? | | Perhaps there are other strategies I'm not aware of. | tutuca wrote: | Excellent rundown of many problems I've encountered in recent | versions of npm and node. | | I've never ever got `audit fix` or `audit fix --force` to solve | any of the mentioned vulnerabilities. Ever. I even relied on | downloading every dependency one by one to find that there where | other offending packages. I just gave up. | | It's really useless and deceptive. | cphoover wrote: | Vulnerabilities are just code paths that can behave in unexpected | ways and be abused.... I'm not sure the author's point, that | development configuration could not hide malicious code? Why not? | | All NPM does is scan to the dependency graph for vulnerability | reports, it doesn't make any assessment of your consuming | application's use-case. If you don't find this useful that is | fine, don't use it. | | I think it's totally worthwhile to figure out which tools rely on | insecure dependencies. | | Also looks like you can specify npm to ignore dev dependencies: | | > _Any packages in the tree that do not have a version field in | their package.json file will be ignored. If any --omit options | are specified (either via the --omit config, or one of the | shorthands such as --production, --only=dev, and so on), then | packages will be omitted from the submitted payload as | appropriate._ | danabramov wrote: | > _I 'm not sure the author's point, that development | configuration could not hide malicious code? Why not?_ | | Quite the opposite! Quoting the article: | | _As any security professional will tell you, development | dependencies actually are an attack vector, and perhaps one of | the most dangerous ones because it's so hard to detect and the | code runs with high trust assumptions. This is why the | situation is so bad in particular: any real issue gets buried | below dozens of non-issues that npm audit is training people | and maintainers to ignore. It's only a matter of time until | this happens._ | | My point is that in the sea of non-issues, real issues are easy | to miss and ignore. | | _> If you don't find this useful that is fine, don't use it._ | | You can't "not use it" because it's literally the default | behavior built into `npm install` now. Of course there are ways | to opt out, but this doesn't alleviate the confusion. | cphoover wrote: | All it does is look to see if either your direct dependencies | or descendant dependencies exist in the advisory database.... | | It seems like a simple algorithm that works pretty well. | Perhaps ignoring certain dependencies makes sense, via an | ignore list. | | I just find the title "NPM is broken by design" to be a | little hyperbolic, when it seems like the complaint is that | it's tedious removing all the low-quality dependencies from | your project. node security/npm-audit has at least increased | the conversation around security for many around the npm | ecosystem, where there wasn't much-if-any discussion prior. I | think they deserve credit for this. | | EDIT: I'm not sure why I'm being downvoted. | argomo wrote: | Think of the article as customer feedback. The customer may | not appreciate everything the product does for them, nor | may they be using it in the fashion where it would be most | effective. | | So what? Your job (if this was your customer) would be to | figure out how to make them happier. Maybe you are getting | down-voted because (while you're correct on some fine | points), you're broadly dismissing the concerns of the | article. Case in point: those "low-quality dependencies" | aren't something you can easily switch out for quality | parts... they're deep dependencies of many of npm's | flagship tools and frameworks. | z5h wrote: | Seems to me that if you don't have a pure functional language | with tree-shaking, and only including existing (non-generated) | code, you won't know if any (3rd party) code in particular will | be called in compiled output, and you'll just have to guess and | err on the side of paranoia Is there a fix? | preinheimer wrote: | Honestly, this hit me. | | I'm not a react developer, I was experimenting with it for a new | project. I finished the tic-tac-toe tutorial, then tried to throw | bootstrap on top to build from there. It told me there was 97 | vulnerabilities (85 moderate, 12 high)... | | I just deleted the directory and went back to vanilla JS. This is | a fun side project, I don't need that. | | My tweet about it: | https://twitter.com/preinheimer/status/1402785757962592256 | jmull wrote: | FYI, it's probably not react-bootstrap or bootstrap or any of | their dependencies being flagged. It's some of the other ~2K | packages already installed. | alerighi wrote: | That is exactly the point of the article. Every JS developer | knows that these numbers are stupid and doesn't look at them. | | However a beginner that doesn't know what impact they have of | course is scared if when installing a library it tells you that | there are all that vulnerabilities. | IggleSniggle wrote: | As a beginner _just to npm_ I can imagine getting totally | freaked out and worried that my whole system was | _potentially_ compromised after seeing a "Critical" | vulnerability reported as installed on my system. | | After all, npm can execute any script with the users | permissions on install...except often (compared to bash) it's | less easily inspected due to the common use of nested | dependencies! | | I, too, would delete my node_modules, and if I even _wanted_ | to move forward at that point, would probably waste at least | half a day looking up the Critical vulns and discovering that | they are _probably_ not at all critical in my particular | scenario. Like not at all for the 99.99% use case. | | After experiencing something like that, it's just like the | article says. "The boy who called wolf." Really terrible use | of the labels "Critical" and "High". The labels are fine, but | the way they are applied is just stupid. | 1MachineElf wrote: | It's true that the signal to noise ratio is high for much of | these, but whatever solution we settle on, it should take into | account that forcing even beginners to learn how to use npm audit | means that security will be taken into consideration from the | start, which is both valuable and a net benefit. | tonetheman wrote: | Bad/ill formed regexes took down the internet recently so they | are in fact an attack surface | https://blog.cloudflare.com/details-of-the-cloudflare-outage... | mbesto wrote: | > this "vulnerability" is absurd in this context | | Yes that's exactly the point. The audit tool has no awareness of | the context and nor do the people who create severities. | | If severities were absolute then there would be no reason for | anyone to review them. You would simply upgrade your libraries | and be done with it, but that can't always be achieved nor may | make business sense. | | I do agree with the author's note about providing a better way to | provide feedback on severity reviews. | | npm audit is better than no npm audit...telling people it's | broken by design is going to discourage them from using it | completely. smh. | raziel2p wrote: | Exactly. Why does it matter if it's absurd in this context? | Just upgrade it to be on the safe side. Asking vulnerability | databases to judge whether vulnerabilities are safe in | devDependencies or not is a ridiculous idea, even more so when | you consider that the line between static and dynamic have gone | blurry long ago. | nirvdrum wrote: | I don't think anyone should be blindly upgrading anything. | Doing so brings about its set of problems and in many cases | makes things worse. This is particularly true in the case of | Create React App where just upgrading dependencies will often | break the application. | | The last Create React App I worked on (~3 months ago) had | over 500 "vulnerabilities" reported by npm/yarn audit. Most | of the reported vulnerabilities were obviously junk. As the | author noted, there's no need to report vulnerabilities in | the same dependency in every path through the dependency | graph. The noise made it very difficult to sift through the | output for anything useful. Even then, I have my doubts about | how applicable the results are because with tree shaking of | an SPA, it's quite possible the vulnerable part of a | dependency is never even used. | city41 wrote: | > Just upgrade it to be on the safe side | | Upgrading a dependency can go anywhere from trivial to | absolute nightmare. Usually somewhere in the middle where it | takes time and effort to do right. A typical JS app nowadays | has hundreds if not thousands of dependencies. I'd love to | see a world where "just upgrade" is reasonable advice, but we | are not there. | mmis1000 wrote: | Or even undoable because it is a dependency of dependency, | that vulnerable major version is no longer maintained, and | your dependency heavily relies on specific feature of that | major version. | | At this point, what should you do now? | | The author of dependency of dependency is probably not | going to touch it because it is fixed in the new major | version. The author of dependency is probably also not | going to fix it instantly because it requires major | rewrite. | glotgizmo wrote: | Fork the repo and fix it yourself, ideally basing the | change off the fix on the new major version if possible. | | Yes, you now don't get vuln. notifications for the | original repo, which is an issue in itself. It would be | nice to mark a CVE as mitigated in your package.json and | to also mark a resolution to still pick up CVEs from the | original package. E.g | | { "dependencies": { badRepo: | "1.0.0" // has a dependency that is vulnerable }, | "resolutions": { "badRepo/**/dependency": | "git://github.com/org/dependency" // fixed, but now won't | report new cves from the original badRepo/**/dependency | package. Would be good to specify that we still want | reports for the original repo | | } | | That is how we handle such issues in our team, we also | review any forks at the start of every sprint to see if | it has been resolved and we can remove the fork | dependency. | | If the vuln is valid and exploitable in your system, what | other choice do you have? It's the pitfalls on depending | on 3rd party packages. If you are using an old major | version that now has a vuln that is only fixed in a newer | version, NPM doesn't make that situation worse. | | Caveat: These are my 5 minutes thoughts, I could probably | do a better, more thorough write up. | michaelt wrote: | _> Why does it matter if it 's absurd in this context?_ | | If I wanted shitty false alarms about bogus security issues, | I'd get a PCI-DSS audit. | danabramov wrote: | _> Just upgrade it to be on the safe side._ | | A big part of the problem is there is no reliably way to | "just upgrade it" today in npm: | | - `npm audit fix --force`, which is supposed to do that, is | buggy and doesn't work | | - There is no way to override a transitive dependency with | npm (there is with Yarn though, so hopefully this feature | will come to npm soon) | | - Sometimes the fix in transitive dependency _also_ includes | breaking changes (e.g. because it wasn't backported), and so | updating it subtly breaks the logic | | _> Asking vulnerability databases to judge whether | vulnerabilities are safe in devDependencies or not is a | ridiculous idea_ | | I don't think databases can do it, but what I'd like to be | able to do is to be able to provide advisory that the way _my | package_ uses a concrete transitive dependency is not | affected by that vulnerability. Because as the package owner | I _do_ have that context. I understand there may be | significant issues with this approach though! | cphoover wrote: | > _Because as the package owner I _do_ have that context. I | understand there may be significant issues with this | approach though!_ | | But what if one of your contributors slips in a merge that | uses the vulnerable code path of your dependency... Does | this "not affected" marker still exist, and now you have | vulnerable code? Does it disappear with each version? | | What if someone maliciously adds a "not affected" marker? | To a package they intend to exploit? | | Edit: Again why the heck am I being downvoted? | TheDong wrote: | > what if one of your contributors slips in a merge that | uses the vulnerable code path of your dependency | | If your threat model is a contributor submitting | malicious code, your problem is not something npm audit | will help with either way. | | If a malicious actor is able to add the "not affected" | marker, you have bigger problems. | | The threat model you're talking about neither seems | realistic, nor like something npm audit can help with. | The attack vector of a contributor sneaking in malicious | code is dealt with by only giving the commit bit to | trusted people, and reviewing code yourself. | cphoover wrote: | > _The threat model you 're talking about neither seems | realistic, nor like something npm audit can help with. | The attack vector of a contributor sneaking in malicious | code is dealt with by only giving the commit bit to | trusted people, and reviewing code yourself._ | | How is this not _realistic_ when it has already been seen | in the npm ecosystem multiple times. For an example of | this in the wild see the event-stream (crypto-mining | trojan) fiasco: https://github.com/dominictarr/event- | stream/issues/116 | | Dependencies are a target for exploit, your package may | be safe now and then become unsafe in the future, either | intentionally or unintentionally. | enumjorge wrote: | The problem is, if a security vulnerability snaked past | the maintainers of a project, what hope do I have as | someone who consumes the package to a) catch it b) know | how to fix it? | cphoover wrote: | That's exactly the issue that npm-audit seeks to | ameliorate. It's not perfect, but it's better than | nothing. | alerighi wrote: | Have you ever worked with a complex project? Upgrading isn't | easy if you have a moderate number of dependencies, also you | risk introducing bugs for fixing a problem that really | doesn't impact you. It doesn't make much sense to me... | city41 wrote: | I do think he makes a valid point towards the end though. | create-react-app, and projects like it, get a lot of bug | reports about these vulnerabilities. It's a lot of energy | dedicated to something that ultimately isn't that important if | you understand the context. I can understand the frustration. | seemslegit wrote: | I recently implemented my own npm vulnerability audit tool for | the CIO department of a major org - it just adds 'vulnerability' | in red next to any npm-based project in their spreadsheet. | phkahler wrote: | >> Five false alarms wouldn't be too bad. | | >> Unfortunately, there are hundreds. | | This is primarily a result of the absurd number of dependencies | NPM encourages (requires?) people to use. The duplicates are also | there in part because of the large number of dependencies and | should not be shown more than once by the tool. | | Stop building projects with an absurdly large dependency tree, | this is just one problem that results from it. | TechBro8615 wrote: | I'd imagine that in most projects, the bulk of the dependency | is due to dev tooling. I don't think it's fair to optimize for | small dependency trees when setting up your buildchain - | otherwise you're precluding any usage of create-react-app or | Next or whatever development platform. This problem is further | compounded by the fact that those tools encourage including dev | dependencies as regular dependencies, since the output is | compiled anyway. | | The answer here is probably some kind of static analysis to | know which packages end up shipping in the actual bundle to | users. I think Dan referenced some work in that regard. | mcintyre1994 wrote: | It doesn't solve everything, but we use npm-audit-resolver[0] and | it's.. workable. It presents you vulnerabilities, offers to fix | (upgrade the nested dependency) if a version exists that meets | all the constraints, and gives you an option to ignore for a | week/month/forever if no fix exists. Those decisions (including | fixes, which is a bit silly) get recorded in a JSON file in | source control. For each group of ignores we add a link to the | relevant Github issue where it's been reported, so if the ignore | time we chose expires we can quickly go and see what the status | is. | | There are still problems: | | - The decisions file gets unweildy, mainly because every time it | fixes something it writes to the file. You probably only care | about ignores. It's also append only, though you could manually | clear it down sometimes. | | - It always defaults to fixing at the deepest level, which is.. | not ideal for NPM. On my machine (a not very old Macbook Pro) NPM | simply can't update a dependency 20 layers deep in the tree, ie | `npm update nested-dependency-from-hell --depth 20` will | eventually time out and won't fix anything. So you have to | manually crawl up tree yourself and find the thing that can be | updated - or just ignore it until the thing right at the top of | the tree gets updated. | | I'm not surprised to see Dan posting this though. I agree with | everything he said, so I don't mean this as an attack, but a lot | of the time the thing at the top of the tree we're waiting for an | update on is create-react-app. It must be incredibly annoying how | many Github issues get opened on that repo every time there's a | new NPM advisory on some 20-dependencies-deep parser it uses for | something or other. | | I do like the suggested fix that a maintainer can use their | knowledge of the specific usage to say the vulnerability doesn't | apply. Often in these threads there's a perfectly good | explanation of why it isn't a real issue, and then people come | back with "Okay but can you please update it anyway because I'm | forced to audit and my security team/CI are yelling at me". | | [0] https://www.npmjs.com/package/npm-audit-resolver | [deleted] | w3news wrote: | It also has some false results. Like package x has a | vulnerability in version 1.x And you have a private package | @company/x with version 1.x. Than npm audit will blame your | private package, even if you dont have used the original package | x. | AtNightWeCode wrote: | This is how it works by design. | johndoe42377 wrote: | I am Jack's absolute lack of surprise. | xmprt wrote: | Instead of marking dependencies as safe by the developer or by | the end user, I wonder if the immediate parent can mark it as | safe (because it has the appropriate context) and then npm audit | can avoid reporting that "vulnerability" when it sees it. | Pxtl wrote: | I do wonder if a typed language shouldn't have distinct types for | trusted vs untrusted strings and binaries. | gitgud wrote: | Agreed, you shouldn't see low risk security warnings by default, | they're more appropriate for larger projects, with something to | lose. | | The [1] yarn package manager is much nicer to work with in many | more ways. | | [1] https://classic.yarnpkg.com/en/ | unanswered wrote: | TFA identifies "high risk" false positives too, so this | response doesn't seem to have anything to do with them problem | as stated by TFA. | nonameiguess wrote: | It isn't broken by design. I sympathize and understand it's | annoying to have to comb through false positives and mark them as | such, but until a level of AI we're nowhere near being near | exists, you can't automate this process, so the only alternative | is to ignore all vulnerabilities. | | Complaining about this is misunderstanding the asymmetrical costs | of different types of statistical error. Vulnerability scanners | are sensitive by default because the cost of lots of false | positives is annoyed developers who have to slow down their | delivery cadence. The cost of false negatives is anything from | compromising user data to losing your company to bringing down | the power grid of a major city depending on what the application | is. | | Which of those is a higher cost? npm can't possibly know the | answer to that, so it has to default to assuming security | actually matters to you. If it doesn't, your local policies can | be more lax, but don't expect the tool to change for you. | danabramov wrote: | _> it's annoying to have to comb through false positives and | mark them as such_ | | There is no way to "mark them as such". That's half of the | issue. The other half is that many people reporting these | issues have not "opted into" any security tooling and don't | understand its tradeoffs. They just ran `npm install`, and npm | adopted default behavior of showing these warnings. For a lot | of people this is their first programming environment. | | _> you can't automate this process, so the only alternative is | to ignore all vulnerabilities._ | | I don't think the answer is necessarily automation. But as a | package author, I'd like to be able to mark somewhere that a | particular transitive vulnerabilities can't affect my users. | | Or at least I'd like npm to offer a reliable way to update | packages deep in the tree and override the resolved versions. | Currently, there isn't such a way. | eropple wrote: | _> The other half is that many people reporting these issues | have not "opted into" any security tooling and don't | understand its tradeoffs. ... For a lot of people this is | their first programming environment._ | | This attitude makes me kind of uncomfortable. Like, I have | taught software development to a decent number of folks, but | I've always done so in a relatively isolated environment. If | one is buying into web programming, I have a hard time | feeling like it matters that it's their first programming | environment--it is a hostile place (the web) and some | understanding of that hostility is pretty high on the list, I | think, of Things To Get Used To. There's definitely a tension | there with "don't overwhelm a novice", but I don't | necessarily think optimizing _for_ the novice case is wise, | especially when we want those novices to have their heads on | a swivel, too. | | _> But as a package author, I 'd like to be able to mark | somewhere that a particular transitive vulnerabilities can't | affect my users._ | | I definitely agree with this, though, and this is a good way | to help make something like `npm audit` more intelligible and | useful. | watwut wrote: | Frontend is however typical first place to develop in. And | backend should never trust frontend anyway, making frontend | actually lower risk place. You will hack yourself | basically. | eropple wrote: | _> Frontend is however typical first place to develop in_ | | I think that, even today, this is a bold claim to make. | Do you have something to substantiate it? | schneidmaster wrote: | > This attitude makes me kind of uncomfortable. | | I think the point though is that security warnings need to | be actionable and high-signal. Experienced folks are | absolutely tuning out the security warnings on npm install, | because 95% of the warnings are like the examples in the | post -- I know they don't affect me/my use case and there's | nothing I can do about them anyway. The effect is only | compounded for novices who run "npx create-react-app hello- | world" and immediately see something incomprehensible about | a vulnerability in react-scripts > webpack > watchpack > | watchpack-chokidar2 > chokidar > glob-parent. It either | discourages them from programming entirely or it teaches | them to ignore security warnings. | | I don't disagree with your overall point -- e.g. we should | absolutely teach novices "here's what XSS is and how to | avoid it" early and often. But if a dependency manager is | going to surface a vulnerability alert every time I install | dependencies, the alerts should be 1) high severity (to the | point where I should actually stop using the package if I | am unable to patch/upgrade) or 2) at least immediately | actionable. The current npm audit implementation does the | opposite -- 95% of the alerts are totally irrelevant to my | actual security posture, and the suggested command to | upgrade a vulnerable dependency is unreliable and can | actually downgrade to an older, even-less-secure version | (!). | three14 wrote: | The alternative is hiding most of the reports by default. It's | a firehose, and almost all of it is guaranteed to be useless. | For example, denial of service in a devDependency shouldn't be | shown unless the user specifically requests it. Denial of | service shouldn't be marked "high" importance, even though | occasionally it might be quite important to some user. | bogota wrote: | That is not the cost of false positives. The cost of false | positives is ignoring it completely. I have had jobs where we | just block the security scanners because they won't listen to | any feedback about why what they are scanning was intentionally | setup for the purpose of testing vulnerabilities on an internal | only network. Additionally at other jobs security tickets just | start to get ignored because they send too many tickets that do | not matter. I feel the security field likes to ignore most | feedback and play holier than though. At all companies i worked | at i have only had one good security team that worked with | people instead of just throwing things over the wall. | cratermoon wrote: | I agree about the false positive problem. Boy who cried wolf | and all. I've also worked with security vendors who offer to | run "free" vulnerability scans for you, and to absolutely | nobody's surprise, they find vulnerabilities that just happen | to be the ones that they can fix, if you buy what they are | selling. | | Still, your example is problematic. Beware the "internal-only | network". Such a thing has mostly lost meaning today, and it | was never much more than a picket fence anyway. "All devices | must be capable of maintaining their security policy on an | un-trusted network." https://collaboration.opengroup.org/jeri | cho/commandments_v1.... | watwut wrote: | The issue was "intentionally setup for testing purposes". | cratermoon wrote: | What testing purposes? How long was it up? Without | knowing more, that doesn't eliminate it as a problem. | There are plenty of cases where something set up "just | for testing" ended up being the entry point for | attackers. | dale_glass wrote: | It's a tricky problem to solve. | | Ideally you'd want to show only relevant alerts, but... how? | You'd need to know which kind of errors are relevant for a | particular project, but that'd require solving the halting | problem. This is made much worse by that it's JS. | | Some libraries have an enormous complexity and attack surface. | Take a database interface -- there probably is a vulnerability in | some obscure corner the typical person may not even know exists. | | I think though at the very least some improvement could be made | by better priorization and categorization. DoS by exploiting a | regex parser isn't that big of a deal if your project is just | getting started, but an exploit allowing arbitrary code execution | would still be. | scottfr wrote: | You just need a way for a package maintainer to flag a | vulnerability in a dependency as a non-issue that does not | affect that package's use of the dependency. | | In Dan's twitter thread, he calls this out as a viable | solution. | minxomat wrote: | You don't have to go all out doing exhaustive dynamic analysis. | Data flow analysis gets rid of 99% of the most popular bugs | (injection, validation, defaults, etc.). GitHub CodeQL can do | this, and produces much better results than any static analysis | tool I've ever used. Feeding this data back into npm (owned by | GH) is just the next step. | Macha wrote: | This is a general problem with many security scanning tools, and | when a security team is empowered to give deadlines to fix any | issue they report, leads to much frustration and poor relations | in teams. | | Imagine if you had 3 days to fix the regex DoS issue shown there, | screw your release freeze and your current sprint plans, and you | have the real working environment in some companies. | | I've also heard reports of people trying to claim bug bounties | for similar reports, or security vendors that run automated tools | that detect for issues of similar (lack of) value. | _jal wrote: | Among other things, it illustrates the insufficiency of a | single numeric value for assessing 'badness', which in turn | masks a management issue. | | CVEs try to supplement with flags for remotely exploitable, | etc. but it still intentionally leaves a lot of space for | interpretation, which is necessary for any normal enterprise. | | The problem comes in when analysts (or their managers) | interpret inflexibly, without appropriate technical context, or | without understanding business impact and tradeoffs. | | If you look at the workflow, it is hard to close the loop from | engineering or IT back to security. We need a set of controls | for secops departments' output relevance and departmental | interoperation. | killion wrote: | I like his point about `npm audit --production` being a good way | to cut down the noise. But Github doesn't seem to take dev | dependencies into account when sending security alerts. I get | emails about non-issues from them all the time. | dean177 wrote: | It is just pure noise: Add `audit=false` to your ~/.npmrc to | disable it | gampleman wrote: | We basically run it in CI... and then allow it to fail without | failing the build. -\\_(tsu)_/- | | It seems like a lot of this has been designed for Node (backend) | development, whilst ignoring the fact that NPM is probably used | more heavily for front-end development at this point. | mmis1000 wrote: | Yep, some vulnerable package isn't even in the compile output. | How a dev server that only binds to 127.0.0.1 a serious DOS | problem? Who on the earth will want to DOS that? | [deleted] | aerojoe23 wrote: | It sounds like npm needs a mitigated and irrelevant flag, these | flags should include an explanation field. Security teams would | also have to accept this as a solved/fix status. | | For projects you own you'd have to flag each dependency path | though, because for example, one dependency may not have the | input for the regex exposed to the end user, while another | dependency could. | | Maintainers of libraries should also flag the security issues, | and an issue with these two statuses on them wouldn't be raised | by default. Options should be available to list them though for | auditing. | | For more security critical teams/projects, a per project setting | to alert about any issues the maintainers have flagged irrelevant | or mitigated and you'd have to accept them before it it would | stop alerting about them. | efitz wrote: | Writing my comments in the snarky tone of the article. | | So the article boils down to "a bunch of these vulnerabilities | aren't applicable to my app which is built using a specific NPM | package". | | Congratulations. Welcome to the world of practical information | security. | | As a security engineer, we're lucky if your favorite package | manager even associates vulnerability information with your | packages. Never mind that you're pulling in code at build time | from who-only-knows-where that almost certainly wasn't security | reviewed. But that's for another post. | | Now you have a package manager that is kind enough to tell you | that there might be a vulnerability, and you're upset because NPM | did not have specific logic to understand the mechanics of one of | the packages it manages? And the upshot is that you have to apply | judgment and attention to each notification? Is that a tear in my | eye- no, wait, it's just an eyelash. | | How many packages are there? I'm sure the NPM guys have nothing | better to do than to build context awareness for every package in | their repository. | | In all seriousness, I would love to see context awareness in | vulnerability reporting. But expecting a package manager to | understand that because of your specific choice of framework, | that the DoS could only be conducted by an admin of your app, | seems unreasonable to me. | kaishiro wrote: | As a security engineer, do you feel like the addition of npm | audit is a net positive for the security of the npm ecosystem? | Touche wrote: | Typical security engineer opinion. This "feature" is costing | the industry tens, perhaps hundreds of million of dollars in | wasted salary hours but it's worth it to you in the off-chance | .1% are even potentially affected. Because only your job | matters. | overgard wrote: | The point is that if the feature is going to constantly produce | false positives, it's useless. I concur with the author, I | never check those warnings anymore. | lxe wrote: | I agree with the author. Just like them, I only write code | without any bugs that can be affected by the "vulnerabilities". I | also never commit to upstream so others won't be able to edit my | code. All my projects only run on my machine (which is of course | also absolutely exploit-free and it's not connected to the | internet). | cratermoon wrote: | You're being snarky, which is fine, but the author addresses | that. If you're compromised, the attacker is not going to dig | through your development folder to inject a regex that makes | your build slow. They'll exploit privilege escalation bugs to | install a bitcoin miner, ransomware, a DDOS bot node, or use | some other vulnerability to grab and/or exploit your secrets. | They'll do it the most direct way possible, not via some half- | broken regex parser. | klodolph wrote: | Difficult problem to solve. It seems like the reasonable solution | here is to have auditing integrated with the build system--but | there are so many wacky build systems for JavaScript. | _fob_ wrote: | Indeed, npm is not aware of the context of the vulnerabilities. | That does not invalidate them, however, and mean they should be | hidden. I've worked in offensive security for quite long enough | (been a dev for 10+ years before) to tell you that your context, | or the most common one, isn't all that exist and someone's going | use it the way it makes the app vulnerable. Based on the | article's example, someone's going to build an app that builds an | app. | | A vulnerability is a vulnerability, whether it applies to your | context or not. A metaphor might be: "The passenger door is | broken on my car, but I'm the only one to use it". Seriously, | who, in their right mind, is going to argue that the door isn't | broken? | | - If your dependencies have security vulnerabilities, apply the | updates. | | - If you cannot update because there's no fix available, let your | org or you assess the risk and go from there. | | - If you cannot update because it breaks your app, {find a | replacement, fix it yourself, let your org or you assess the risk | and from from there}. | | A sensible org has a process that freezes releases until known | security issues are fixed. Freezes can also be opposed by devs | and are evaluated on a case-by-case basis (because sometimes they | are not relevant to the product, or someone steps up to take the | blame for incidents and the org agrees). | | We might not like it because it disturbs the "flow", but it's | just part of the engineering process. More to the point though, | why not take this opportunity to teach newcomers how to code | properly, pick well-engineered and -written programs, and handle | this vulnerability management process altogether? In any case, I | hope newcoming-dev is not going to push to prod anytime soon. ;) | | edit: formatting | bscphil wrote: | > A metaphor might be: "The passenger door is broken on my car, | but I'm the only one to use it". Seriously, who, in their right | mind, is going to argue that the door isn't broken? | | I think a better metaphor might be, the button on your key fob | that opens the trunk doesn't work, so you have to open the | trunk using a physical lever. Every time you start the car, a | loud warning siren sounds, and a red message appears on the | dashboard to tell you that there is a "high impact" problem | with your car, and you need to take it to be serviced. If you | were merely the owner of the car, and other people also had to | drive it, you might understandably be the target of several | complaints about this "high impact" problem. | hsbauauvhabzb wrote: | I agree. | | Ever seen apps which are basically impossible to patch because | devs have ignored patching for so long that it's basically | impossible to version bump things sanely? I have. | three14 wrote: | A lot of these cases that npm reports are denial of service | vulnerabilities (and marked high risk!). I just tried it on a | project I have, and 11 out of 15 are DOS vulnerabilities in | code that I run locally. When the normal user is using a | project only locally, and the issue is DOS, it's hard to argue | "but maybe someone will eventually put it online" and therefore | I need to drop what I'm doing and patch my dependencies. (Yes, | sometimes that would be the only way to satisfy npm, since the | semver rules prevent it from fixing things automatically.) | planb wrote: | Funny. I had a discussion about the same topic in context of | docker image security scanners last week. 100% agree with the | author here! | j1elo wrote: | I guess we could have a documentary series! | | Next up, _npm link: broken by design_ | | Synopsis of the chapter: _A command with broken behavior that has | been reported since as early as 2015, but that "got lost" every | time the winds changed and the project decided to change where to | manage bugs. What will happen in the latest attempt from an | affected user? Tune in and be ready for an exciting ride!_ | | https://github.com/npm/cli/issues/2372 | | Spoiler: bugs are not sentient beings that solve themselves just | by closing the issue (or the whole issue tracker, for that | matter). | | EDIT to clarify: Sorry for the snarkyness. I just find it funny | in a sarcastic way that up until I reported the issue in 2020, | the issue had been reported repeatedly but "lost" in the way | because the project closed or ignored the issue every time it | changed issue tracker. Which happened _twice_ since 2017! so go | figure the amount of reports that had gone to waste. On the flip | side, this time they haven 't changed platforms (yet), although | the issue has been closed prematurely anyway. | mikewhy wrote: | Funny, because Yarn does do what you expect here and I | absolutely loathe it. | datavirtue wrote: | Agreed. I have been trained by npm to ignore its audit messages. | quaffapint wrote: | As mentioned in the article we ran into the same overload and | just ended up running `npm audit --production` as part of our CI | pipeline since that's what would be going out. | solatic wrote: | > Inlining dependencies kind of goes against the whole point of | npm | | I mean, this is why people love language with deep, solid | standard libraries. You don't have a situation where a problem in | a sub-sub-sub-sub-dependency provokes five different groups of | people to all issue an update, one after another. You just | upgrade your underlying installation to the latest patch version | and continue. | | Language ecosystems where a few lines of code constitutes a | library _fundamentally_ result in you being dependent on a huge | number of outside people to cooperate on updates. _That 's_ | what's broken. Not a tool which tells you that you have out-of- | date libraries and, by the by, hooks into CVE databases. | | OP should stop and consider whether it might be beneficial to | inline some of those dependencies before dismissing it out-of- | hand. If you never use the dependency in such a way as to present | a real security risk... and you don't need feature updates from | upstream, i.e. the software is fine as-is when you first | incorporated the dependency... then why wouldn't you inline the | dependency? | | If anything, inlining the dependency will allow static code | analyzers to point out all the parts of the dependency which | you're not using (i.e. dead code) and eliminate it all. That way, | even if the dependency _were_ to be discovered to have a security | fault, if the faulty code was in a section that you eliminated as | dead code... then you don 't have a security problem in the first | place! | akoumjian wrote: | The interaction is not the worse thing about npm audit. The | security model of the tool has a big hole depending on how you | use it: https://mulch.dev/blog/CVE-2020-5252-python-safety-vuln/ | | In essence, if you are scanning an environment that is already | compromised, `npm audit` results can't be relied upon if you are | running it in the same environment. It should be self-evident but | I'm sure plenty of people use the tool this way. | jrochkind1 wrote: | > Inline all dependencies during publish... From a maintainer's | point of view, the upsides are clear: you get faster boot time, | smaller downloads, and -- as a nice bonus -- no bogus | vulnerability reports from your users. | | And when you inlined a version that later _really does_ have a | vulnerability, it is not easily flagged or fixed by your | consumers. | | The tension between "upgrades (especially of indirect | dependencies) might break" and "upgrades (especially of indirect | dependencies) might be necessary to fix bugs or patch security | vulnerabilities" is real. There is no magic bullet to get around | it. There are practices to try to balance it -- which generally | involve ecosystem-wide commitment to backwards compatibility, | reflected in semantic versioning (and minimizing major releases). | | That npm dependency trees are often _insane_ doesn 't help | though. I'm not totally sure why they are so insane, but I | increasingly think that npm's ability to have _multiple versions | of same dependency_ in the dependency tree -- often seen as a | huge advantage over other platforms -- is in fact part of the | problem. It makes the dependency tree even more insane, and it | also accomodates a false belief that it 's fine to lock to very | specific versions of dependencies -- because it won't prevent | other dependencies from co-existing in tree with other | conflicting requirements after all. Which then accomodates a | false belief that dependency maintainers don't need to worry too | much about backwards compatibility, after all consumers can just | lock to specific working versions... and now we wind up with | insane dependency trees which depend on vulnerable versions in | ways that require a whole bunch of releases to resolve. | twistedpair wrote: | > That npm dependency trees are often insane | | For my hundreds of repos (Java, Scala, JS, Typescript, | Python...), Snyk flags 99% of the CVEs for the JS repos. | Shocking how I've only seen a few dozen or so Java based CVEs | flagged over the last few years. | | Perhaps it's because my NPM based repos have ~10K more | dependencies? That and the Java stdlib handling most needs w/ | the vanilla lang. | bscphil wrote: | Well said. | | I would add that I think the devDependencies solution is | underrated. Not using it is a bad practice. npm has a nice | feature, `npm prune --production` which will remove all the dev | dependencies for you resulting in a clean build of the program. | You can easily have things set up so that none of the | development dependencies that have all these audit issues are | _ever_ present on your production machines if you do things | right. | | Furthermore, if you have a project with end users, | devDependencies allows you to make clear in your issue template | that audit issues that don't show up in a production build are | very likely to be false positives and will probably be closed | without comment. If you aren't properly isolating your | dependencies, you can't take advantage of this. | | At the end of the day, as you say, the issue is largely with | Node projects having too many dependencies and a large number | of relatively minor issues that affect very specific use cases | get reported. That's a hard _ecosystem_ problem to solve, not | necessarily something that indicates an inherent problem with | npm audit; but if someone isn 't using devDependencies, that | alone could constitute an enormous improvement in their | workflow. | Vinnl wrote: | If there's a vulnerability in Webpack (a devDependency) that | injects malicious code into your bundle, `npm prune | --production` won't save you. | remram wrote: | This is not a vulnerability (ie. security bug) it's an | attack (ie. malicious). | tshaddox wrote: | > That npm dependency trees are often insane doesn't help | though. I'm not totally sure why they are so insane, but I | increasingly think that npm's ability to have multiple versions | of same dependency in the dependency tree -- often seen as a | huge advantage over other platforms -- is in fact part of the | problem. | | Aren't npm dependency trees so large because JavaScript doesn't | have much of a standard library? And also, similarly, the | community is so large and has been moving so fast that even _de | facto_ standards have difficulty forming and surviving at a | large scale across the community. | zelphirkalt wrote: | Big part of the insanity is also how projects introduce | dependencies for very simple things like padding a number or | a string. | HideousKojima wrote: | https://www.npmjs.com/package/is-odd | | 447,211 weekly downloads for what can be done in vanilla JS | with foo % 2 === 1; | Ayesh wrote: | Which itself depends on is-number package. | zelphirkalt wrote: | You and GP have shown me new even more scary depths here. | Not sure whether I should thank you for that. (When does | the next flight off this rock go?) | tshaddox wrote: | It's not really that crazy. This package is a small | amount of code, but it's important code (the same goes | for this package's dependency is-number). This package | shows up in the dependency trees of some popular | packages, which is probably where most of the weekly | downloads come from. | | If you're writing straightforward application code where | you already know you have a valid number, then this | package probably isn't for you. You can just do num % 2 | === 1. | zelphirkalt wrote: | I get it, JS is a weird language, but simple things like | "is number" are still easy enough to do in JS, | especially, when ints and floats are all just "number" in | JS: | | function is_number(val) { return typeof val === "number"; | } | | With a function that easily written, no one should have | any excuse to depend on a third-party dependency for it. | tshaddox wrote: | But the code you posted is not what the code in this | package does. If all you need is the code that you | posted, then you should absolutely use that. | LadyCailin wrote: | leftpad was a small amount of code too. If it's a small | amount of code that's design stable and downloaded often, | it's an extremely strong candidate for inclusion in the | standard library. | handrous wrote: | The lack of static typing (in base JS, at least) also makes | it hard for tools to automatically spot very basic brokenness | in dependencies without (repeatedly) running & testing the | code. This makes even "safe" version bumps less trustworthy | and harder to audit, and makes it harder for developers to | notice if they've accidentally changed an interface on one of | their libraries that they marked as a minor patch (i.e. the | errors are both harder to check for, _and_ more likely to | occur, basically _because_ they 're harder to check for), so | it's tempting to stick to old versions longer. | | Add to that everything else--the fast pace of changes, | javascript "culture", the weak standard library, the tendency | to patch in what ought to either be basic language features | or else avoided in favor of more-vanilla idioms, often in | competing and incompatible ways--and all that is how you end | up with 20 slightly-different copies of the same damn library | in your dependency tree, and then 20 other copies of another | library that does the same thing. | theptip wrote: | > I'm not totally sure why they are so insane | | I think a big part of it is that due to much stronger pressure | on bundle size than most other environments, each library tends | to be small, so there have to be more to carry the same amount | of functionality. | | Duplicates are certainly a contributing factor as well, and | small bundles compound with allowed-duplication to further | increase the tree size. I think that small package size also | probably makes it harder to require a single version for each | dep, since there are going to be more edges in the graph and | therefore more relations for library maintainers to keep track | of (including what would in other languages be intra-package | requirements), so you're more likely to get version | incompatibilities. | munificent wrote: | I agree with all of this. Also JavaScript's "standard | library" is nearly nonexistent (or at least was when Node | first got big). That built a culture of people assuming they | needed to reach for third-party dependencies for nearly | everything (see: leftpad). | enumjorge wrote: | Slightly related to the lack of a standard library is that | a lot of these 3rd party packages come from random people | in the community. It's great that people are so willing and | able to share code, but it also means that as a community | we put a lot of trust into code that may not be vetted or | funded properly. I think we assume that because these | packages are open source that someone is making sure they | are safe to consume, but because there's so many of them | it's hard to verify them. | ipaddr wrote: | You only support corporately funded open source? | enumjorge wrote: | That's not at all what I said. C/C++, Python, and Rust | are examples of languages that are not owned by a single | company yet they are funded enough to be able to provide | a stable standard library. | riho wrote: | The the main problem is the fact that this audit happens with no | context, and the audit results offer no information about the | context an issue applies to either. Every issue should have a | clear explanation about why and where it's an issue, and be | tagged. Then we'd just need a way to hint npm what context a | package will be used in, similarly to what we already do for | devDependencies. | | Also going through an audit result in a CLI isn't really the best | experience. I wish I could just click a link and open up the | report in a browser to drill down into issues. | hsbauauvhabzb wrote: | No it's not. The main problem is the dependency tree hell. If | an ancestor version bumps, you should probably version bump | too, irrespective of exploitability. | | Don't like it? Try using more maintainable dependency trees. | trunnell wrote: | A lack of imagination by the author, unfortunately... | | A DoS on your build machine and dev machine can be indeed be | critical issues. Imagine this scenario: | | Your source code is somehow compromised and attackers slip in | rogue code to your production site. It siphons off passwords or | other PII. The attackers also take advantage of several of these | RegEx DoS vulnerabilities to prevent you from quickly fixing the | problem. When you discover the issue, you'll first see that your | build machine is unresponsive, so you can't just spin a fixed | build and re-deploy. You'll sync your main branch to figure out | what is going on, perhaps ready to make a build from your dev | machine, but running yarn build hangs. It might take you 1 minute | to solve or 5 hours - hard to guess. But every minute you're | delayed is another minute the attacker is siphoning off your | production data. | | npm audit isn't perfect, but I don't agree with the author that | devDependencies can't have critical vulnerabilities. Build | machines and dev machines _are_ critical infrastructure. Recall | the method of attack of SolarWinds [1]. | | Related: we all trust that the "many eyes" of open source | contributors will keep our dependencies relatively clean, but | this function is not infinite. There is some threshold of lines | of code and rate of change that will outstrip the community's | natural ability to find and fix problems. I wish the npm | community was more sensitive to the risks that are inherent in | current practices. Efforts to limit dependencies and perhaps | somehow tag which versions have completed a security audit (and | by whom) would be great to see. | | [1] https://krebsonsecurity.com/2021/01/solarwinds-what-hit- | us-c... | askmike wrote: | > Your source code is somehow compromised and attackers slip in | rogue code to your production site. | | Really at this point it's too late to do anything else, instead | of trying to dos your dev machine he can instead do simpler | things like delete your ssh key from the machine. But let's | play along: | | > The attackers also take advantage of several of these RegEx | DoS vulnerabilities to prevent you from quickly fixing the | problem. When you discover the issue, you'll first see that | your build machine is unresponsive | | There is nothing any attacker can do with the static files on | the server that will trigger and RegEx DoS in your local | development. Aside from the fact that you wouldn't download | whatever is on the server back to your machine, even if you did | it would never trigger such a DoS since (in the examples in the | link) these are modules related to running a dev version of a | frontend project based on the raw source files. | | Your scenario is only true when an attacker pwned both your | production server and your laptop. A regex DoS is really the | last thing you worry about at that stage. | trunnell wrote: | I see your point that even worse things can happen when dev | machines are compromised. The point I tried to make is that | even a DoS of your machine can be a big problem. | | > There is nothing any attacker can do with the static files | on the server that will trigger a RegEx DoS... | | IIUC, an attacker could change my package.json to include | inputs to browserlist that trigger a RegEx DoS. To do that, | the attacker only needs to make a fraudulent commit. Given | how easy most teams make it to commit code, this isn't too | high of a bar. | nirvdrum wrote: | If you, as an attacker, are going to make a fraudulent | commit and change package.json, you could just pull in a | bogus dependency or add a new script/command that gets run | on the build/dev machine. I agree the bar to submitting a | fraudulent commit is unfortunately too low for many teams. | But, this also extends to package publishing, too. | | We've seen packages published through compromised dev keys | or the maintainer granted a new bad actor rights to | publish. Here we could envision a situation where someone | reports a legitimate, but low impact, security issue and | also publishes a bogus package that everyone is now | upgrading to. On the whole, these messages aren't | encouraging people to upgrade to a new, verified release | (i.e., a fixed version). They're encouraging people to | upgrade to the latest release. Even if you suspend the bad | actor thought experiment, the latest release of a package | in all likelihood hasn't been audited beyond ensuring the | previously reported security issue has been addressed. | Upgrading indiscriminately is a risky activity as well. I | don't think we should be encouraging people to do that (in | any language ecosystem). | | It's not lack of imagination of attack vectors at play | here. Treating extremely low risk factors as if they're | high priority reduces trust in the system as a whole. | Getting developers to care more about security is a | laudable effort, but I think the `npm audit` approach (as | reported in the post) is going to encourage bad practices. | trunnell wrote: | I agree with all of your points except for the very last | one. | | Are we shooting the messenger (npm audit) here? Seems | like the problem is lack of trust and lack of information | about security of dependencies. Npm audit is just | pointing that out. The size of the problem makes it very | uncomfortable. | dj_mc_merlin wrote: | 1. You wouldn't wait for a full build in that scenario, but | deploy a known-good last image or emergency shut down. | | 2. If you are doing a full build and fail because of the regex | DOS, then that build would also contain the attacker injected | siphoning code, which would make your entire exercise futile in | the first place | | 3. Not obviously messing with the network or crashing build | machines would be a better way of siphoning data for longer. | | 4. This is very contrived. | smsm42 wrote: | I think if the attacker got as far as deploy their code in your | CI/CD pipeline and prod system, there's no "quickly" fixing it. | There's a full shut down, restoring from trusted backup, full | data and code audit and a lot of pain in the future validating | and restoring the code and the data. Quick rebuild is not | something that would be your priority there - how do you know | this quick build won't be compromised anyway? If somebody got | into your internal systems on the level they could modify the | code, it's not a 1 minute problem and not a 5 hours problem, | it's much bigger... | trunnell wrote: | I think the typical scenario is that you understand how big | of problem it is only in retrospect. | | In the moment, your first thought is that there is some type | of quick fix that will restore functionality (if your site is | down) or evict the intruder if something funny is detected. | As a sibling commenter said, most teams would try to deploy a | previous known-good build asset. | | But I stand by my point that a DoS of a development system | can indeed be critical! I'm surprised to find that I appear | to be in the minority here... | cerved wrote: | the machine doesn't need to be compromised, just check it into | source control | est31 wrote: | I think this is a really great article and highlights an | important weakness that modern security tools in this context | have: they don't distinguish between vulnerabilities that can be | triggered by malicious developer code, and vulnerabilities that | can be triggered by malicious users/websites. | | For a proper assessment, such differences need to be encoded in | the security advisory, and the audit tool needs to analyze if the | code is called at run time or build time, and then act | accordingly. | ur-whale wrote: | This should be: npm: broken by design. | | Or even, since it's in fact the language itself that sets the | tone for the entire ecosystem: javascript: broken by design. | littlecranky67 wrote: | I've been saying this for years, especially to useless "prototype | polution" notices being reported by npm audit. In a project where | this "pollution" only happens on the nodejs side in our build | tools, they are meaningless if our output is a browser JS bundle. ___________________________________________________________________ (page generated 2021-07-07 23:00 UTC)