login  Naam:   Wachtwoord: 
Registreer je!
 Scripts:

Scripts > PHP > Beveiliging > Simpele Debug class (veilige print_r)

Simpele Debug class (veilige print_r)

Auteur: Thomas - 01 januari 2014 - 20:53 - Gekeurd door: Wijnand - Hits: 6424 - Aantal punten: 5.00 (2 stemmen)



Noot 2014-03-05:
Let op bij het gebruik van de htmlspecialchars() aanroep in de static methode escape(). Hier is geen encoding (3e parameter) opgegeven. Wellicht doe je er verstandig aan deze expliciet op te geven. Afhankelijk van je PHP versie kan de default waarde van deze parameter verschillen.

Bij het lezen van de tutorial over debugging zag ik dat voor het dumpen van variabelen print_r() werd gebruikt. Nu is dit een eenvoudige manier, maar niet altijd handig, want de waarden kunnen HTML / JavaScript bevatten. Daarmee is het dus ook niet veilig.

Ook bij het dumpen van variabelen mag je veiligheid niet uit het oog verliezen, in de variabelen die je dumpt kan immers user input zitten! Voor extra toelichting zie de user comments van bovenstaande tutorial.

Ik heb even zitten prutten en heb een Debug klasse in elkaar gefietst, een soort van veilige print_r() zeg maar, die zowel keys als values escaped en tevens wat informatie over het type variabele retourneert.

Je kunt natuurlijk ook altijd je eigen ding bouwen, eventueel in combinatie met var_dump() ofzo. Denk daarbij dus wel aan output escaping.

Code:
De klasse:

  1. <?php
  2. class Debug
  3. {
  4. protected static function escape($text) {
  5. return htmlspecialchars($text, ENT_QUOTES);
  6. }
  7.  
  8. protected static function clean($in) {
  9. if (is_array($in)) {
  10. // Because we might introduce new (or overwrite existing) keys when we escape them,
  11. // we build a new array $out instead of overwriting $in.
  12. $out = array();
  13. foreach ($in as $k => $v) {
  14. $out[self::escape($k)] = self::clean($v); // $v might be anything, call clean() again
  15. }
  16. $in = $out;
  17. } elseif (is_numeric($in)) {
  18. $in = '(<span style="color: #ff0000;">numeric</span>) '.$in; // no cleaning necessary
  19. } elseif (is_bool($in)) {
  20. $in = '(<span style="color: #ff0000;">bool</span>) '.($in ? 'true' : 'false'); // print boolean value as string
  21. } elseif (is_object($in)) {
  22. // Convert object to string using print_r.
  23. $in = '(<span style="color: #ff0000;">object</span>) <span style="color: #009900;">'.self::escape(print_r($in, true)).'</span>';
  24. } elseif (is_null($in)) {
  25. $in = '(<span style="color: #ff0000;">null</span>)';
  26. } elseif (is_resource($in)) {
  27. $in = '(<span style="color: #ff0000;">resource</span>)'; // @todo add more info?
  28. } elseif (is_string($in)) {
  29. $in = '(<span style="color: #ff0000;">string</span>) '.self::escape($in);
  30. } else {
  31. // something we missed
  32. $in = '(<span style="color: #ff0000;">something</span>)';
  33. }
  34. return $in;
  35. }
  36.  
  37. public static function dump($in, $file='', $line='') {
  38. if (!empty($line) && !empty($file)) {
  39. echo '<b>variable dump in file '.$file.' on line '.$line.'</b>';
  40. } else {
  41. echo '<b>variable dump</b>';
  42. }
  43. if (is_array($in)) {
  44. echo '<pre>'.print_r(self::clean($in), true).'</pre>';
  45. } else {
  46. echo '<pre>'.self::clean($in).'</pre>';
  47. }
  48. }
  49. } // class
  50. ?>


De klasse heeft één publieke methode (dump) die je op twee manieren kunt aanroepen: ofwel met één parameter, waarbij je de te dumpen variabele meegeeft, ofwel met drie parameters, waarbij de tweede en derde parameters (respectievelijk) de "magische constanten" __FILE__ en __LINE__ bevatten. Hiermee kun je zien waar (in welk script) en op welke regel de dump methode is aangeroepen. Dit kan handig zijn als je op een moment meerdere dumps in je code hebt staan om te zien welke wordt uitgevoerd.

Voorbeeld:
  1. <?php
  2. // Test class.
  3. class Test
  4. {
  5. protected $test;
  6.  
  7. public function __construct($test) {
  8. $this->test = $test;
  9. }
  10. }
  11.  
  12. // Test variable.
  13. $test = array(
  14. 'a' => array( // subarray
  15. 1 => "<script>alert('hoi')</script>", // nasty code
  16. 2 => false, // a boolean
  17. 77 => true, // another boolean
  18. 3 => '5.6666667', // a numeric value stored as string
  19. 'object' => new Test('<b>hallo</b>'), // an object
  20. 4 => 1.2, // a numeric value (float)
  21. 5 => 7, // a numeric value (integer)
  22. 6 => array( // subsubarray
  23. 'z' => '<b>bold</b>', // more nasty code
  24. 'a' => 'asdf', // a string
  25. '<la' => 'hai', // nasty key
  26. ),
  27. 9 => null,
  28. ),
  29. '<b>' => 'lala<br />', // key with code in it
  30. '&lt;b&gt;' => 'hoi', // escaped variant of previous key, which should not be overwritten by your dump functionality...
  31. );
  32.  
  33. // Dump the evil code in a safe way.
  34. Debug::dump($test, __FILE__, __LINE__);
  35. ?>
Download code! Download code (.txt)

 Stemmen
Niet ingelogd.

 Reacties
Post een reactie
Lees de reacties (3)
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.037s