I just viewed a very nice #31c3 talk about a well known issue with certain functions within two very widely used perl-modules (DBI & CGI).
When I heard the arguments brought to the presenter from the audience
within the Q&A, I thought to myself, well, they’re right. All of these
attack vectors are in theory something that could have been prevented by
just flatten arguments (as you always should). Then again, this makes
for a really, really messy programming style that does not come easy if
you were programming any other programming language prior to perl.
Lucky me, I started programming with perl. I think within the third
script I used the first own functions and within my fourth script I
realised that it is probably best for everyone to start all your
functions this way:
sub myFunc {
my ( $arg1, $arg2, $arg3 ) = @_;
...
return $result;
}
Then again, this is very, very bad style. I remember how amazed I was when I had to construct something in PHP as a backend for a small webapp, and it was very easy to ask the interpreter if and how many arguments all my user-defined functions need. This is unthinkable in Perl and just one line in PHP.
$functions = get_defined_functions()['user'];
This is very beautiful and allowed me a thing which is probably insane securitywise, but worked in my case like a charm. The following is a handler in PHP, that allows you to define any user-defined function within the URL param “action”, pass it anything wichin the URL param “data” and display the result as JSON. I am now using this as a template for small webapps to provide async data from php/mysql.
<?php
//we will ALWAYS RETURN JSON, so we might as well set the header now:
header('Content-type: application/json');
//all your functions here, remember functions either take no or one parameter, the parameter can be an object, map, array or whatever
//FROM HERE INPUT HANDLING
$allowed = get_defined_functions()['user'];
//DEBUG:
//print_r($allowed);
if( $_REQUEST['action'] && in_array($_REQUEST['action'],$allowed) ) {
if(array_key_exists('data', $_REQUEST)){
$return = call_user_func($_REQUEST['action'],($_REQUEST['data']));
}
elseif (need_params($_REQUEST['action']) == 0) {
$return = call_user_func($_REQUEST['action']);
}
else {
$return = array( 'danger' => 'The action '.$_REQUEST['action'].' requires a parameter, please define "data" with a correct value');
}
echo(json_encode($return));
exit;
}
//if nothing happened up until now ... well something is very wrong, let's state that correctly:
$returnvalue = array( 'warning' => 'I believe you did not give me anything to do, that makes me very sad!');
echo(json_encode($returnvalue));
?>
So here you go, this is basically a very small framework that allows you to expose any data whatsorever via simple HTTP requests to your webapp. It is certainly not perfect, because I am a real PHP noob, but I thought it might be worth a share.