Skip to content
This repository
Browse code

Fix potential security vector

- Fixes a potential security vector whereby if the value of a view model
  key references a PHP function, that function is called.
  - Now validates the callback to determine if it is a static method
    call or namespaced function call; if not, simply returns the value.
  • Loading branch information...
commit 6d0e0851c8beb3b0f4652b46412275458611fc18 1 parent 2ee91d0
Matthew Weier O'Phinney authored September 22, 2011
1  .vimproject
@@ -79,6 +79,7 @@ mustache=/home/matthew/git/phly_mustache CD=. filter="*.php *.html *.xml *.txt"
79 79
      template-with-pragma-and-partial.mustache
80 80
      template-with-sections-and-delim-set.mustache
81 81
      template-with-sub-view.mustache
  82
+     template-referencing-php-function.mustache
82 83
     }
83 84
    }
84 85
   }
31  library/Phly/Mustache/Renderer.php
@@ -364,14 +364,15 @@ public function getValue($key, $view)
364 364
         }
365 365
         if (is_object($view)) {
366 366
             if (isset($view->$key)) {
367  
-                if (is_callable($view->$key)) {
  367
+                if (is_callable($view->$key) && $this->isValidCallback($view->$key)) {
368 368
                     return call_user_func($view->$key);
369 369
                 }
  370
+                return $view->$key;
370 371
             }
371 372
             return '';
372 373
         }
373 374
         if (isset($view[$key])) {
374  
-            if (is_callable($view[$key])) {
  375
+            if (is_callable($view[$key]) && $this->isValidCallback($view[$key])) {
375 376
                 return call_user_func($view[$key]);
376 377
             }
377 378
             return $view[$key];
@@ -457,4 +458,30 @@ protected function handlePragmas($token, $data, $view)
457 458
             }
458 459
         }
459 460
     }
  461
+
  462
+    /**
  463
+     * Is the callback provided valid?
  464
+     * 
  465
+     * @param  callback $callback 
  466
+     * @return bool
  467
+     */
  468
+    protected function isValidCallback($callback)
  469
+    {
  470
+        if (is_string($callback)) {
  471
+            if (strstr($callback, '::')) {
  472
+                // Referencing a static method call
  473
+                return true;
  474
+            }
  475
+            if (strstr($callback, '\\')) {
  476
+                // Referencing a namespaced function
  477
+                return true;
  478
+            }
  479
+
  480
+            // For security purposes, we don't want to call global functions
  481
+            return false;
  482
+        }
  483
+
  484
+        // Object or array callback -- always okay
  485
+        return true;
  486
+    }
460 487
 }
21  tests/PhlyTest/Mustache/MustacheTest.php
@@ -552,4 +552,25 @@ protected function getRecursiveView()
552 552
             ),
553 553
         );
554 554
     }
  555
+
  556
+    /**
  557
+     * @group injection-issues
  558
+     */
  559
+    public function testArrayValuesThatReferToPHPBuiltInsShouldNotCallThem()
  560
+    {
  561
+        $test = $this->mustache->render('template-referencing-php-function', array(
  562
+            'message' => 'time',
  563
+        ));
  564
+        $this->assertEquals('time', trim($test));
  565
+    }
  566
+
  567
+    /**
  568
+     * @group injection-issues
  569
+     */
  570
+    public function testObjectPropertiesThatReferToPHPBuiltInsShouldNotCallThem()
  571
+    {
  572
+        $model = (object) array('message' => 'time');
  573
+        $test  = $this->mustache->render('template-referencing-php-function', $model);
  574
+        $this->assertEquals('time', trim($test));
  575
+    }
555 576
 }
1  tests/PhlyTest/Mustache/templates/template-referencing-php-function.mustache
... ...
@@ -0,0 +1 @@
  1
+{{message}}

0 notes on commit 6d0e085

Please sign in to comment.
Something went wrong with that request. Please try again.