PHP script needs permission to run a sudo command with shell_exec()

PHPsudounix

I have a PHP script which contains a shell_exec() and the command it executes normally requires sudo. I've edited the sudoers with visudo to contain the following:

www-data ALL = NOPASSWD: /var/root/node/npm/node_modules/less/
%users ALL = NOPASSWD: /var/root/node/npm/node_modules/less/

I suspect either should work, but I went with the belt-and-suspenders approach to be sure.

I'm editing etc/sudoers with vim, so after adding these lines, I do 😡 and everything works. My PHP script does what it's supposed to… for about 10-15 minutes. Then the script stops working. Specifically, the shell_exec() stops working.

If I do sudo visudo again, my new lines are still there. But only when I save it again does the script start working again.

Can anyone tell me why this might be happening? I have two guesses that aren't very good:

  1. There is some sort of grace period that starts when I sudo visudo and this is what's allowing my script to work (but only until it expires).
  2. The new data in etc/sudoers is staying in sudoers.tmp (the "Lock file")…
    Neither of these add up to me.

EDIT:

I think I'm using the wrong username… It looks like for MAMP, the apache user is actually my user (not www-data). I know this because I added this to my PHP script: echo = shell_exec("whoami"); My username appears: Emerson. So does this mean I should add Emerson ALL = NOPASSWD: /var/root/note/npm/node_modules/less/bin/lessc to my sudoers file?

EDIT:

I've got it working with this in my sudoers file. Emerson ALL=(ALL) NOPASSWD: ALL It works, but I don't think it's the way it should be. Aside from a bunch of redundancy, it's also too permissive. I've left all the nonsense in so you can see what I've currently got.

#

# Host alias specification

# User alias specification

# Cmnd alias specification

# Defaults specification
Defaults        env_reset
Defaults        env_keep += "BLOCKSIZE"
Defaults        env_keep += "COLORFGBG COLORTERM"
Defaults        env_keep += "__CF_USER_TEXT_ENCODING"
Defaults        env_keep += "CHARSET LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE"
Defaults        env_keep += "LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME"
Defaults        env_keep += "LINES COLUMNS"
Defaults        env_keep += "LSCOLORS"
Defaults        env_keep += "SSH_AUTH_SOCK"
Defaults        env_keep += "TZ"
Defaults        env_keep += "DISPLAY XAUTHORIZATION XAUTHORITY"
Defaults        env_keep += "EDITOR VISUAL"
Defaults        !requiretty

# Runas alias specification

# User privilege specification
root    ALL=(ALL) ALL
%admin  ALL=(ALL) ALL
Emerson ALL=(ALL) NOPASSWD: ALL

# Uncomment to allow people in group wheel to run all commands
# %wheel        ALL=(ALL) ALL

# Same thing without a password
 %wheel ALL=(ALL) NOPASSWD: ALL

# Samples
# %users  ALL=/sbin/mount /cdrom,/sbin/umount /cdrom
# %users  localhost=/sbin/shutdown -h now

#Allow PHP to compile .less files
www-data ALL = NOPASSWD: /var/root/node/npm/node_modules/less/bin/lessc
%users ALL = NOPASSWD: /var/root/node/npm/node_modules/less/bin/lessc
Emerson ALL =(ALL) NOPASSWD: /var/root/node/npm/node_modules/less/bin/lessc
apache ALL =(ALL) NOPASSWD: /var/root/node/npm/node_modules/less/bin/lessc

Best Answer

Neither of the things you suggested are the issue here.

Do you have a requiretty line in your sudoers file? This would explain why it works for you, but not your PHP script. Removing that would fix the issue.

Sudo may have been configured to cache your password for 15 minutes, check for a line like 'Defaults timestamp_timeout = XXXX' in your sudoers file.

One word of advice, consider limiting sudo to only the files it needs. What if an attacker manages to drop a malicious file into your node_modules/less/ directory?