📜 ⬆️ ⬇️

PHP5. "Secure Templates"

Historically, I do not use external template engines such as Smarty or others. I use the main “active” template, i.e. just a PHP file in which data for content zones are called and inserted as plain HTML (how it is generated in this case does not matter). In the previous version of CMS, which was not “boxed” and in which there was virtually no separation of user rights, this aspect did not particularly strain - access to the template was either “direct” (ftp, etc.) or through the administrator interface for the administrator. But, accordingly, a person with access to the admin panel could cram any php code inside this file. In the new version of CMS this is unacceptable, because this is actually a detour of rights. Therefore, it was decided to abandon such "unsafe" patterns.

In search of the simplest and most elegant way out, using minimal “external” solutions, I remembered one remarkable feature of the PHP XSLT processor ( XSLTProcessor ). Namely, the use of PHP functions in transformations, while you can limit the list of these functions. And this is exactly what is needed.

Let us turn to examples.

The standard “active” pattern looked like this:
')
<? php <br>$ main_ctx = CMSContentObj::getInstance () - > getData("main_ctx");<br>$title = CMSContentObj::getInstance()- > getTitle();<br>// <br>? > <br> < html > <br> < head > <br> < meta content ="text/html; charset=utf-8" http-equiv ="Content-Type" /> <br> < title ><? =$title;? > - mysite.ru </ title > <br> < link href ="/_css/main.css" rel ="stylesheet" type ="text/css" > <br> < script type ="text/javascript" src ="/_js/jquery.js" ></ script > <br> </ head > <br> < body > <br>…<br> <? =$main_ctx;? > <br>…<br> </ body > <br> </ html > <br> <br> * This source code was highlighted with Source Code Highlighter .


Those. just the HTML data is pulled from the content and inserted into the HTML code.

In the case of XSL, the template looks like this:

<? xml version ="1.0" encoding ="utf-8" ? > <br> < xsl:stylesheet version ="1.0" xmlns:xsl ="http://www.w3.org/1999/XSL/Transform" xmlns:php ="http://php.net/xsl" > <br> < xsl:output encoding ="utf-8" indent ="yes" method ="html" /> <br> < xsl:template match ="/page" > <br> <!-- <br> Variables <br> --> <br> < xsl:variable name ="title" select ="php:function('CMSStaticContent::getTitle')" /> <br> < xsl:variable name ="main_ctx" select ="php:function('CMSStaticContent::getData','main_ctx')" /> <br> <!-- <br> / Variables <br> --> <br> < html > <br> < head > <br> < meta content ="text/html; charset=utf-8" http-equiv ="Content-Type" /> <br> < title >< xsl:value-of disable-output-escaping ="yes" select ="$title" /> - mysite.ru </ title > <br> < link href ="/_css/main.css" rel ="stylesheet" type ="text/css" /> <br> < script type ="text/javascript" src ="/_js/jquery.js" /> <br> </ head > <br> < body > <br> …<br> < xsl:value-of disable-output-escaping ="yes" select ="$main_ctx" /> <br> …<br> </ body > <br> </ html > <br> </ xsl:template > <br> </ xsl:stylesheet > <br> <br> * This source code was highlighted with Source Code Highlighter .


Isn't it true?

LS: For some reason, I could not use constructions like CMSContentObj :: getInstance () -> getTitle (), so I had to create an intermediate class CMSStaticContent “on my lap”:

class CMSStaticContent {<br> public static function __callStatic($name, $arguments) {<br> $cms = CMSContentObj::getInstance();<br> if (method_exists($cms, $name)) {<br> return call_user_func_array(array($cms, $name), $arguments);<br> } else {<br> throw new Exception();<br> }<br> }<br>}<br> <br> * This source code was highlighted with Source Code Highlighter .


Well, now it just remains to create an empty XML, register the functions and make the conversion, like this:

$doc = new DOMDocument();<br>$doc->loadXML( '<page/>' );<br>$xsl = new DOMDocument();<br>$xsl->load($xsl_template);<br>$proc = new XSLTProcessor();<br>$proc->registerPHPFunctions(array('CMSStaticContent::getData', 'CMSStaticContent::getTitle'));<br>$proc->importStyleSheet($xsl);<br>echo $proc->transformToXML($doc);<br> <br> * This source code was highlighted with Source Code Highlighter .


Well, actually, that's all. We have limited PHP functions that can be performed during conversion, and through such a template it is impossible to have access to the system.

PS: And no external template engines.

Source: https://habr.com/ru/post/87417/


All Articles