$ sudo rm -rf / === NPM install
ghuntley.com
ghuntley.com
alias npm='aa-exec -p sandbox npm'
alias node='aa-exec -p sandbox node'
sandbox profile: # /etc/apparmor.d/sandbox
include <tunables/global>
profile sandbox {
#include <abstractions/base>
#include <abstractions/consoles>
#include <abstractions/nameservice>
/sys/** r,
/{usr/,}bin/* ixr,
# nodejs install dir
owner /home/*/nodejs/**/* rix,
owner /tmp/** rw,
owner /tmp/**/ rw,
owner /home/*/.npm/_* lrw,
owner /home/*/.npm/_*/ lrw,
owner /home/*/.npm/_*/** lrw,
owner /home/*/.npmrc r,
owner /home/**/node_modules/ rwix,
owner /home/**/node_modules/** rwix,
owner /home/**/package.json rw,
owner /home/**/package-lock.json rw,
owner /home/*/projects/**/ r,
owner /home/*/projects/** r,
}
To load the profile:sudo apparmor_parser -r /etc/apparmor.d/sandbox
edit: For completeness, added step to load the profile.
If this policy isn't available and enabled by default in some package containing common policies, do you really expect your average developer to a) even know anything about AppArmor, or b) know how to write an AppArmor policy file without spending a few hours digging through docs, reading examples, and engaging in a bunch of trial and error?
(If your answer is "yes" to either of those questions, I'd suggest you might overestimate what is common knowledge.)
Like, the tone of the comment makes no sense, the hard part isn't on the OP, and OP wasn't saying AppArmor is easy, just the content of their comment is easy (which it is!)
It's like saying flipping a light switch to turn on a light is easy... the having someone fly in complaining that understanding industrial power generation is not easy at all.
My point is: how do we know the instructions are actually safe?
If you don't trust it, don't run it... but I don't know how anyone in software development would be unable to function if they've never been able to trust someone else's config file suggestion.
It's not, it has subtle gaps in the sandbox which still allow some of the attacks it's supposedly protecting you from.
None of this applies to maintaining my development machine. You might want to revisit your gate keeping.
And the little demo script GP wrote seems pretty straight forward to me.
AppArmor has come a long way. It's worth learning about it. They have quite a few builtin profiles that you can take advantage of.
And you're still giving it plenty of access to any projects under your home dir, or opportunities to modify other npm packages that are being installed, to gain execution outside of sandbox later on.
The most common attacks is to mess with thinks you build for release in ways which then allow attacking the consumer.
For example by tweaking package, package lock, or even the source code.
Only the last one is prevented here.
Then there is also the thing that installing (user wide or even global) system utilities with npm is a thing, and wouldn't work with your apparmore profile (all need their own profile)
Similar locally running node programs are an attack vector and your profile allow modifying the `node_modules` of such programs even if they don't use npm...
Also you need root rights for loading profiles which can make having a profile for each project a problem as the dev doesn't necessary has root rights. (E.g. in a company with company managed desktop systems this is the default.)
Don't get me wrong. I'm not saying you shouldn't use apparmore and other sandboxes. I even think it's the future of Linux.
My point is appamore isn't simple and it's one of the most simple solutions out there.
Or in other words we still have quite a way to go.
And it's not just about doing sand-boxing, but also about managing sandboxed programs, e.g. last time I looked the app stores of both snap and flatpack where a horror-house of not-properly maintained packages with security vulnerabilities, as well as doggy potentially malicious "unofficial" packages. Even if you sandbox is perfect you still care about security, e.g. you don't want a openoffic package to send copies of all documents you use somewhere else... and that's if the sandbox if used (... flatpack ... facepalm).
Let me correct it:
It MUST be the future of Linux or Linux will have serious problems.
typed sudo rm -rf / opt
And let it rip.
Then got a weird error message, like a library couldn't load....then the icons in the dock went away, then the only thing that was working properly was the web browser windows that were still fully loaded in memory
then noticed the SPACE between '/' and 'opt'
rm -rf was rm -rf-ing from root.
Valuable lesson learned that day.
Also, if you're willing to lean into npm a bit, there's tools that give a layer of protection over rm such as https://github.com/sindresorhus/trash-cli
People used these folders for builds of our systems which could be accessed from any of our various supported environments (basically every flavour of UNIX under the sun - no pun intended there). Lots of them would also use them for development work, since many people simply remoted into a convenient UNIX box and fired up emacs or vi. I was one of the few people using my local machine for development because I was working on a Java application, and running an IDE locally was simply very convenient.
We also had our own CI system that built everything for every supported system overnight, and ran huge suites of automated tests, which also used this 2TB volume.
The key word here is shared. I had my own folder but I could do `cd ..` and see everybody else's folders, and then go poking around in them with full read/write access.
You can see where this is going, can't you?
A handful of weeks before I joined the company somebody had updated a script in a test case (I forget whether it was a pre or post) that did some cleanup. The clean-up was basically an `rm -fR *` in the current directory. What they hadn't spotted before commiting the script is that they'd `cd`ed up one or two directories too far, meaning that they ran an `rm -fR *` in the root folder of the volume.
Everything was gone. Nobody could get anything done, and it took them a day or two to restore the volume from backups (which, fortunately, they had).
Some people lost a day or two's work so, fortunately, it wasn't a business ending event or anything like that. More a cautionary tale and an object lesson about the dangers of running commands like this with unrestricted access to volumes.
Within a month another graduate developer had accidentally restored the whole FS. We got to go home early, but had browse-only access from then on.
Of course, we still retained write access to the whole FS because prod and dev were just different root directories and our deployment process was "cp" if you had CLI skills, or copy/paste in Windows Explorer if you like GUIs. We got an rm -rf runaway a little later, though only on home directories IIRC. The early 2000s were wild.
They certainly were. In my prior job my Windows 98SE development PC had a public IP address.
rm is disallowed to remove . and .. under POSIX, so, for that reason, / needs to be treated specially too.
# rm -rf /
rm: it is dangerous to operate recursively on '/'
rm: use --no-preserve-root to override this failsafe
There's still lots of ways to screw up a rm, like "rm -rf /*" or deleting your entire home directory, but a space after the initial / was apparently common enough that they eventually put a big failsafe for that in the GNU version. rm -rf /$MYVAR
If you don't set $MYVAR and don't set bash to error on unset variables you are in for trouble.You can also prevent this by never using $VAR, and instead always using ${VAR:?} to exit with error if VAR is unset (or use one of the other options to provide a default).
From that day onward I always make sure the first line of my bash scripts contains at least "set -e".
"This was how I knew OSX was a real Un*x"
No big deal, restore from backup, right?
It turned out nobody had connected the backup drive to the new server. It was still connected to the server it replaced, which was still in the rack, but turned off.
I finished what I was doing and wanted to clean up after, so after undoing my changes I ran userdel -r on that user (-r removes its home directory). The command took way longer than expected, at some point I terminated it to investigate as I assumed there was something unrelated going on (high CPU or IO contention).
At this point you probably figured out what happened. By the time I stopped the command the damage was done and a good part of the system has been nuked. Surprisingly (and thankfully I guess) the actual firewalling and routing is done at kernel level so it continued doing its job totally fine despite userspace being nothing more than a smoldering wasteland.
rm -rf * .some-extension
Missed the extra space, hit Enter, lost several days of work. Much smaller blast radius, but still an expensive mistake for a trip like that. No, it wasn't in source code control - a few of us might have been using CVS at that time (this was before Git's time), but apparently I wasn't, or I wouldn't remember the episode decades later.
> This is just one of the reasons why I think by 2023 working with ephemeral cloud-based dev environments will be the standard. Just like CI/CD is today.
Over my dead body will I ever use a cloud environment to write code. tmate[0] might be the closest I ever get.
I get some developers don't care about what they throw aimlessly onto a cloud, but I don't know what's being logged, what's being stored, how long it's being stored, who has access to it, what third-parties have access to it, and so on. The business I own or the one I write code for might care if those files were exposed like that.
Use a local VM. Or a development proxy. The cloud isn't a solution for everything.
If one wants to go sandboxing, the right place for it would be in npm, where packages should not be able to modify anything but themselves.
Example of tasty file that a package manager should never be able to read: /Users/mxey/.ssh/ssh_rsa or /Users/mxey/.netrc
Linux security model (and I suppose other OSes too, but I'm most familiar with) is fundamentally incompatible with desktop environments. Mobile OSes got it much better.
I love Snap because it confines processes to sandbox.
If good security isn't easily obtainable for tech-savvy person in one hour, there is basically no security.
https://medium.com/agoric/pola-would-have-prevented-the-even...
> When installing an untrusted package, run `npm install` or `yarn add` with the `--ignore-scripts flag`. If, like me, you tend to forget this, you can set npm/yarn to never run scripts with `{npm,yarn} config set ignore-scripts true`.
This disables install scripts, which is a primary attack vector for malware on npm. It also breaks some packages, though, but I've had this setting on for a while with no major problems.
Node apps should be developed in isolated containers or VMs.
We need peer review of every update, imo.
Starting to think checking node_modules into an app repo, so you get update diffs, is sane.
I don't have a problem with making the convenient route possible, but it's very troubling that the tooling actively fights you if you want to take a saner approach.
The challenge with a lot of these systems is that there _are_ "official" packages that have some higher level of checks and quality control, and these best case examples are generally talked about on the relevant marketing pages for these tools. But these vetted packages are generally accessible in the same way as unofficial "wild west" packages that would be high risk to use. The line is very blurry and you can easily be sucked into a false sense of security.
I'm amazed at how many times I see these systems being used as a matter of course without any consideration at all given to the risks of importing packages of unknown quality from unknown third-parties.
And it's very difficult to avoid using these systems too. I use brew, docker, npm, Nuget etc. - it's hard to be productive and to not do so as a developer in 2021.
I have a standard process I go through for taking on new development dependancies, of vetting the author of Nuget/NPM packages as best I can. I rarely add a dependancy without having gone through my little (likely very insufficient) "due dilligence" process first, but this doesn't cover downstream/implicit dependancies...
I'll also try not to bring in dependancies for simple things. I prefer reinventing the wheel where necessary and writing my own simple string formatter or parser utility as opposed to taking the easy way out and adding another dependancy for the matter of a few lines of code.
But I don't know how to solve the wider issue. The first step, I guess, is to make sure that everyone really knows what the risks are, so that at least we're all using these package mangers with our eyes fully open.
Some things should be held to a higher standard and with those, tools like NPM that only serve to make the job faster but not make the end product better shouldn't be allowed.
> Honestly, I would not be suprised by 2030 if insurance companies made the usage of ephemeral sandboxes (in whatever form: be that cloud, OCI, or firecracker) a condition of issuing cyber insurance.
Whatever form it takes, insurance companies' influence on the development process is a new and profound thing. Try to think of an industry where insurance is involved that doesn't go to great lengths to comply with their requirements; manufacturing, bulk transport, personal transport, health care, home ownership, civil engineering, chemical development, plant maintenance, entertainment, farming...it's an endless list. Devs can rant all they want (people in other industries sure do!) but if the insurer's mandates are imposed at a company level, they won't have much choice.
Given the pace of new compliance I've had to onboard in the last few years, I think it's coming a lot sooner than 2030.
Maybe 2024 or 2025.
Banks and insurance companies have been implementing on their own and requiring rigorous standards from their vendors. Then there's meeting the requirements for FedRAMP certification if you want to sell to Uncle Sam.
If you look at the tech stack of a company like Progressive and how they do software deployments, they are _significantly advanced_ in comparison to the rest of industry. They also made their transformation extremely quickly by committing adequate internal resources to the problem.
This anti-feature should be removed, and other safer workarounds provided.
1000% agreed. I might need to refactor the article to remove the focus on NPM. It was cited for two reasons:
- awareness that an important RFC that people need to vote on
- npm is related to ua-user agent-parser incident (mystery meat in a binary package)
Just don’t run npm install (or pip install) on a production server but install things exclusively from the distro packages or if they are not available use a container. On your PC… keep a backup on hand and possibly don’t save the keys that you use to access production systems on a txt file.
Really npm is not that much of a deal. The problem is more for CI machines that can get compromised but for workstations… they are already insecure
The one and only solution here is – don't pull code from sources you don't fully trust.
An idea that is antithetical to the whole ecosystem surrounding npm/JavaScript. You can be careful with your direct dependencies, but their dependencies and those things dependencies? That's how a bunch of otherwise very respectable/well engineered projects ended up with left-pad in them.
Eventually it got passed to me. The files were missing. This was on a 16T file store, one of about 10, and investigating showed about 200G was missing.
Backup was an rsync job every hour to another server, with a —-delete option every week on a Monday morning.
Trawling though the auth logs eventually showed a second line engineer had elevate shimmed to root and managed to delete a bunch of files by running “find -delete” with a mangled name filter. He’d tried to solve a real problem by copying and pasting from google, failed, not realised why it failed, and given up.
Several dozen hours of archive material had been gone, forever
(There was also the time a different engineer at a different site transferred an archive with ftp. In ascii mode.)
Shouldn't there be a sort in there before the uniq?
> Honestly, I would not be suprised by 2030 if insurance companies made the usage of ephemeral sandboxes (in whatever form: be that cloud, OCI, or firecracker) a condition of issuing cyber insurance. In this distributed world where remote development is now a norm moving towards ephemeral sandboxes is an important lever to counter the increasing threat of source integrity and supply chain attacks.
Note that we still need to address the underlying issue of source integrity and supply chain attacks, because many of these things people are blindly including via NPM and similar are not just used in development. They are often also used in production code that is dealing with real customers.
Probably. uniq only removes duplicate lines when they're adjacent to each other. I doubt the git grep command output has all the matches adjacent.
I've read it's more efficient to use 'sort -u' instead of 'sort | uniq'. These days I only use the latter if I need uniq's -c to show the count of matches for each unique line.
Consider this input
1 foo
2 foo
1 foo
2 bar
1 bar
2 bar
For that "sort -u" and "sort | uniq" would give the same thing: 1 bar
1 foo
2 bar
2 foo
But if you wanted to sort numerically, "sort -n -u" would not give the same result as "sort -n | uniq". The latter gives: 1 bar
1 foo
2 bar
2 foo
but the former gives: 1 foo
2 foo
The man page for GNU sort says of "-u":> with -c, check for strict ordering; without -c, output only the first of an equal run
but "sort -n 1" gives:
1 bar
1 foo
1 foo
2 bar
2 bar
2 foo
and so the equal runs are "1 bar", "1 foo", "1 foo" and similarly for the "2" lines, so I'd expect the output to be "1 bar" and "2 bar", not the "1 foo" and "2 foo" that it actually gives.The man page for BSD sort's explanation of "-u" explains what is going on:
> Unique keys. Suppress all lines that have a key that is equal to an already processed one. This option, similarly to -s, implies a stable sort. If used with -c or -C, sort also checks that there are no lines with duplicate keys.
Doing "sort -s -n 1" shows "1 foo" as the first "1" line and "2 foo" as the first "2" line, explaining why those are the two lines that make it past "-u".
The rm -rf vulnerability is essentially a problem with a chain only being as strong as its weakest link. If any of the maintainers in the hundreds of node dependencies your project uses is malevolent, you're screwed. Hence, the security of the chain depends much more on the number of links it has rather than its innate strength.
Even large and complex dependencies tend to be well engineered in Python. BeautifulSoup is a widely used library for loosely parsing HTML. It requires only Python and an internal library. lxml is another HTML parser (which BS can optionally use), and it requires only Python and a couple of C libraries. Even an entire web framework (Flask) uses only 4 Python dependencies directly and only one of these (the Jinja template engine) has recursive dependencies on other Python packages. All told it's about 10 Python packages needed in total.
Or consider this, if you want an example of a trivial command line tool: the Python tldr[1] client uses only 3 libraries as recursive dependencies. The Rust client, tealdeer, has 119. The official nodejs client has, if I'm counting correctly, 603.
[1] https://tldr.sh/
That's my experience, anyways, having previously worked on a large rails application, as well as large golang applications, and now spending most of my time in a typescript project.
But this sort of thing happens quite often outside NPM as well. If you're an author of a popular web browser extension then you've probably received emails from random shady people offering to buy your extension. And of course, some people are offered a sum they can't refuse. Google and Apple app stores aren't immune from this either.
I just remembered the absolute saddest hijacking I ever witnessed. It was this blog I read one day. The guy had some interesting articles (business, I believe). I kept reading and he starts talking about his health. It gets worse and worse. Then suddenly the tone of the articles change. I notice weird links to vitamin and supplement crap stuck in articles that had nothing to do with it. The articles became incredibly generic. So I did some research. Turns out, the guy died from cancer, apparently his domain name expired, and some SEO spammer type took his domain and his content and repurposed it for shitty harvesting purposes.
By extension, people can learn some things about their employer by their opinions of using open source libraries in company products.
1. The company is against open source entirely, preferring to buy closed source alternatives, which tells you that the company thinks software development (and by extension you as the developer) is just a cost to be minimized that they don't care about otherwise.
2. The company is not against open source, but does a poor job of keeping tabs on security patches, which just tells you that the bosses are not very smart, I suppose.
3. The company does a good job of using open source, contributing back to the libraries they use to improve them, and keeps up with security patches and issues, which means the company is invested in its developers and development processes and is likely a good place to work.
me: hey, how can I do $x?
random: $ sudo rm -rf
I love stupid stuff like this that gullible and naive people follow. It reminded me of my early days in Counter Strike. XxXButtStuffXxX: how do I spray decal?
random: press F10
random2: press Alt+F4
...
XxXButtStuffXxX left the game
It's classic, harmless trolling/pranking before it became the toxic beast it is today. $ touch -- -rf
$ mkdir subdir1
$ touch subdir1/test1
$ rm *
$ ls
-rf
$
With zsh it's almost the same, it just warns me first: $ touch -- -rf
$ mkdir subdir1
$ touch subdir1/test1
$ rm *
zsh: sure you want to delete all 2 files in /path/to/test [yn]? y
$ ls
-rf
$
Since there was a file called -rf, `rm *` expands to `rm -rf subdir1`, and that's what it does. The actual file named -rf survives because -rf was interpreted as an option rather than a filename. It would only have been removed if I did `rm -rf -- *`.Globs getting interpreted as switches is a very unfortunate footgun, sure, but I don’t see how you could eliminate it while retaining the same level of smarts in the shell (tokenization but only into dumb strings), and DOS/Windows command line parsing is IMO essentially a reductio ad absurdum for the idea of having less (no tokenization, but the shell still splits commands). Except maybe require the -- between switches and arguments whenever there are arguments? But not only is that an incomplete fix, it also goes contrary to convenience of interactive usage, which is important: much of the tension in shell syntax and Unix utilities is due to balancing it with conventional programming, I feel, and I wouldn’t want to be writing even Perl or Tcl instead, let alone Powershell or the like.
echo a > -
echo b | cat -- -
Output: bhttps://www.defensecode.com/public/DefenseCode_Unix_WildCard...
Basically the entire implementation is defined by this one file, it's pretty simple, like you'd hope: https://git.launchpad.net/safe-rm/tree/src/main.rs
I absolutely do not remember the internet being so characterised back in 1996. It was a place of wonder and hope.
The reason I use a VM or container is so that I can get rid of it easily.
Mitigate risks. Please.
This struck me, because in most help-oriented discords I've I've joined nowadays, the policy seems to be "don't beat around the bush and just ask your damn question". I've actually been chastised for not just asking my question immediately a few times. Funny how cultures change.
Or mount my local emacs configuration, which I sometimes tweak and currently just save to disk and carry on with my work (I'm not asking how to run emacs in gitpod, I know there was some work on that)?
Am I out of luck, gitpod/insurer/employer knows best? Or are there ways provided accessible to individual developers to 1. do arbitrary customization and 2. "mount" writeable directories from a laptop filesystem (or something similar)?
Have you blogged about your method of note taking? Are they done in-line on the code? I see the mention of emacs (high five) but have you come across https://marketplace.visualstudio.com/items?itemName=vsls-con... yet? I wonder if such a thing exists yet for emacs…
But more to the point, I don't want to have to justify every tiny aspect of my development environment. Does gitpod provide a way out of that sort of authoritarian system?
> For taking notes I use the iPadOS15 notes feature by swiping from the bottom right hand hot corner.
Honest question: what does swiping have to do with how to not have all my personal notes in the cloud?
Hm, I think perhaps you're saying one can keep notes that are not in the dev environment at all? Of course that's true, but I'm incredibly accustomed to working entirely in a heavily customized emacs, switching between org-mode buffers and code. Sometimes that's via org links to specific tiny fragments of code content (a link to e.g. a filename + the text "def my_function(" will take me right there even if the code changes a bit).
But then I realized he's still at the bottom of the hierarchy of needs, while I'm at the top, self-actualized. If he ever does get paid to produce drudgery, he will see it was not the solution he hoped.
rm -rf "$STEAMROOT/"*
and if $STEAMROOT wasn't set, that amounted to rm -rf * rm -rf "${STEAMROOT:?}/"*
Will exit with error instead of running rm if STEAMROOT is unset. Even if used inside a conditional.https://github.com/MrMEEE/bumblebee-Old-and-abbandoned/commi...
There so many comments on that commit that Microsoft Github's backend apparently cannot load the page -- I just get the "unicorn".
Anyway, this issue also points it out: https://github.com/MrMEEE/bumblebee-Old-and-abbandoned/issue...
Maybe if this also picks up steam, we will get `npm brick` as the solution from the NPM team.
- If=input file
- Of=output file
Never swap (you’ll make this mistake once and hopefully never again) the order and always do IF before OF (I comes before O in the alphabet)
First, you need to create a partition: Run fdisk.
A few short seconds later I unfortunately no longer had a windows machine.
I.e use timeshift backups / cloud sync / src control for anything vital + treat your OS as a throw away, or at least, re-instate-able in <30 min.
1) regular backups
2) use LVM for your filesystems and make a script to create regular CoW snapshots. I always have a snapshot running that lets me get back to previous, known state with very little effort.
I intended to delete a folder, but somehow `/` sneaked in and I pressed Enter...
I also think my PC back then looked exactly like the one in the picture from the article :)