exec() is potentially insecure, because it can execute any command on your system that the PHP process has permission to run. The key to using it securely is to ensure that the command you send to
exec() never contains direct user input.
Your example code is insecure because
$command depends on unfiltered user input from
$r is only supposed to set the parameters for the command, it can still be constructed in such a way that it calls other commands. You cannot depend on the web interface to set only valid data in the
$_POST fields, because it is very easy for a hacker to build an HTTP request with any data they like.
Ideally, the way around this is to do checks on the user input then set
$command using only data that is generated by your script (is it one of a pre-set list of strings, or a number in a certain range?). You have done this correctly for setting
$du - the insecure example would be setting
$du = $reg_wvar . '.py'.
Sometimes you do have to pass user input, such as your username parameter. In this case, you have to make sure that anything nasty is filtered out of the input before you use it in a command. This answer will be helpful.
The other thing to consider is what happens when the command is executed. The Raspberry Pi GPIO pins normally need root permissions for access, but it's a bad idea to give PHP (or your Python scripts) that level of permission. To address this, you need to set up the GPIO beforehand, and set permissions that allow them to be used by your Python scripts without needing
I use the script below to set up GPIO on my system when it boots. It's called from the
/etc/rc.local file, so it runs once at startup with root permissions:
if ! [[ -e /sys/class/gpio/gpio27 ]]; then
echo "27" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio27/direction
echo "0" > /sys/class/gpio/gpio27/value
chmod 664 /sys/class/gpio/gpio27/value
chgrp gpio /sys/class/gpio/gpio27/value
This configures pin 27 as an output, then sets the permissions so that it can be written to by members of the
gpio group. I set up this group to include the username of my web server.
If you need more flexibility (e.g. reconfiguring the GPIO pins from your Python scripts), then look at the wiringPi GPIO Utility. It is a little less secure because it uses root permissions when it runs, but the risk is a lot lower than running your own scripts as root.