Information Security Asked by UserK on December 26, 2020
I have noticed several questions on Stack Overflow, like this one, about executing commands with root privileges using PHP. The answer proposed to add the line
www-data ALL=(ALL) NOPASSWD: ALL
to the /etc/sudoers.d
file.
Is it a safe approach to solve the problem? Does it create a vulnerability?
This... is atrocious. The whole point of running Web things as a non-root user is damage containment: in case the Web server process gets hijacked through some vulnerability, at least the attacker won't obtain full control of the machine, since he will be constrained by the limitations of the non-root account www-data
. But if you give www-data
a way to run every command it wishes to, with the rights of any user (including root
), and without any further authentication, then you just lost that damage containment feature.
To be fair, www-data
+ sudo is slightly better than simply running everything as root
, because the going-to-root has to be explicit; therefore, common flaws like a PHP script writing files in improper locations would be harder to exploit. But still, making www-data
a member of the sudoers looks like a poor idea.
Correct answer by Tom Leek on December 26, 2020
I did some recent research and found some ways to do this, but as said by @tom-leek, it would in no way be 100% consistent, just a less unsafe method.
But there is a way that I believe is easy even for professionals with little experience like me!
The best secure method is to use the crontab.
Save all your commands in a database (mysql whateaver)
Create a cronjob to read these mysql entries and execute via exec()
or shell_exec();
Add these lines to cron
crontab -e
I prefer to check every 5s but you can check each 10 minutes, as you prefer.
The PHP put values in db table, a simple table with 1 value worked for me and just it! $domain_name kkk
The root user checks the table and get records, generate certificates and remove $domain_name
of table.
You can use acme.sh, I prefer Lego, but whatever.
If your system is hacked you never will lose your root access and can fix it quickly!
I found this good idea in this article: https://sanjaykumarns.blogspot.com/p/how-to-execute-root-level-privileged.html
Where killProcess.php fetches the process IDs from the database and execute the kill linux command(or any other linux commands as per your requirement) through the php function shell_exec().
Since the cronjob entry is configured as the root user, the specified script has all the same set of privileges as the root user.
Answered by felipecalil on December 26, 2020
Every time, with no exception, when you see ALL=(ALL) NOPASSWD: ALL
in the /etc/sudoers
file, someone deserves to be fired. Basically, you have a second root user.
Is it safe? Hell no. Does it create a vulnerability? Hell yes.
You can use sudo to safely grant a non-root user (including www-data) a privileged execution, but it should always be as specific as possible. If you need to run /usr/bin/my_system_tool +x /var/cache/my_cache
as root for whatever reason, that exact command, including parameters should be in the /etc/sudoers
file.
Answered by Tom on December 26, 2020
When considering how secure something is, you should assume the attacker is able to log in as your www-data user, and have a shell. This does not mean your attacker really can get a shell, but there can be plenty of ways how the attacker can execute arbitrary shell commands; they could be results of library bugs like shellshock, or oversights in your code.
The best way of doing this is, like @AlexeyVesnin said, to use a specialized process to do the work. Have this process listen on a (unix domain, so it isn't reachable from the network) socket, read its input from said socket, sanitize the input(!), do the work, and return some result to the socket, from where the web server script reads results. Any authorization (user needs to enter some password on the web site to be allowed to do this) should be handled in that process, and the www-data user should not be able to read any of that authorization data.
In case your budget, or your skill, doesn't make this best approach feasible, using the sudo approach isn't completely wrong, but you should restrict sudo permissions to the minimum you actually need. For example, let's assume you want to show current disk I/O data on your web site, for which you need to call iotop
:
make a script, in this example /var/www/bin/get-disk-io
, that extracts the data you need:
/usr/sbin/iotop -b -n 1 | /usr/bin/head -2
$1
, $2
, ... , $*
, $@
/etc/sudoers
env_reset
is in the defaults policy in your sudoers fileNote that this is still safer than a suid program, since (a) you can restrict who can execute it, so an attacker who gains the ability to execute a program under a different user won't be able to use it, (b) you can't pass arbitrary parameters to it, (c) the environment is sanitized by sudo
, and (d) you can make sudo log when the command gets executed, so you have an audit trail that a suid program doesn't give you.
Note: Do not do this unless you know what you're doing. If you're asking, or reading, this question on stackexchange, you probably don't. So don't do this.
If you set the owner of an executable to a certain user (chown user /my/executable/file
), then set the suid bit (chmod u+s /my/executable/file
), then that program will run under the permissions of that user every time it is executed. So, for example, chown root /bin/cat; chmod u+s /bin/cat
will run every invocation of cat
with root rights, which means you can read every file on the system independent of its access rights. Do not try this on a system that is connected to a network, not even for 5 minutes to "check if it works".
strace
, the s
bit has no effectLinux has a capabilities system, that works almost like suid, but a much finer granularity. For example, if you need a process to be able to use port numbers below 1024, in classical unix systems, you need to run the command as root, often meaning you need to do the above chown/chmod u+s
stuff, which allows using those port numbers, but also grants access to the filesystem. Linux allows you to give the port capability without everything else that comes with root:
setcap cap_net_bind_service+EP /path/to/my/program
Do man 7 capabilities
to learn more. If you seriously consider giving suid to a program, think twice if setting a capability isn't a better idea.
Answered by Guntram Blohm on December 26, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP