slickstack
slickstack copied to clipboard
Adminer is public-facing by default and should be more secure
Adminer is public-facing by default. SQL tools like Adminer and phpMyAdmin, while convenient for quick administration tasks, greatly increase the attack surface of a site when they are public-facing. I think requiring manual "installation" of Adminer would be a better practice. Having Adminer along with any future backend tools run on an alternative port (which users are encouraged to lockdown by firewall) would probably be best practice.
Edit: Looks like Adminer required manual "installation" via ss-install-adminer in the past. I guess I would urge a return to that?
This is a security flow detected by Detectify services as well. There are not important flows but this.
Thanks for your feedback on this @blakepb
The reason why we install Adminer by default is because we aim to make SlickStack as easy to use as possible for newbies who don't have much DevOps experience (and more importantly, potential freelancers).
That said, although our security overall has been very strong I think, Adminer has been ignored for too long. The challenge with securing Adminer is how to make it easy to use for newbies, but still making it as secure as possible...
Here's some of the ideas that I have seen around the web:
- using very strong passwords
- some type of brute force protection
- using non-typical port number
- requiring SSH/port forwarding to access Adminer
- restricting Adminer to specific IP addresses and/or internal network, VPN range, etc.
- using Apache/Nginx password authentication to access the page
- disabling root user access to Adminer
- enabling SSL/HTTPS on Adminer
- etc, etc
It's important to note that SlickStack does already have SSL/HTTPS for Adminer, and this is because it loads via PHP-FPM in the Nginx server block on port 443 already. If we changed the port number, we'd have to customize SSL configuration which seems a bit janky, and requires more "moving parts"... I'm not against "security by obscurity" per se, and previously SlickStack did use port 6969 by default for SSH (for example), but some of that is kinda gimmicky and unserious IMO.
We also already rate-limit the Adminer URLs using Nginx zone settings -- that could possibly be better optimized, but it's definitely active and working already, at least.
As a fairly technical person myself, who uses a variety of devices and travels sometimes, I can't imagine requiring SSH keys and/or port forwarding to a local computer, etc, just to access Adminer, and I know the majority of clients I work with and their freelancers wouldn't be able to figure that out either, so that's a no-go I think.
We recently added the ability in SlickStack to restrict sudo
SSH sessions to a specific IP address, since SlickStack defaults to discouraging SSH key usage, this was a requested alternative that seemed to make sense. However, restricting Adminer to certain IP addresses would probably confuse and frustrate most typical WordPress users... unlike SSH, which is certainly a more technical thing to begin with, Adminer is something that your average web designer might require.
And since SlickStack supports only a single site per server, the non-root database user already has access to production, staging, and dev databases, just like the [email protected] user, so disabling access for the "root" user wouldn't really add any more security on its own for our purposes...
Ref: https://serverfault.com/questions/445294/securing-phpmyadmin-non-standard-port-https Ref: https://www.tecmint.com/secure-phpmyadmin-centos-ubuntu/ Ref: https://gripfastistech.com/index.php/blog/54-how-to-protect-adminer-by-ip-address-on-nginx.html Ref: https://stackoverflow.com/questions/3687940/how-to-restrict-access-to-phpmyadmin Ref: https://stackoverflow.com/questions/2631269/how-to-secure-phpmyadmin
In summary:
We use SSL, rate-limiting (anti-brute force), and single site per server already (isolation), and the default passwords that SlickStack generates for database users are pretty strong.
Right now I think the only practical and user-friendly additions we might consider would be changing the Adminer URL to make it less guessable for bots, and/or consider enabling password protection via Nginx.
We also have a new option in ss-config
for disabling Adminer, although it's not actually functional yet.
Another potential approach here might be requiring user authentication via /wp-admin/ before access to adminer.php is allowed, but I'm not sure if that would introduce as many drawbacks as benefits, e.g.:
https://wordpress.org/plugins/db-access-adminer/
There's been several such WP plugins over the years, although I recall some security concerns in the past.
Honestly this could be the best approach, as then security concerns would come mostly down to file permissions, and then whatever existing security exists for /wp-admin/ and wp-login.php etc.
I would have to consult with some WordPress devs to try this probably, or get some help.
For now, I'm going to proceed with generating random strings for the Adminer frontend URL, that seems to be the easiest improvement here, and also no risk of complicating things (e.g. using Nginx/WP authentication).
Okay, well there are too many commits to reference here. But see:
https://github.com/littlebizzy/slickstack/blob/master/modules/nginx/sites/production.txt
And:
https://github.com/littlebizzy/slickstack/blob/master/modules/wordpress/mu-plugins/xxx-common.txt
These now have a placeholder @ADMINER_RANDOM_URL
which is replaced with the value of ADMINER_URL
during the initial ss-install
process, unless a value exists already for that variable in ss-config
. So maybe this is good for some users who want to keep an easy-to-remember URL like /adminer/
or whatever, but that now requires opt-in and by default the Adminer frontend access URL will be a difficult to guess string generated by OpenSSL.