2

A week or two ago I just started using Zend Framework seriously and have had trouble escaping manually with Zend_View::escape(). Does anyone knows how to escape vars in templates (Zend_View templates) automatically without using $this->escape(), or any other tricky ways like output buffering and PREG replacing *.phtml files.

I'd like to know the best practice in this case.

chikaram
  • 700
  • 1
  • 7
  • 18

5 Answers5

2

You can extend Zend_View to create a custom view class which autoescapes things, or you can use a view helper to turn autoescaping on/off.

I have written a blogpost about it, with example code for both approaches: How to automatically escape template variables in Zend_View

Jani Hartikainen
  • 42,745
  • 10
  • 68
  • 86
  • Thank you so much. The approach looks fine. But the thing is that it can't escape values returned by methods. E.G. in my template I go like: foreach ($this->comments as $comment): ?>

    = $comment->getText() ?>

    endforeach ?>. I don't want to code like = $this->escape($comment->getTitle()) ?>, which I think is really a pain. If you have any other idea, I'd like you to let me know.
    – chikaram Jul 06 '10 at 03:15
  • I don't think you can autoescape returned values from functions. That is a limitation of how Zend_View works. There is the parser for short tags which processes the view script and changes it so that short tags work, you could probably use a similar approach to adding escape calls to everything, but it might be slow and tricky. – Jani Hartikainen Jul 06 '10 at 08:59
2

Over at the PiKe project we build a custom stream wrapper that automatically escapes all view variables, with a MINIMAL performance hit! You can still get the RAW value with:

<?=~ $variable ?>

Notice the "~" character. Checkout http://code.google.com/p/php-pike/wiki/Pike_View_Stream

I know you said that you want to avoid "tricky ways like output buffering and PREG replacing *.phtml files.", but I still think it's a very neat way to fix auto escaping in Zend Framework 1.

Pieter Vogelaar
  • 365
  • 2
  • 4
  • 16
0

You said "automatically", so I believe that that means when you do echo $this->var; you want it escaped. Well, if that's the case, maybe you could do the escaping when the variable is set to the view. AFAIK it's done in the Zend_View_Abstract class' __set magic method* (around line 300). Changing the core ZF code is not recommended, so you could go by extending Z_V_A or Z_V and just override the __set method.

*I'm not 100% sure that Z_V_A::__set is the only place where the params are assigned to the view, but I think it should be. Can't think of any other place for that.

Edit: Personally, I'd avoid this and just stick with the good ol' $this->escape(). More typing but less magic going on in the background.

robertbasic
  • 4,325
  • 1
  • 27
  • 25
  • Thank you for your advise. But I want a somewhat drastic solution for this case. If you code good ol' $this->escape() manually, you may forget to escape and have your app XSS-vulnerable. And "the biggest trouble" for me is it makes harder to explain how cool ZF is to Smarty or symfony users (you can auto-escape outputs with both of them). – chikaram Jul 06 '10 at 03:31
0

You have asked for best practice then what you are doing is already it. Wait till when you want to display your data before modifying it only for output reasons.

I understand you find writting ->escape() everytime tedious but its still the way to go.

If you where to auto escape everything then you would run into problems one day when you want/need unescaped data.

Iznogood
  • 12,447
  • 3
  • 26
  • 44
  • I understand your point. But with symfony and Smarty you don't need to bother coding those tedious stuff. – chikaram Jul 06 '10 at 03:36
0

ZendX_View_Autoescaping, this project provides you a ViewRenderer with autoescaping of all assigned view variables.

https://github.com/jensklose/ZendX_View_Autoescaping

Try it!

It supports:

  • escaping into deep data structures
  • escaping the array keys
  • possibility to switch the escaping context (html, json, nofilter)
Florent
  • 12,310
  • 10
  • 49
  • 58
jens.klose
  • 351
  • 2
  • 8