Jake Saunders wrote about discovering that a recent Next.js vulnerability allowed hackers access to their server through an Umami instance. I use Umami, too!

I logged into my VPS and didn’t see any suspicious files or running processes. I then opened my Umami dashboard to poke around, and my browser immediately opened a window to a gambling site. Well, shit.

Damage assessment

The browser’s developer console showed that an onclick event was added to the <html> object, and this was originating from a file disguised to look like a standard Next.js library file used by Umami. So the attacker was able to modify and add files, as well as spoof the modified date to hide their tracks.

Umami was running in a Docker container, but I had to check if they had escaped the container. Running various commands revealed that the sudo command was no longer working properly. Gemini asserted that this was a sure sign that malicious actors had been doing naughty things. I wasn’t as confident, but I also am not experienced enough to convince myself that everything was fine, so I decided to play it safe by accepting that everything could have been compromised. I spun up a fresh new VPS and migrated my data and files over. Using Caddy and Docker Compose makes my installations extremely portable, and the migration itself only took a couple of hours.

Tightening security

My security wasn’t too bad before, but I did take one additional step on the new server by using user namespaces for my Docker containers.

Some processes within Docker containers need to run as root, which gives attackers an attack route if they break out of the container. By using namespaces, you can remap the container’s root user to a non-privileged user on the host machine. Even if an attacker managed to break out of the container, they would not be able to do anything.

What was the purpose of this attack?

In the aforementioned post, the attacker used the compromised server to mine Monero. This makes sense – it’s free money. But in my case, all they did was inject a link to a (annoying, but harmless) gambling website. All things considered, this is pretty benign, considering everything else they could have done.

I’ve explored what the motivations for this type of attack may have been. Most likely, the play is to link to a shady site from many compromised sites, in order to increase SEO rankings.

Another possibility is to collect tons of servers that are available to use, and use them as a proxy network to rotate IP addresses or conceal network activity.

In either case, there is a benefit to having the compromise go unnoticed for as long as possible. That would explain why the damage seemed so isolated.