Security concerns with minified JavaScript code
lists.debian.org
lists.debian.org
I'm sure there are some additional gains to be made from knowing the syntactical structure of the language you're minifying, since no generic compression scheme can know that. But that seems really marginal — and, as the article in question shows, opens up potential security vulns.
Most here are talking about uglify which does very superficial minimization, but Google's closure compiler is in the mix too, and that provides static type checking, nested variable flattening, dead code removal, inlining optimizations, and more. These things are substantial, not marginal, especially the static type checking. It's closer to C++ compilation than it is to gzip.
Gzip can be used (and usually is) either way, and generally still has some benefit even on minified code. But no, gzip can't replace or provide the majority benefit of a minification pass, they're two mostly independent things done for mostly different reasons.
if you use Closure Compiler in Advanced mode it will rename and rescope pretty much everything except native methods and strings (making lots of globals cause it assumes you're compiling all page's code at once), it will eliminate unused code even from third party libs like jquery and do all sorts of stuff that make the beautified code very expensive to understand, follow and reverse and even then you may end up with only half a library that does only one specific task and the rest of the code would be missing.
you have to do a bit of JSDoc annotations in some places to fix some breakages and restructure the code a tiny bit to get it to rename absolutely everything but the results are excellent.
To have that sort of optimisation you'll have to run the Closure compiler with ADVANCED_OPTIMIZATIONS enabled. Last time I checked that mode of compilation didn't work with JQuery and not with most other libraries. To use it with your own code you'll have to follow certain rules.
I think most people just use uglify or the Closure compiler in SIMPLE_OPTIMIZATIONS, neither of which does the very advanced stuff of ADVANCED_OPTIMIZATIONS.
All you will get is a lot of function a with arguments z d and f calling eq on z and passing it d, then returning the qln value of the result.
Slightly more readable, yes, but still like debugging assembler.
even so, there's nothing it can do to bring back eliminated code, meaningfully extract inlined functions and scope everything appropriately to help a reverser understand context. it would still take an immense amount of effort only to get back something very specific.
the only thing you can probably get out of it is some largely mathematical chunks that cannot be restructured much, eg: rgbToHsv.
There is a lot to minification, these tools just undo cosmetic minification.
If it can infer most of it from OSS? Sure. But big web apps do a lot more.
For React-Native for example, I've heard people going from 15fps animation to 60fps when going into prod (!). I always tell them to benchmark their animation on the prod build, because dev build is _not_ representative of the perf you get.
Granted, it doesn't necessarily need to be the minifier's job. But that's the way things are currently done in JS.
If the minifier provides that much more incentive for helpful error messages then I'm all for it. It has helped us avoid a huge amount of duplicate questions when people start with React too. As a matter of fact, I think most libraries should adopt this approach for this feature alone (Webpack makes this process less of a hassle, but we can do better). Otherwise you'd be caught between inserting expensive checks and not inserting them out of perf concern, which would be a true premature optimization.
What would be more interesting is to see the results of the different minifications. E.g. how much you get from simply removing comments and whitespace? How much if you also rename variables? There might be diminishing returns (and increased security risks) if you go further than those two simple and "safe" improvements
When you are working on a large engineering team with lots of JavaScript volume written by a lot of different people, the dead code elimination alone is worth it; it means you can use one function from a library with millions of lines and your compiled JavaScript will only contain that individual function rather than many megabytes of unused code.
It's the same story compressing other material. 7-zip has filters to preprocess x86 and IA64 machine code to make it more amenable to LZMA, and such filters can get you a further 10-15%.
1. Gzip is not free. You would have to perform it on every single request. That costs money. Minification is a one time thing.
2. Gzip does not strip documentation.
3. Gzip, as you mentioned, cannot do language specific compression. So if your code is written poorly and can be better written with a closure, Gzip won't do that for you. Proper minification will.
4. Gzipping minified code is cheaper than gzipping non minified code.
5. Minified code uses lesser breadth of variable names and literals. This makes for more efficient Gzip.
As others have mentioned - Gzipping gives around 50% compression, full minification around 70%, and both combined around 80-90%. So if you go whole nine yards, you can save 40% extra on bandwidth. That could equate to thousands of dollars in saving every month for even a moderately famous web app.
The argument here is why not simply use gzip and not use minification at all.
Do it once and cache.
Minification - combination of bandwidth savings and smaller code
Remember that Javascript on the client must run once per page load / per script inclusion. The larger the code, the more that must be parsed and executed.
Minification probably had more of an impact before Chrome+V8 when JavaScript engines competed to become extremely optimized. I suppose now most vendors have some sort of in-memory cache for recent scripts feature which would vastly reduce the average script execution due to the need to parse less frequently.
When you already have a pipeline like gulp or grub (and if you are developing JavaScript, you should), adding minification is just one more line of code. So, why not minify if it doesn't represent any effort and it could mean better performance? Also, usually, developers don't have access to the production webserver.
Most of the time, people are to busy to analyze all the pros and cons of every action they do.
Said that, if Debian is an open source OS, then yes, they should have access to the unminified code of the applications they include. Or, at least, the sourcemaps.
* As you mentioned, you get most of the benefits from gzip compression. * You pay a major debugging penalty for having your code minified, since it's much harder to figure out what happened with minified code. * After the first request your code is going to be cached locally, anyway, so we're only talking about the initial request. * Using a CDN for your libraries will buy you much more. It's not 100% relevant, but if you're worried about download speed, this is one thing that does make sense.
Related article I found: http://engineeredweb.com/blog/why-minify-javascript/
Minification was used on those systems because the space savings resulted in performance improvements.
Deminification would be less of a security concern than potential issues being introduced by minification.
> To me the problem suggests that it is important from a security and
> accountability perspective to 1) include the human-readable source
> code of JavaScript in Debian packages, and 2) to compile the
> human-readable source code into a minified code (if required) during
> package builds, using a JS-minifier that is included in Debian.
> Thoughts?
This is anyway mandatory in Debian.
https://lists.debian.org/debian-devel/2015/08/msg00478.htmlI wonder... I'm assuming their concern surrounds stuff that is installed on-disk with the package manager. Is there any benefit at all to JS minification when the file:// protocol is in use? Marginal (if at all) improvements to parse time? Anything else? Or is "everyone doing it?"
It is a terrible way, but you can't complain that it's a lot faster than rewriting V8 to count nodes.
Node has pretty much become the standard for dealing with client-side assets in projects.
More problematic is that nodejs isn't available on all Debian architectures, due to lack of V8.
I'm mainly echoing concerns that were in play when Mono had been gaining a little traction, and as an example a few useful utilities were added to Ubuntu's release, bringing in a large runtime... in this case it's not quite as big, but node_modules can get a little big depending on what you're working on (much better with SSD).
"If a JavaScript library typically is shipped as minified or compiled code, it must be compiled or minified as part of the RPM build process. Shipping pre-minified or pre-compiled code is unacceptable in Fedora."
http://pkgs.fedoraproject.org/cgit/roundcubemail.git/tree/ro...
https://wiki.debian.org/onlyjob/no-minification
One argument that really drives it home -- GZIP compression without minification is faster and better, and from my own experience takes exactly two lines of nginx config to set up.
Is there really any benefit of using minification besides code obfuscation?
That's just a minor point but it can help with speed. Is it enough of an optimization that it's worth it though? I'm not sure; I haven't seen much in the way of benchmarks in this area.
if (process.env.NODE_ENV !== 'production') { invariant(x, y); console.info(z); }This might be a good candidate for having the link updated.
Now, you compile your code with this compiler, and if your own build reproducibly has the same results as this verified compiler, you're safe.
My solution even protects me from attacks where the source of the minifier is safe, and only the minified minifier contains the bug.
You are thinking of another kind of backdoor than the one being discussed. The backdooring technique being discussed relies on a compiler bug hidden in plain sight in the compiler's source code. It has not been sneaked into the binary with a “trusting trust”-like technique. The bug is just an ordinary compiler bug, you do not need to be the one who put it there, it can be a known, published bug and have already been fixed in the compiler's development version (although you can also have found the compiler bug yourself and have omitted to report it for maximum sneakiness).
Re-compiling the compiler does not make the bug go away. Compiling GCC with TCC does not fix bugs in GCC (otherwise people would be doing it more often).
Compiler have bugs, and some of these bugs cause them to silently emit the wrong assembly code for the source program passed to them. One of the authors of the original article that inspired bcrypt's blog post reported hundreds of bugs in Clang and GCC, of which about half are “wrong code” bugs: https://github.com/csmith-project/csmith/blob/master/BUGS_RE...
You are right that Debian and other distributions assume that compilers do not have “wrong code” bugs, though. The only problem is that this is not true.
[1] https://www.destroyallsoftware.com/talks/the-birth-and-death... is funny, but the honest truth is that it's likely the future of web technologies, as Javascript is so deeply entrenched in the fiber of the web standards and the practical implementation of the browsers.
(I'm not a JS developer so I might've missed a few other things, but minifying JS is definitely a much harder problem than doing it with something like C.)
Closure compiler parses JavaScript code, removes dead code, minimizes what's left
Security concerns with minified JavaScript code
One of those moments where I pause to wonder if I should even read further haha.
The only way to be sure is not minifying the source.
It has the answer to your question. Namely, you can write bugs that are exploitable that aren't present in the original source, that only appear in the minified output. Which means that a) it is a whole lot harder for someone to find (especially if it's something that is "obviously" correct), and b) it's plausibly deniable.
https://www.gnu.org/software/librejs/
It won't help towards minification bugs or backdooring, but it's a step in the right direction.