1

I would like to know how to run the php scripts which are stored in the database without using eval().

The expected process is as follow

When user POST a string which contains {{typed_alias }}, the system will search the table whether this alias has record in the alias column.

If yes -> replace what user typed with the correspond script which is stored in the replacement column.

If not -> show the original string including {{ wrong_alias }}

The expected result is as follow

When user posts
Hello, {{morninggg}}, the current unix time is {{nowTime}}

Array output from db

array

 0 =>
   array
     'ID' => 445
     'alias' => 'morning'
     'replacement' => 'Good morning'
 1 =>
   array
     'ID' => 446
     'alias' => 'nowTime'
     'replacement' => time()
 2 =>
   array
     'ID' => 447
     'alias' => 'tommorowNow'
     'replacement' => time()+86400

Return

Hello, {{morninggg}}, the current unix time is 147855220

Now I have already solved the database array by using foreach and also can replace the alias with script by using str_replace().

Current classI use to foreach data from database and do the replacement is as follow

class replace {
    public $definitions;

    public function setDefinitions($definitions) {
        $this->definitions = $definitions;
    }

    public function tag($input) {
        if($this->definitions && is_array($this->definitions)) {
            foreach ($this->definitions as $definition) {
                if($defintion['alias'] == 'time') {
                    $input = str_replace('{{' . $definition['alias'] . '}}', date('Y-m-d'), $input);
                } else {
                    $input = str_replace('{{' . $definition['alias'] . '}}', $definition['replacement'], $input);
                }
            }
        }
        return $input;
    }
}

Current using method

$replace = new replace();
$replace->setDefinitions($tagEngine);
$parsedString = $replace->tag($__input);

//$__input is what user POST to the server

echo $parsedString;

However, the current result is as follow

Hello, {{morninggg}}, the current unix time is time()

The script can't be run successfully on the page

But when I give the definition manually like this

$definition = array('morning' => 'Good Morning', 'nowTime' => time()); foreach ($definition as $key => $value) $source = str_replace('{{' . $key . '}}', $value, $source); return $source;

The script can be run and returns

Hello, {{morninggg}}, the current unix time is 147855220

I know that using eval() can run the scripts, however, it is regarded as a dangerous method in a real-world application by people.

Can anyone give me suggestions about how to deal with this problem?

Thank you!

4
  • I don't think there is any other way than using eval(), except not storing PHP code in your database. Which is exactly what you should do. Commented Dec 5, 2014 at 13:22
  • @Acule , thanks for your advice. But why can I run time() when I give the definition manually. Commented Dec 5, 2014 at 13:25
  • @Mark Because the database returns a string and eval() executes the string as code. Commented Dec 5, 2014 at 13:28
  • This sounds like a bad idea. If there is any security holes (such as a SQL injection hole), you've just opened up the ability for someone to execute their own code on your server, which could do anything from spamming, to distributing viruses and worse. I strongly recommend you add some logic to this, such as a special flag, then use if statements in your code to spot it's "special" and inject the relevant hard-coded value. And make sure you santitise your database inputs. Commented Dec 5, 2014 at 13:32

1 Answer 1

1

You should not use functions like eval() to fix this. You should pull all php-code out of your database and parse the different aliasses as follows (I have just altered the tag() method in the replace class:

public function tag($input) {
    if($this->definitions && is_array($this->definitions)) {
        foreach ($this->definitions as $definition) {
            $replacement = $definition['replacement'];
            switch($definition['alias']) {
                case 'nowTime':
                    $replacement = date('Y-m-d');
                    break;
                case 'tommorowNow':
                    $replacement = date('Y-m-d', (time() + 86400));
                    break;
            }
            $input = str_replace('{{' . $definition['alias'] . '}}', $replacement, $input);
        }
    }
    return $input;
}

As you can see, for every php-code alias, you can add another case in the switch() statement. You can read up on the switch() control structures at the following link:

PHP: switch - Manual

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.