limetech Posted August 18, 2015 Share Posted August 18, 2015 Plugin Authors: A primary goal of 6.1 is to button up some security holes; hopefully, you have followed along with the 6.1-rc release series. In particular, we have made some changes having to do with commands passed in the 'cmd' (for update.htm) and '#command' (for update.php) query variables. In addition we have eliminated and/or moved around certain command utilities. These changes may or may not affect your plugin (probably they will). Here we will outline the changes that should be made. Please reply in this thread with questions/comments. Command Execution Here we're referring to a mechanism whereby a "command" can be passed in http GET or POST via query variable. In the past, these commands could be anything, including for example, things that could display the passwd file or delete arbitrary files. In an untrusted network of course this is undesirable. If you define a root password then authentication is necessary to successfully execute http GET/POST and up until now that was "good enough" - but no longer. Here we describe some methods we've seen plugins employ and how to fix. Note: update.php features an #include argument which also must follow the below rules. There are basically 4 ways a command string can be passed: 1) An absolute path which whose root is like a “/usr/local/emhttp” (docroot) jail: cmd=/webGui/scripts/mycmd cmd=/plugins/<plugin-name>/scripts/mycmd When the command is actually executed the server will prepend “/usr/local/emhttp” to form the real path of the command passed to exec(). This is now the “best practice” for all such command strings. 2) An absolute path where docroot is explicitly included: cmd=/usr/local/emhttp/webGui/scripts/mycmd cmd=/usr/local/emhttp/plugins/<plugin-name>/scripts/mycmd This will work but we will generate syslog message similar to: “Deprecated absolute path:” In 6.1 ‘stable’ this will be an error. There are no uses of this form in the 6.1 webGui. 3) A relative path: cmd=webGui/scripts/mycmd cmd=plugins/<plugin-name>/scripts/mycmd cmd=rm file This will work but we will generate syslog message similar to: “Deprecated relative path:” In 6.1 ‘stable’ this will be an error. There are no uses of this form in the 6.1 webGui. 4) An absolute path outside our docroot: cmd=/usr/sbin/rm file This will not work at all and will generate an error message in the syslog. Once 6.1 stable is released, we’ll use realpath() function to verify commands do not get outside /usr/local/emhttp but this is not enforced completely yet. Note this precludes the use of common shell commands such as 'cp', 'mv', etc. For doing such operations you must create a wrapper script. Wrapper scripts should be in your plugin/scripts directory. Commands executed with exec()/shell_exec() The “best practice” is to specify an absolute path: exec(“/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/plugin $args”); though this will work (but watch out: no leading ‘/’): exec(“plugins/dynamix.plugin.manager/scripts/plugin $args”); and one could also use: exec(“$docroot/plugins/dynamix.plugin.manager/scripts/plugin $args”); Use of built-in commands Command that used to be in /root have been moved to /usr/local/sbin (in particular 'mdcmd'). If one of these is used please use the new absolute path, eg., "/usr/local/sbin/mdcmd". Plugins that define scripts should put them in the plugin-specific ./scripts directory. If your plugin defines a script that would be useful for someone at the console, it's ok for it to generate a symlink to the script in /usr/local/sbin. See for example, the 'plugin' command. Command arguments Arguments for commands passed via 'cmd' or '#command' must be specified using separate query variables. For example, with 'update.htm': GET /update.htm?cmd=/plugins/dynamix.plugin.manager/scripts/plugin&arg1=version For 'update.php': POST /update.php <post body> #command=<mycommand> #arg[1]=<argument 1> #arg[2]=<argument 2> etc Link to comment
bonienl Posted August 18, 2015 Share Posted August 18, 2015 Perhaps also good to mention that plugins which have scripts defined to start and stop a service under /etc/rc.d are recommended to move to /usr/local/emhttp/plugins/<plugin name>/scripts as well. For example /etc/rc.d/rc.myService becomes /usr/local/emhttp/plugins/myPlugin/scripts/rc.myService Link to comment
Squid Posted August 18, 2015 Share Posted August 18, 2015 I really applaud the effort in closing any and all security holes in unRaid. Community Applications is ready to go for 6.1 Final Link to comment
dlandon Posted August 25, 2015 Share Posted August 25, 2015 What of this has changed for rc6? Link to comment
Squid Posted August 25, 2015 Share Posted August 25, 2015 Looks like Tom edited the OP with this: (I got nailed by it) Command arguments Arguments for commands passed via 'cmd' or '#command' must be specified using separate query variables. For example, with 'update.htm': GET /update.htm?cmd=/plugins/dynamix.plugin.manager/scripts/plugin&arg1=version For 'update.php': POST /update.php <post body> #command=<mycommand> #arg[1]=<argument 1> #arg[2]=<argument 2> etc Link to comment
dlandon Posted August 25, 2015 Share Posted August 25, 2015 Looks like Tom edited the OP with this: (I got nailed by it) Command arguments Arguments for commands passed via 'cmd' or '#command' must be specified using separate query variables. For example, with 'update.htm': GET /update.htm?cmd=/plugins/dynamix.plugin.manager/scripts/plugin&arg1=version For 'update.php': POST /update.php <post body> #command=<mycommand> #arg[1]=<argument 1> #arg[2]=<argument 2> etc That's what I was looking for. Link to comment
dlandon Posted August 25, 2015 Share Posted August 25, 2015 I've been messing with the unassigned devices plugin to see if I can make it work for rc6 because rc5 broke it, then rc6 broke it again. I have everything working but I can't figure out the syntax I need for this line; var content= "<div class='switch-wrapper'><input type='checkbox' class='complete-switch'></div><button type='button' onclick='$.post(\"/update.php\",{\"#command\":\"/plugins/unassigned.devices/scripts/udevadm trigger --action=change\"}};' value='Rescan Disks'>Rescan Disks</button></div>"; Can anyone suggest how to code this line to get it to work with rc6 and pass the command and arg separately? The scripts/udevadm is a symlink to /usr/sbin/udevadm, which may not be necessary because udevadm may be in the path. I'll investigate that further once I get this working. Link to comment
bonienl Posted August 25, 2015 Share Posted August 25, 2015 I've been messing with the unassigned devices plugin to see if I can make it work for rc6 because rc5 broke it, then rc6 broke it again. I have everything working but I can't figure out the syntax I need for this line; var content= "<div class='switch-wrapper'><input type='checkbox' class='complete-switch'></div><button type='button' onclick='$.post(\"/update.php\",{\"#command\":\"/plugins/unassigned.devices/scripts/udevadm trigger --action=change\"}};' value='Rescan Disks'>Rescan Disks</button></div>"; Can anyone suggest how to code this line to get it to work with rc6 and pass the command and arg separately? The scripts/udevadm is a symlink to /usr/sbin/udevadm, which may not be necessary because udevadm may be in the path. I'll investigate that further once I get this working. Sure, the correct syntax is: var content= "<div class='switch-wrapper'><input type='checkbox' class='complete-switch'></div><button type='button' onclick='$.post(\"/update.php\",{\"#command\":\"/plugins/unassigned.devices/scripts/udevadm\", \"#arg[1]\":\"trigger\", \"#arg[2]\":\"--action=change\"});' value='Rescan Disks'>Rescan Disks</button></div>"; Any parameters need to be passed as a separate array of arguments (#arg[1], #arg[2], etc). The line above is written in JSON notation. Ps1. In the original string is a mistake with double '}}' it should be '})' Ps2. It is also required that scripts are placed under the <plugin>/scripts location instead of /usr/local/sbin. Link to comment
peter_sm Posted August 27, 2015 Share Posted August 27, 2015 i have this code .... <form name="stop_openvpnserver" method="POST" action="/update.htm" target="progressFrame"> <input type="hidden" name="cmd" value="/usr/local/emhttp/plugins/openvpnserver/scripts/rc.openvpnserver stop"> <input type="submit" name="runCmd" value="Stop"> </form> I change the cmd line to ... <input type="hidden" name="cmd" value="/plugins/openvpnserver/scripts/rc.openvpnserver stop"> but it still won't work? what have I missed ? //Peter Link to comment
bonienl Posted August 27, 2015 Share Posted August 27, 2015 Use: <input type="hidden" name="cmd" value="/plugins/openvpnserver/scripts/rc.openvpnserver[color=red]&arg1=[/color]stop"> Link to comment
peter_sm Posted August 27, 2015 Share Posted August 27, 2015 Use: <input type="hidden" name="cmd" value="/plugins/openvpnserver/scripts/rc.openvpnserver[color=red]&arg1=[/color]stop"> Thanks, but where and how do I specify &arg1 Link to comment
bonienl Posted August 27, 2015 Share Posted August 27, 2015 Use: <input type="hidden" name="cmd" value="/plugins/openvpnserver/scripts/rc.openvpnserver[color=red]&arg1=[/color]stop"> Thanks, but where and how do I specify &arg1 It is not allowed anymore to specify parameters directly in the command, instead they need to be given as separate arguments: Incorrect: /plugins/openvpnserver/scripts/rc.openvpnserver stop Correct: /plugins/openvpnserver/scripts/rc.openvpnserver&arg1=stop Link to comment
trurl Posted August 27, 2015 Share Posted August 27, 2015 Use: <input type="hidden" name="cmd" value="/plugins/openvpnserver/scripts/rc.openvpnserver[color=red]&arg1=[/color]stop"> Thanks, but where and how do I specify &arg1 You are specifying it by saying arg1=stop Link to comment
dmacias Posted August 27, 2015 Share Posted August 27, 2015 Use: <input type="hidden" name="cmd" value="/plugins/openvpnserver/scripts/rc.openvpnserver[color=red]&arg1=[/color]stop"> For some reason I could not get that to work. Log kept showing invalid command. I looked through update.php but couldn't figure out why $command === false. I didn't try too hard either. I just split the rc file into a start and stop script. Then tied those to event folder scripts also. Link to comment
trurl Posted August 27, 2015 Share Posted August 27, 2015 Posting this for another use who can't post in this subforum A) I can't reply to the thread for whatever reason. B) Relevant to the thread in question... He might need to XML Encode the &args1= portion to be &args1= since it's inside HTML value node. Link to comment
dmacias Posted August 28, 2015 Share Posted August 28, 2015 Posting this for another use who can't post in this subforum A) I can't reply to the thread for whatever reason. B) Relevant to the thread in question... He might need to XML Encode the &args1= portion to be &args1= since it's inside HTML value node. I'll try that with a different plugin. But truthfully it was just easier to split the rc script and remove the bash functions and case logic since I already was using javascript to update the post value anyway. Edit: I figured it out. Since I was using update.php I needed something like this. But I will just split rc.script and make a start and stop script since its cleaner. <code> <form name="deluged_settings" method="POST" action="/update.php" target="progressFrame"> <input type="hidden" name="#file" value="<?=$deluged_cfgfile;?>" /> <input type="hidden" id="command" name="#command" value="/usr/local/emhttp/plugins/deluged/scripts/rc.deluged" /> <input type="hidden" id="arg" name="#arg[0]" value="start" /> </code> Link to comment
limetech Posted August 28, 2015 Author Share Posted August 28, 2015 Posting this for another use who can't post in this subforum A) I can't reply to the thread for whatever reason. B) Relevant to the thread in question... He might need to XML Encode the &args1= portion to be &args1= since it's inside HTML value node. I'll try that with a different plugin. But truthfully it was just easier to split the rc script and remove the bash functions and case logic since I already was using javascript to update the post value anyway. Edit: I figured it out. Since I was using update.php I needed something like this. But I will just split rc.script and make a start and stop script since its cleaner. <code> <form name="deluged_settings" method="POST" action="/update.php" target="progressFrame"> <input type="hidden" name="#file" value="<?=$deluged_cfgfile;?>" /> <input type="hidden" id="command" name="#command" value="/usr/local/emhttp/plugins/deluged/scripts/rc.deluged" /> <input type="hidden" id="arg" name="#arg[0]" value="start" /> </code> Yes this method is best practice. Link to comment
PhAzE Posted August 31, 2015 Share Posted August 31, 2015 Use: <input type="hidden" name="cmd" value="/plugins/openvpnserver/scripts/rc.openvpnserver[color=red]&arg1=[/color]stop"> I'm using the update.htm file in my plugins and doing the above doesn't seem to work for me either. Here's my code currently: <form name="app_install" method="POST" action="/update.htm" target="progressFrame"> <input type="hidden" name="cmd" value="/plugins/<?=$appname;?>/scripts/rc.<?=$appname;?>&arg1=install"/> <input type="submit" name="runCmd" id="STDSMBUTTON" value="Install"/> </form> $appname in this case is "Btsync" by adding &arg1= above, it still doesn't actually pass that argument over to the script file. Is there another step I'm missing? Link to comment
peter_sm Posted August 31, 2015 Share Posted August 31, 2015 Hi! You can try this, I got info from Tom! I have no time right now to test ...... Using update.php is preferred: <tr> <td width="30%"> <form name="start_openvpnserver" method="POST" action="/update.php" target="progressFrame"> <input type="hidden" name="#command" value="/plugins/openvpnserver/scripts/rc.openvpnserver"> <input type="hidden" name="#arg[1]" value="start"> <input type="submit" value="start"> </form> </td> <td> <span class="red-text">Start OpenVPN Server</span></td> </tr> Link to comment
PhAzE Posted August 31, 2015 Share Posted August 31, 2015 Will update.php work on unraid 5 as well? My plugins are universal between the different unraid versions so I don't want to break the backwards compatibility on them. I'm guessing the cmd for update.htm is missing something (in my plugin) or broken in rc6...? Link to comment
bonienl Posted September 1, 2015 Share Posted September 1, 2015 Will update.php work on unraid 5 as well? My plugins are universal between the different unraid versions so I don't want to break the backwards compatibility on them. I'm guessing the cmd for update.htm is missing something (in my plugin) or broken in rc6...? No, update.php was introduced as part of Dynamix, which isn't present in unRAID v5. It is still possible to use update.htm / cmd in v6.1 though syntax has changed so you need to take care of that between old and new unRAID versions (if you want to keep compatibility). Link to comment
bonienl Posted September 1, 2015 Share Posted September 1, 2015 Use: <input type="hidden" name="cmd" value="/plugins/openvpnserver/scripts/rc.openvpnserver[color=red]&arg1=[/color]stop"> I'm using the update.htm file in my plugins and doing the above doesn't seem to work for me either. Here's my code currently: <form name="app_install" method="POST" action="/update.htm" target="progressFrame"> <input type="hidden" name="cmd" value="/plugins/<?=$appname;?>/scripts/rc.<?=$appname;?>&arg1=install"/> <input type="submit" name="runCmd" id="STDSMBUTTON" value="Install"/> </form> $appname in this case is "Btsync" by adding &arg1= above, it still doesn't actually pass that argument over to the script file. Is there another step I'm missing? Try the following <form name="app_install" method="POST" action="/update.htm" target="progressFrame"> [b] <input type="hidden" name="cmd" value="/plugins/<?=$appname;?>/scripts/rc.<?=$appname;?>&arg1=install"/>[/b] <input type="submit" id="STDSMBUTTON" value="Install"/> </form> Link to comment
PhAzE Posted September 1, 2015 Share Posted September 1, 2015 Thanks, that didn't seem to resolve it. Pressing the install button still just flashes the screen and reloads the page but the command is never passed to the server it seems. Link to comment
PhAzE Posted September 1, 2015 Share Posted September 1, 2015 Is there any include required for update.htm like there is with update.php? Link to comment
bonienl Posted September 1, 2015 Share Posted September 1, 2015 Thanks, that didn't seem to resolve it. Pressing the install button still just flashes the screen and reloads the page but the command is never passed to the server it seems. When you execute the command, check the syslog to see if the command is rejected (no message should mean it is executed). Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.