{"id":50823,"date":"2020-11-08T03:01:25","date_gmt":"2020-11-07T17:01:25","guid":{"rendered":"http:\/\/www.rjmprogramming.com.au\/ITblog\/?p=50823"},"modified":"2020-11-07T21:51:08","modified_gmt":"2020-11-07T11:51:08","slug":"php-passthru-output-buffering-verb-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/php-passthru-output-buffering-verb-tutorial\/","title":{"rendered":"PHP Passthru Output Buffering Verb Tutorial"},"content":{"rendered":"<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php\"><img decoding=\"async\" style=\"float:left; border: 15px solid pink;\" alt=\"PHP Passthru Output Buffering Verb Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis_verb.jpg\" title=\"PHP Passthru Output Buffering Verb Tutorial\"  \/><\/a><p class=\"wp-caption-text\">PHP Passthru Output Buffering Verb Tutorial<\/p><\/div>\n<p>Yesterday&#8217;s <a title='PHP Passthru Output Buffering Security Tutorial' href='#phppobst'>PHP Passthru Output Buffering Security Tutorial<\/a> set up a framework for our tightened &#8220;defence&#8221; of our &#8220;Passthru&#8221; (PHP) web application woooooooorrrrrrrrlllllld view, but there is scope, still, to improve the &#8220;offence&#8221;, a move which affects &#8220;defence&#8221; as well <font size=1>(wouldn&#8217;t you know it?!)<\/font>.<\/p>\n<p>That improvement is to &#8230;<\/p>\n<blockquote><p>\ngenericize the verb\n<\/p><\/blockquote>\n<p> &#8230; which we find ourselves commonly doing (in our) programming, because of our penchant for functional (ie. action &#8220;verb&#8221;) rather than &#8220;object oriented&#8221; (ie. subject or object &#8220;noun&#8221;) way of writing the code.   In other words we tend to think of the whole problem in terms of action points to provide a solution, rather than thinking of the players and working out the roles and behaviours of those players.  It&#8217;s no big deal which approach you take, as long as you end up with the correct result, in a reasonably timely manner.<\/p>\n<p>For us, we often model a first draft of such a functional program (or web application) on the &#8220;verb&#8221; of primary interest,  resulting in our first draft containing several hardcodings of the word (or &#8220;verb&#8221;) &#8220;whatis&#8221;.  And so, &#8220;genericization&#8221;, for us, is often to turn that\/those &#8220;hardcoding(s)&#8221; into a variable that can be shared across that code base, hence the &#8220;early on&#8221; PHP codeline &#8230;<\/p>\n<p>&lt;?php<br \/>\n<code><br \/>\n $verb=\"whatis\";<br \/>\n<\/code><br \/>\n?&gt;<\/p>\n<p> &#8230; as a default first assumption (for the genericization), and a friendly approach for backward compatibility <font size=1>(another personal desire with our code)<\/font>.  What is such a &#8220;genericization drive&#8221;&#8216;s favourite accomplice?  For us, it is an HTML select (dropdown) element, as a &#8230;<\/p>\n<ul>\n<li>where there was one, &#8220;plug in&#8221; several<\/li>\n<li>take up little extra webpage room doing this<\/li>\n<li>the programmer controls the option contents<\/li>\n<\/ul>\n<p> &#8230; the stringency here being that, even for the &#8220;faux textbox entry possibilities&#8221; (because, yes, this &#8220;verb&#8221; will require its own separate argument <font size=1>(or will it?!)<\/font>), you must make sure its value is non-blank, and hence, as mentioned in that last point above, &#8220;the programmer controls the option contents&#8221;, and in that way, can control the implications of the &#8220;offence&#8221; additional functionality to the concerns of the &#8220;defence&#8221; security concerns of the programmer and web server hosting that PHP web application.<\/p>\n<p>So feel free to try out <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php--GETME\" title=\"whatis.php\">third changed whatis.php<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php--GETME\" title=\"whatis.php\">whatis.php<\/a> third incarnation of our &#8220;Passthru&#8221; verb (report) <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php\">web application<\/a>.<\/p>\n<p>Back to that &#8220;<font size=1>(or will it?!)<\/font>&#8221; question above, yes, for <a target=_blank title='Linux or unix curl information from computerhope' href='http:\/\/www.computerhope.com\/unix\/curl.htm'>Curl<\/a> purposes, where we try, for user&#8217;s sanity, to never involve more than one URL argument we allow the proposed &#8220;operating system&#8221; verb equate to the &#8220;name&#8221; in the classic &#8230;<\/p>\n<p><code>name=value<\/code><\/p>\n<p> &#8230; relative database (and other) architectures, allowing Curl users to encapsulate all they wish to convey to our web application in the one &#8230;<\/p>\n<p><code>curl HTTP:\/\/localhost:8888\/whatis.php?ping=127.0.0.1<\/code><\/p>\n<p> &#8230; example of a local (<a target=_blank title='MAMP for Apache\/PHP\/MySql on Mac OS X local web server' href='http:\/\/www.mamp.info'><i>MAMP<\/i><\/a>) web application call via curl (on the command line).<\/p>\n<p>Notice with the code below how we manipulate switches to help some operating system command line commands limit themselves to one iteration &#8230;<\/p>\n<p><code><br \/>\n&lt;?php<br \/>\n \/\/ whatis.php<br \/>\n \/\/ Supervise whatis command<br \/>\n \/\/ November, 2020<br \/>\n<br \/>\n $verb=\"whatis\";<br \/>\n<br \/>\n function retpins($pins, $reld) {<br \/>\n   global $verb;<br \/>\n   if ($verb == \"who\" && trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") {<br \/>\n   $pins=urlencode(\"-H\");<br \/>\n   if ($reld) {<br \/>\n   echo \"&lt;html&gt;&lt;body onload=\\\"location.href=document.URL.split('#')[0] + encodeURIComponent('-H');\\\"&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n   exit;<br \/>\n   }<br \/>\n   } else if ($verb == \"screencapture\" && trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") {<br \/>\n   $pins=urlencode(\"-c\");<br \/>\n   if ($reld) {<br \/>\n   echo \"&lt;html&gt;&lt;body onload=\\\"location.href=document.URL.split('#')[0] + encodeURIComponent('-c');\\\"&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n   exit;<br \/>\n   }<br \/>\n   } else if ($verb == \"ping\" && trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") {<br \/>\n   $pins=urlencode(\"-o\");<br \/>\n   if ($reld) {<br \/>\n   echo \"&lt;html&gt;&lt;body onload=\\\"location.href=document.URL.split('#')[0] + encodeURIComponent('-o');\\\"&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n   exit;<br \/>\n   }<br \/>\n   } else if ($verb == \"top\" && trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") {<br \/>\n   $pins=urlencode(\"-l 1\");<br \/>\n   if ($reld) {<br \/>\n   echo \"&lt;html&gt;&lt;body onload=\\\"location.href=document.URL.split('#')[0] + encodeURIComponent('-l 1');\\\"&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n   exit;<br \/>\n   }<br \/>\n   } else if ($verb == \"tree\" && trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") {<br \/>\n   $pins=urlencode(\"c:\");<br \/>\n   if ($reld) {<br \/>\n   echo \"&lt;html&gt;&lt;body onload=\\\"location.href=document.URL.split('#')[0] + encodeURIComponent('c:');\\\"&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n   exit;<br \/>\n   }<br \/>\n   } else if (trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") { \/\/ if ($verb == \"uptime\" && trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") {<br \/>\n   $pins=urlencode(\";\");<br \/>\n   if ($reld) {<br \/>\n   echo \"&lt;html&gt;&lt;body onload=\\\"location.href=document.URL.split('#')[0] + encodeURIComponent(';');\\\"&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n   exit;<br \/>\n   }<br \/>\n   }<br \/>\n   return $pins;<br \/>\n }<br \/>\n<br \/>\n function maybe($iv) {<br \/>\n   if ($iv == \"ping\") { return \"ping -o\"; }<br \/>\n   return $iv;<br \/>\n }<br \/>\n<br \/>\n $verbs=array(\"whatis\", \"man\", \"jobs\", \"ping\", \"uname\", \"help\");<br \/>\n $insh='insearch';<br \/>\n $sayopt='';<br \/>\n<br \/>\n $meth=\"POST\";<br \/>\n if (strpos((\"~\" . strtolower($_SERVER['SERVER_NAME'])), '~localhost') !== false) { $meth=\"GET\"; }<br \/>\n<br \/> <br \/>\n if (PHP_OS === \"Darwin\") {<br \/>\n   array_push($verbs, \"say\", \"textutil\", \"screencapture\", \"who\", \"uptime\", \"top\", \"hostname\");<br \/>\n } else if ($meth == \"GET\" && strtoupper(substr((PHP_OS . '   '), 0, 3)) === 'WIN') {<br \/>\n   $verbs=array(\"tree\", \"ping\", \"help\", \"echo\");<br \/>\n   $verb=\"tree\";<br \/>\n } else { \/\/if ($meth == \"GET\") {<br \/>\n   array_push($verbs, \"uptime\", \"echo\");<br \/>\n }<br \/>\n<br \/>\n foreach ($verbs as $value) {<br \/>\n   $sayopt.='&lt;option value=' . $value . '&gt;' . $value . '&lt;\/option&gt;';<br \/>\n }<br \/>\n<br \/>\n $gb=\"\";<br \/>\n try {<br \/>\n  if (strpos(('~' . $_SERVER['HTTP_USER_AGENT']), '~curl') === false) {<br \/>\n    $gb=\"y\";<br \/>\n  }<br \/>\n } catch (Exception $ee) {<br \/>\n }<br \/>\n<br \/>\n if (isset($_POST['verb'])) {<br \/>\n   if (trim(str_replace(\"+\",\" \",urldecode($_POST['verb']))) != '') { $verb=str_replace(\"+\",\" \",urldecode($_POST['verb'])); }<br \/>\n } else if (isset($_GET['verb'])) {<br \/>\n   if (trim(str_replace(\"+\",\" \",urldecode($_GET['verb']))) != '') { $verb=str_replace(\"+\",\" \",urldecode($_GET['verb'])); }<br \/>\n }<br \/>\n<br \/>\n foreach ($verbs as $value) {<br \/>\n if (isset($_POST[$value])) {<br \/>\n   $insh=$value;<br \/>\n   $verb=$value;<br \/>\n } else if (isset($_GET[$value])) {<br \/>\n   $insh=$value;<br \/>\n   $verb=$value;<br \/>\n }<br \/>\n }<br \/>\n<br \/>\n $pins='';<br \/>\n if (isset($_POST[$insh]) && strpos(strtolower('' . $_SERVER['HTTP_REFERER']), \"rjmprogramming.com.au\") !== false) {<br \/>\n   $pins=retpins($_POST[$insh],false);<br \/>\n } else if (isset($_GET[$insh]) && strpos(strtolower('' . $_SERVER['HTTP_REFERER']), \"\/localhost\") !== false) {<br \/>\n   $pins=retpins($_GET[$insh],true);<br \/>\n } else if ($meth == \"GET\" && isset($_GET[$insh])) {<br \/>\n   $pins=$_GET[$insh];<br \/>\n   if ($verb == \"who\" && trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") {<br \/>\n   $pins=urlencode(\"-H\");<br \/>\n   } else if ($verb == \"screencapture\" && trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") {<br \/>\n   $pins=urlencode(\"-c\");<br \/>\n   } else if ($verb == \"ping\" && trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") {<br \/>\n   $pins=urlencode(\"-l 1\");<br \/>\n   } else if ($verb == \"top\" && trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") {<br \/>\n   $pins=urlencode(\"-o\");<br \/>\n   } else if ($verb == \"tree\" && trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") {<br \/>\n   $pins=urlencode(\"c:\");<br \/>\n   } else if (trim(str_replace(\"+\",\" \",urldecode($pins))) == \"\") {<br \/>\n   $pins=urlencode(\";\");<br \/>\n   } else {<br \/>\n   $pins=$_GET[$insh];<br \/>\n   }<br \/>\n } else if ($meth == \"GET\") {<br \/>\n   $pins=' ';<br \/>\n }<br \/>\n<br \/>\n if (trim($pins) != '' && !isset($argv)) {<br \/>\n   if (urldecode($pins) == '') {<br \/>\n     echo \"&lt;html&gt;&lt;head&gt;&lt;title&gt;Operating System \" . maybe($verb) . \" -- RJM Programming - November, 2020&lt;\/title&gt;&lt;\/head&gt;&lt;body onload=\\\" document.getElementById('insearch').focus(); \\\"&gt;&lt;form action=.\/whatis.php method=\" . $meth . \"&gt;&lt;h1&gt;Supervise &lt;select title=verb name=verb&gt;\" . $sayopt . \"&lt;\/select&gt; command&lt;\/h1&gt;&lt;h3&gt;RJM Programming - November, 2020&lt;\/h3&gt;&lt;br&gt;&lt;br&gt;&lt;input placeholder='Enter object' type=text id=insearch name=insearch value=''&gt;&lt;\/input&gt;&nbsp;&lt;input type=submit value=Go&gt;&lt;\/input&gt;&lt;\/form&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n   } else if ($meth == \"GET\" && $gb == \"\") {<br \/>\n     passthru(maybe($verb) . \" \" . explode(\"\\n\",explode(\"\\r\",explode(\";\",explode(\"&lt;\",explode(\"&gt;\",explode(\"|\",str_replace(\"+\",\" \",urldecode($pins)))[0])[0])[0])[0])[0])[0]);<br \/>\n   } else {<br \/>\n     ob_start();<br \/>\n     passthru(maybe($verb) . \" \" . explode(\"\\n\",explode(\"\\r\",explode(\";\",explode(\"&lt;\",explode(\"&gt;\",explode(\"|\",str_replace(\"+\",\" \",urldecode($pins)))[0])[0])[0])[0])[0])[0]);<br \/>\n     $var = ob_get_contents();<br \/>\n     ob_end_clean();<br \/>\n     echo \"&lt;html&gt;&lt;head&gt;&lt;title&gt;Operating System \" . maybe($verb) . \" \" . explode(\"\\n\",explode(\"\\r\",explode(\";\",explode(\"&lt;\",explode(\"&gt;\",explode(\"|\",str_replace(\"+\",\" \",urldecode($pins)))[0])[0])[0])[0])[0])[0] . \" - RJM Programming -- November, 2020&lt;\/title&gt;&lt;\/head&gt;&lt;body onload=\\\" document.getElementById('insearch').focus(); \\\"&gt;&lt;pre&gt;$ \" . $verb . \" \" . explode(\"\\n\",explode(\"\\r\",explode(\";\",explode(\"&lt;\",explode(\"&gt;\",explode(\"|\",str_replace(\"+\",\" \",urldecode($pins)))[0])[0])[0])[0])[0])[0] . \"&lt;br&gt;\" . str_replace(\"\\n\", \"&lt;br&gt;\", $var) . \"&lt;\/pre&gt;&lt;br&gt;&lt;br&gt;&lt;form action=.\/whatis.php method=\" . $meth . \"&gt;&lt;h1&gt;Supervise &lt;select title=verb name=verb&gt;\" . $sayopt . \"&lt;\/select&gt; command&lt;\/h1&gt;&lt;h3&gt;RJM Programming - November, 2020&lt;\/h3&gt;&lt;br&gt;&lt;br&gt;&lt;input placeholder='Enter object' type=text id=insearch name=insearch value=''&gt;&lt;\/input&gt;&nbsp;&lt;input type=submit value=Go&gt;&lt;\/input&gt;&lt;\/form&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n     exit;<br \/>\n   }<br \/>\n } else if (!isset($argv) && ($pins == '' || (trim($pins) == '' && $meth == \"GET\")) && !isset($_GET[$insh]) && $gb != \"\") {<br \/>\n   echo \"&lt;html&gt;&lt;head&gt;&lt;title&gt;Operating System verb - RJM Programming - November, 2020&lt;\/title&gt;&lt;\/head&gt;&lt;body onload=\\\" document.getElementById('insearch').focus(); \\\"&gt;&lt;form action=.\/whatis.php method=\" . $meth . \"&gt;&lt;h1&gt;Supervise &lt;select title=verb name=verb&gt;\" . $sayopt . \"&lt;\/select&gt; command&lt;\/h1&gt;&lt;h3&gt;RJM Programming - November, 2020&lt;\/h3&gt;&lt;br&gt;&lt;br&gt;&lt;input placeholder='Enter object' type=text id=insearch name=insearch value=''&gt;&lt;\/input&gt;&nbsp;&lt;input type=submit value=Go&gt;&lt;\/input&gt;&lt;\/form&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n }<br \/>\n<br \/>\n?&gt;<br \/>\n<\/code><\/p>\n<p><!--p>You can also see this play out at WordPress 4.1.1's <a target=_blank  href='\/\/www.rjmprogramming.com.au\/ITblog\/php-passthru-output-buffering-verb-tutorial\/'>PHP Passthru Output Buffering Verb Tutorial<\/a>.<\/p-->\n<hr>\n<p id='phppobst'>Previous relevant <a target=_blank title='PHP Passthru Output Buffering Security Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/php-passthru-output-buffering-security-tutorial\/'>PHP Passthru Output Buffering Security Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php\"><img decoding=\"async\" style=\"float:left; border: 15px solid pink;\" alt=\"PHP Passthru Output Buffering Security Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis_defence_one.jpg\" title=\"PHP Passthru Output Buffering Security Tutorial\"  \/><\/a><p class=\"wp-caption-text\">PHP Passthru Output Buffering Security Tutorial<\/p><\/div>\n<p>Serverside web applications <font size=1>(such as this current PHP one)<\/font>, more so than purely clientside web applications, are a bit like a lot of sports &#8230;<\/p>\n<ul>\n<li>there is the &#8220;offence&#8221; functionality side that provides a product or service to the user &#8230; as well as &#8230;<\/li>\n<li>there is the &#8220;defence&#8221; functionality side, depending on the architecture of the web application, that concerns itself with security<\/li>\n<\/ul>\n<p> &#8230; and our signature &#8220;Passthru&#8221; &#8220;whatis&#8221; web application ticks a lot of the boxes asking for a good &#8220;defence&#8221;.  Why?<\/p>\n<ul>\n<li>the (PHP serverside) web application accepts user input from a textbox, and feeds it back to itself via an HTML form, to perform more <i>underlying operating system<\/i> actions<\/li>\n<li>in the <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php_GETME\" title=\"whatis.php\">first incarnation of whatis.php<\/a> we set that form to method=GET &#8230; which makes it just too easy to have the worries below be a relevant (bad for security) issue<\/li>\n<li>if that <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php_GETME\" title=\"whatis.php\">first incarnation of whatis.php<\/a> was still current on the rjmprogramming.com.au website we could have circumvented any textbox validation we might have implemented (in a clientside sense) with whatever a savvy user might want to refeed into the web application via either &#8230;\n<ol>\n<li>web address bar URL like (for &#8220;whatis find&#8221;) &#8230;<br \/>\n<code>HTTP:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php?insearch=find<\/code>\n<\/li>\n<li>curl (command line entry (for &#8220;whatis find&#8221;)) &#8230;<br \/>\n<code>curl HTTP:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php?insearch=find<\/code>\n<\/li>\n<\/ol>\n<p> &#8230; as <i>benign<\/i> examples of the modus operandi\n<\/li>\n<\/ul>\n<p> &#8230; but what if the motivations of a user are not <i>benign<\/i>?   Well, yesterday&#8217;s <a href='#poops' title='Security Oops!'>Stop Press <font color=red>Oops!<\/font> intervention<\/a> is a case in point.  It is a &#8230;<\/p>\n<ul>\n<li>security issue, up to the programmer, for such &#8220;underlying operating system&#8221; leaning web applications to close things down as far as the role that textbox user input (or faux ones) so that you do not allow (and in doing so, not needing <font size=1>(and so we are not doing any as of this second incarnation)<\/font> any textbox validation that could cut off at a semicolon or less than sign or greater than sign or vertical (pipe) line character or line feed or carriage return, that textbox validation though could be used as a &#8220;virtue signal&#8221;) &#8230;\n<ol>\n<li>the user input data to contain a multi-command aspect to it &#8230; via scrutiny of $_POST[&#8216;insearch&#8217;] and\/or  $_GET[&#8216;insearch&#8217;] (if a <i>localhost<\/i> web server name in $_SERVER[&#8216;SERVER_NAME&#8217;])<\/li>\n<li>the user input data, yesterday and today, all along, at least ties down that &#8220;verb&#8221; word of the &#8220;operating system via PHP<br \/>\n passthru&#8221; command line <i>command<\/i> first (and all important) word (ie. hardcoded &#8220;whatis &#8220;)<\/li>\n<li>the user input data, yesterday and today, all along, at least ties down that &#8220;verb&#8221; word of the &#8220;operating system via PHP passthru&#8221; command line <i>command<\/i> switches the user might define that cause web server damage (though with &#8220;whatis&#8221; we could not think of any)<\/li>\n<li>call of web application must come from expected place &#8230; via examination of $_SERVER[&#8216;REFERER&#8217;]<\/li>\n<\/ol>\n<p> &#8230; the HTML form method=POST preferable to method=GET for those reasons already talked about\n<\/li>\n<li>limit modes of use as per table below &#8230;<br \/>\n<table border=1>\n<tr>\n<th>PHP Mode of use<\/th>\n<th>localhost web server<\/th>\n<th>rjmprogramming.com.au web server<\/th>\n<\/tr>\n<tr>\n<td>Surfing the web &#8230; no &#8220;whatis&#8221; user input<\/td>\n<td>Allowed (shows textbox for user input)<\/td>\n<td>Allowed (shows textbox for user input)<\/td>\n<\/tr>\n<tr>\n<td>Surfing the web &#8230; &#8220;whatis&#8221; user input<\/td>\n<td>Allowed (method=GET)<\/td>\n<td>Allowed (method=POST only)<\/td>\n<\/tr>\n<tr>\n<td>Curl &#8230; no &#8220;whatis&#8221; user input<\/td>\n<td>Allowed (nothing returned)<\/td>\n<td>Not allowed (nothing returned)<\/td>\n<\/tr>\n<tr>\n<td>Curl (NB. curl can (method=)POST) &#8230; &#8220;whatis&#8221; user input<\/td>\n<td>Allowed (via command line ? argument simulating method=GET)<\/td>\n<td>Not allowed (nothing returned)<\/td>\n<\/tr>\n<tr>\n<td>Command line &#8230; no &#8220;whatis&#8221; user input<\/td>\n<td>Not allowed (nothing returned)<\/td>\n<td>Not allowed (nothing returned)<\/td>\n<\/tr>\n<tr>\n<td>Command line &#8230; &#8220;whatis&#8221; user input<\/td>\n<td>Erroneous (Could not open input file: whatis.php?insearch=find)<\/td>\n<td>Erroneous (Could not open input file: whatis.php?insearch=find)<\/td>\n<\/tr>\n<\/table>\n<\/li>\n<\/ul>\n<p> &#8230; causing what we hope to be a similarly functional <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php-GETME\" title=\"whatis.php\">second changed whatis.php<\/a>, yet considerably more secure <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php-GETME\" title=\"whatis.php\">whatis.php<\/a> second incarnation of our &#8220;Passthru&#8221; &#8220;whatis&#8221; (report) <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php\">web application<\/a> improvement to <a title='PHP Passthru Output Buffering Primer Tutorial' href='#phppobpt'>PHP Passthru Output Buffering Primer Tutorial<\/a> &#8230;<\/p>\n<p><code><br \/>\n&lt;?php<br \/>\n \/\/ whatis.php<br \/>\n \/\/ Supervise whatis command<br \/>\n \/\/ November, 2020<br \/>\n<br \/> <br \/>\n $meth=\"POST\";<br \/>\n if (strpos((\"~\" . strtolower($_SERVER['SERVER_NAME'])), '~localhost') !== false) { $meth=\"GET\"; }<br \/>\n<br \/> <br \/>\n $gb=\"\";<br \/>\n try {<br \/>\n  if (strpos(('~' . $_SERVER['HTTP_USER_AGENT']), '~curl') === false) {<br \/>\n    $gb=\"y\";<br \/>\n  }<br \/>\n } catch (Exception $ee) {<br \/>\n }<br \/>\n<br \/> <br \/>\n $pins='';<br \/>\n if (isset($_POST['insearch']) && strpos(strtolower('' . $_SERVER['HTTP_REFERER']), \"rjmprogramming.com.au\") !== false) {<br \/>\n   $pins=$_POST['insearch'];<br \/>\n } else if (isset($_GET['insearch']) && strpos(strtolower('' . $_SERVER['HTTP_REFERER']), \"\/localhost\") !== false) {<br \/>\n   $pins=$_GET['insearch'];<br \/>\n } else if ($meth == \"GET\" && isset($_GET['insearch'])) {<br \/>\n   $pins=$_GET['insearch'];<br \/>\n } else if ($meth == \"GET\") {<br \/>\n   $pins=' ';<br \/>\n }<br \/>\n<br \/> <br \/>\n if (trim($pins) != '' && !isset($argv)) {<br \/>\n   if (urldecode($pins) == '') {<br \/>\n     echo \"&lt;html&gt;&lt;body onload=\\\" document.getElementById('insearch').focus(); \\\"&gt;&lt;h1&gt;Supervise whatis command&lt;\/h1&gt;&lt;h3&gt;RJM Programming - November, 2020&lt;\/h3&gt;&lt;br&gt;&lt;br&gt;&lt;form action=.\/whatis.php method=\" . $meth . \"&gt;&lt;input placeholder='Enter whatis object' type=text id=insearch name=insearch value=''&gt;&lt;\/input&gt;&nbsp;&lt;input type=submit value=Go&gt;&lt;\/input&gt;&lt;\/form&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n   } else if ($meth == \"GET\" && $gb == \"\") {<br \/>\n     passthru(\"whatis \" . explode(\"\\n\",explode(\"\\r\",explode(\";\",explode(\"&lt;\",explode(\"&gt;\",explode(\"|\",str_replace(\"+\",\" \",urldecode($pins)))[0])[0])[0])[0])[0])[0]);<br \/>\n   } else {<br \/>\n     ob_start();<br \/>\n     passthru(\"whatis \" . explode(\"\\n\",explode(\"\\r\",explode(\";\",explode(\"&lt;\",explode(\"&gt;\",explode(\"|\",str_replace(\"+\",\" \",urldecode($pins)))[0])[0])[0])[0])[0])[0]);<br \/>\n     $var = ob_get_contents();<br \/>\n     ob_end_clean();<br \/>\n     echo \"&lt;html&gt;&lt;body onload=\\\" document.getElementById('insearch').focus(); \\\"&gt;&lt;pre&gt;$ whatis \" . explode(\"\\n\",explode(\"\\r\",explode(\";\",explode(\"&lt;\",explode(\"&gt;\",explode(\"|\",str_replace(\"+\",\" \",urldecode($pins)))[0])[0])[0])[0])[0])[0] . \"&lt;br&gt;\" . str_replace(\"\\n\", \"&lt;br&gt;\", $var) . \"&lt;\/pre&gt;&lt;br&gt;&lt;br&gt;&lt;h1&gt;Supervise whatis command&lt;\/h1&gt;&lt;h3&gt;RJM Programming - November, 2020&lt;\/h3&gt;&lt;br&gt;&lt;br&gt;&lt;form action=.\/whatis.php method=\" . $meth . \"&gt;&lt;input placeholder='Enter whatis object' type=text id=insearch name=insearch value=''&gt;&lt;\/input&gt;&nbsp;&lt;input type=submit value=Go&gt;&lt;\/input&gt;&lt;\/form&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n     exit;<br \/>\n   }<br \/>\n } else if (!isset($argv) && ($pins == '' || (trim($pins) == '' && $meth == \"GET\")) && !isset($_GET[$insh]) && $gb != \"\") {<br \/>\n   echo \"&lt;html&gt;&lt;body onload=\\\" document.getElementById('insearch').focus(); \\\"&gt;&lt;h1&gt;Supervise whatis command&lt;\/h1&gt;&lt;h3&gt;RJM Programming - November, 2020&lt;\/h3&gt;&lt;br&gt;&lt;br&gt;&lt;form action=.\/whatis.php method=\" . $meth . \"&gt;&lt;input placeholder='Enter whatis object' type=text id=insearch name=insearch value=''&gt;&lt;\/input&gt;&nbsp;&lt;input type=submit value=Go&gt;&lt;\/input&gt;&lt;\/form&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n }<br \/>\n<br \/> <br \/>\n?&gt;<br \/>\n<\/code><\/p>\n<p><!--p>You can also see this play out at WordPress 4.1.1's <a target=_blank  href='\/\/www.rjmprogramming.com.au\/ITblog\/php-passthru-output-buffering-security-tutorial\/'>PHP Passthru Output Buffering Security Tutorial<\/a>.<\/p-->\n<hr>\n<p id='phppobpt'>Previous relevant <a target=_blank title='PHP Passthru Output Buffering Primer Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/php-passthru-output-buffering-primer-tutorial\/'>PHP Passthru Output Buffering Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php\"><img decoding=\"async\" style=\"float:left; border: 15px solid pink;\" alt=\"PHP Passthru Output Buffering Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.jpg\" title=\"PHP Passthru Output Buffering Primer Tutorial\"  \/><\/a><p class=\"wp-caption-text\">PHP Passthru Output Buffering Primer Tutorial<\/p><\/div>\n<p>The PHP <a target=_blank title='PHP passthru() method information' href='http:\/\/php.net\/manual\/en\/function.passthru.php'><i>passthru<\/i><\/a> command &#8230;<\/p>\n<blockquote cite='https:\/\/www.php.net\/manual\/en\/function.passthru.php'><p>\nExecute an external program and display raw output\n<\/p><\/blockquote>\n<p> &#8230; is a good way for your underlying command line be expressed within a PHP web application executed in a web browser.<\/p>\n<p>But that &#8220;raw&#8221; above is just that, very &#8220;raw&#8221; in that the neat reports you see with Linux and macOS commands (at the command line) will not show that neatly just by using &#8220;passthru&#8221;.<\/p>\n<p>But you can use PHP output buffers <font color=blue>as per<\/font> <font size=1 color=red>(but there&#8217;s more)<\/font> &#8230;<\/p>\n<p><code><br \/>\n&lt;?php<br \/>\n \/\/ whatis.php<br \/>\n \/\/ Supervise whatis command<br \/>\n \/\/ November, 2020<br \/>\n if (isset($_GET['insearch'])) {<br \/>\n   if (urldecode($_GET['insearch']) == '') {<br \/>\n     echo \"&lt;html&gt;&lt;body onload=\\\" document.getElementById('insearch').focus(); \\\"&gt;&lt;h1&gt;Supervise whatis command&lt;\/h1&gt;&lt;h3&gt;RJM Programming - November, 2020&lt;\/h3&gt;&lt;br&gt;&lt;br&gt;&lt;form action=.\/whatis.php method=GET&gt;&lt;input placeholder='Enter whatis object' type=text id=insearch name=insearch value=''&gt;&lt;\/input&gt;&nbsp;&lt;input type=submit value=Go&gt;&lt;\/input&gt;&lt;\/form&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n   } else {<br \/>\n     <font color=blue><a target=_blank title='PHP ob_start method information' href='http:\/\/php.net\/manual\/en\/function.ob-start.php'>ob_start<\/a>();<\/font><br \/>\n     passthru(\"whatis \" . <font color=red>explode(\"\\n\",explode(\"\\r\",explode(\";\",<\/font>explode(\"&lt;\",explode(\"&gt;\",explode(\"|\",str_replace(\"+\",\" \",urldecode($_GET['insearch'])))[0])[0])[0]<font color=red>)[0])[0])[0]<\/font>);<br \/>\n     <font color=blue>$var = <a target=_blank title='PHP ob_get_contents method information' href='http:\/\/php.net\/manual\/en\/function.ob-get-contents.php'>ob_get_contents<\/a>();<br \/>\n     <a target=_blank title='PHP ob_end_clean method information' href='http:\/\/php.net\/manual\/en\/function.ob-end-clean.php'>ob_end_clean<\/a>();<\/font><br \/>\n     echo \"&lt;html&gt;&lt;body onload=\\\" document.getElementById('insearch').focus(); \\\"&gt;&lt;pre&gt;\" . <font color=blue>\"$ whatis \" . <font color=red>explode(\"\\n\",explode(\"\\r\",explode(\";\",<\/font>explode(\"&lt;\",explode(\"&gt;\",explode(\"|\",str_replace(\"+\",\" \",urldecode($_GET['insearch'])))[0])[0])[0]<font color=red>)[0])[0])[0]<\/font> . \"&lt;br&gt;\" . str_replace(\"\\n\", \"&lt;br&gt;\", $var)<\/font> . \"&lt;\/pre&gt;&lt;br&gt;&lt;br&gt;&lt;h1&gt;Supervise whatis command&lt;\/h1&gt;&lt;h3&gt;RJM Programming - November, 2020&lt;\/h3&gt;&lt;br&gt;&lt;br&gt;&lt;form action=.\/whatis.php method=GET&gt;&lt;input placeholder='Enter whatis object' type=text id=insearch name=insearch value=''&gt;&lt;\/input&gt;&nbsp;&lt;input type=submit value=Go&gt;&lt;\/input&gt;&lt;\/form&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n     exit;<br \/>\n   }<br \/>\n } else {<br \/>\n   echo \"&lt;html&gt;&lt;body onload=\\\" document.getElementById('insearch').focus(); \\\"&gt;&lt;h1&gt;Supervise whatis command&lt;\/h1&gt;&lt;h3&gt;RJM Programming - November, 2020&lt;\/h3&gt;&lt;br&gt;&lt;br&gt;&lt;form action=.\/whatis.php method=GET&gt;&lt;input placeholder='Enter whatis object' type=text id=insearch name=insearch value=''&gt;&lt;\/input&gt;&nbsp;&lt;input type=submit value=Go&gt;&lt;\/input&gt;&lt;\/form&gt;&lt;\/body&gt;&lt;\/html&gt;\";<br \/>\n }<br \/>\n<br \/>\n?&gt;<br \/>\n<\/code><\/p>\n<p> &#8230; to effectively reinstate those carriage return\/line feeds that make the &#8220;passthru&#8221; (underlying operating system) commands those neat reports appealing to our eyes.<\/p>\n<p>Better on a local <a target=_blank title='MAMP for Apache\/PHP\/MySql on Mac OS X local web server' href='http:\/\/www.mamp.info'><i>MAMP<\/i><\/a> web server (under macOS operating system) is today&#8217;s proof of concept <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php_GETME\" title=\"whatis.php\">whatis.php<\/a>&#8216;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/whatis.php\" title=\"Click picture\">&#8220;whatis&#8221; command supervisor<\/a> PHP web application for you to try out (or perhaps download to a local web server).<\/p>\n<p id=poops><i><b><font color=red>Stop Press<\/font><\/b><\/i><\/p>\n<p><font color=red>Oops!<\/font><\/p>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d50785' onclick='var dv=document.getElementById(\"d50785\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/passthru\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d50785' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d50797' onclick='var dv=document.getElementById(\"d50797\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/security\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d50797' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d50823' onclick='var dv=document.getElementById(\"d50823\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/verb\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d50823' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Yesterday&#8217;s PHP Passthru Output Buffering Security Tutorial set up a framework for our tightened &#8220;defence&#8221; of our &#8220;Passthru&#8221; (PHP) web application woooooooorrrrrrrrlllllld view, but there is scope, still, to improve the &#8220;offence&#8221;, a move which affects &#8220;defence&#8221; as well (wouldn&#8217;t &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/php-passthru-output-buffering-verb-tutorial\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,29,37],"tags":[3028,168,234,284,3471,452,471,1839,1533,3362,744,1830,3467,853,3468,2427,932,970,997,1114,1866,1200,1231,1319,1358,1865,3470,3469],"class_list":["post-50823","post","type-post","status-publish","format-standard","hentry","category-elearning","category-operating-system","category-tutorials","tag-action","tag-buffer","tag-command-line","tag-curl","tag-dropdowm","tag-form","tag-function","tag-genericization","tag-get","tag-hardcoding","tag-mamp","tag-method","tag-ob_get_contents","tag-ob_start","tag-output-buffer","tag-passthru","tag-php","tag-post","tag-programming","tag-security","tag-select","tag-stop-press","tag-switches","tag-tutorial","tag-validation","tag-verb","tag-virtue-signal","tag-whatis"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/50823"}],"collection":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/comments?post=50823"}],"version-history":[{"count":13,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/50823\/revisions"}],"predecessor-version":[{"id":50836,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/50823\/revisions\/50836"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=50823"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=50823"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=50823"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}