Eigene Template Engine und die Gefahr von eval()

NTDY

Erfahrenes Mitglied
Ich würde gern einige Anregungen haben wollen.
Hier ist ein Beispielskript einer Template-Engine, die ein Template auf if-endif Platzhalter analysiert und diesen dann mit richtigen PHP Code ersetzt und über eval() ausgibt. Gibt es Sicherheitsprobleme in dieser hier erstellten Fassung, wenn im Template bereits richtiger PHP Code abgefangen wird?

PHP:
<?php
class Template{
  function parse($file){
  // remove given php code in template file
  $file = preg_replace('/^<\?php(.*)(\?>)?$/s', '$1', $file);

  // if condition of template engine
  $ifCond = '/\{if (.*?)\}(.*?)\{\/(endif)\}/ise';
  if(preg_match($ifCond,$file,$result)){
  $beginIf = $result[1];
  $content = $result[2];
  $endIf = $result[3];
  return $this->conditionIf($beginIf,$content,$endIf);
  }
  }

  function conditionIf($beginIf,$content,$endIf) {
  $output = "<?php if($beginIf) { echo \"$content\";};?>";
  return $output;
  }
}

$file = file_get_contents('file.txt');
$tmpl = new Template();
$content = $tmpl->parse($file);
$check = 1;

$content = "?> ".$content;
ob_start();
eval($content);
$content = ob_get_contents();
?>

Template Datei: file.txt
PHP:
{if $check==1}
Hallo mein IF.
{/endif}
 
Du kannst damit beliebigen PHP-Code ausführen.

Eine Variante:

Code:
{if eval(base64_decode("Zm9yICgkaSA9IDA7ICRpIDw9IDEwMDA7ICRpKyspIGVjaG8gJGkgLiAiXG4iOw=="))}
Hallo mein IF.
{/endif}

Die Base64-Daten enthalten diesen Code: for ($i = 0; $i <= 1000; $i++) echo $i . "\n";

(Es stimmt in diesem Fall, aber solche Angaben besser nie glauben.)

Kannst du das verhindern?

Theoretisch ja, praktisch ist es alles andere als trivial.

Nimm eine bestehende Template-Engine wie zum Beispiel Twig.

- http://twig.sensiolabs.org/
 
Die lassen beim Kompilieren von der eigenen Syntax nach PHP einen komplexeren Tokenizer und Parser über den Template-Code laufen und validieren so die Syntax.
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück