TinyButStrong - the PHP Template Engine
Categories > OpenTBS general >

Allow user to upload templates - security concerns

The forum is closed. Please use Stack Overflow for submitting new questions. Use tags: tinybutstrong , opentbs

By: Michael Zangl
Date: 2016-09-09
Time: 12:59

Allow user to upload templates - security concerns


I experimented a bit with opentbs (and other software). I need a system that allows users to upload a template and then creates a odt/pdf based on it.

I have gotten it working, I can generate the files, create jpg previews and do other things.

I am now trying to secure the whole thing. I use libreoffice for converting odt->pdf, this can be put in a sandboy easily.

I have more problems with OpenTBS, since it is a lot easier to use if I don't need to sandbox it.

I managed to disable the $GLOBALS access.
$TBS->VarRef = []
I prevent any use of user functions (but not all. ondata seems not to be affected)

class NoFunctions implements \ArrayAccess {
    public function offsetExists($o) {
        return true;
    public function offsetGet($o) {
        return function() { return ''; };
    public function offsetSet($o, $val) {
        // ignore
    public function offsetUnset($o) {
        // ignore

// internal but works.
$TBS->_UserFctLst = new NoFunctions;
// not required any more
$TBS->SetOption('fct_prefix', 'THERE_IS_NO_SUCH_FUNCTION');
This is how far I came until now.

For access permissions on the images, I could overwrite the Method TbsPicExternalPath in clsOpenTBS. I have not found the best way to do it, I don't really want to change the code unless I need to.
I want to prevent any function calls, object instantiations and other possibilities of users running code.

Has anyone done this? Is OpenTBS even designed to work this way or do I need to sandbox it using a separate PHP process?
By: Skrol29
Date: 2016-09-13
Time: 12:14

Re: Allow user to upload templates - security concerns


> For access permissions on the images,

You can build a small TBS plug-in that you load before OpenTBS. This plug-in could check for parameter "ope=changepic" and check the path of the image.

> I want to prevent any function calls, object instantiations and other possibilities of users running code.

Object instantiation cannot be done directly by TBS/OpenTBS from the template side. But it can call a method of an object from $TBS->VarRef (which is $GLOBAL by default), $TBS->ObjectRef (which is false by default), and merged data ($TBS->MergeField and $TBS->MergeBlock). All of those is tunable from the PHP side.

By: TiViDi
Date: 2017-02-01
Time: 11:13

Re: Allow user to upload templates - security concerns


I am having the same issue. Did you have any luck getting this water proof Michael?

I am using TBS as a template engine for DOCX files that are uploaded by the user. I will supply the user with a set of variables he can use to design his output templates.
Obviously for this use case I don't want the user to be able to include any scripts/files from the server or define variables within the template, instead of using the provided variables - basically any injection should be prevented.
It is rather difficult for me to get an overview over all possibilities to do this with TBS and a way to prevent it. It would be great if TBS had a strict mode that could be activated to prevent from manipulating paths etc.

Any more information on this would be very much appreciated as this would make TBS a great solution for user customised reports!

Thanks for any input on this.

All best,

By: Michael Zangl
Date: 2017-02-06
Time: 10:51

Re: Allow user to upload templates - security concerns


I was not really able to get through the TBS code. It is about 10k lines long and uses a lot of ugly things (pass by reference, the shortes variable names possible, plain arrays with interger indexes that represent objects, ...)

I solved it for my part by adding a TBS plugin that gets called for every replacement. I then match against a strong regexp that only allows variables to be inserted. I also set VarRef to a sanitized array of my data (not the data objects). For Images, I simply set a hash. I then wait for them to be inserted and replace that hash with a published version of the image later. I need to track them because I am converting HTML documents as well.

I still have to check how good it really is, but it seems to work. If this is not enough, I will probably code something on my own.

By: TiViDi
Date: 2017-02-06
Time: 15:44

Re: Allow user to upload templates - security concerns

Hi Michael and thanks for your reply!

That sounds like you are doing a very comprehensive intervention into the existing class! I am not entirely sure I understand the necessity of each of the explained steps.

I have done the following:
$TBS = new \clsTinyButStrong('','wlTempl_','wlTempl_'); // new instance of TBS
$TBS->VarRef = [];
$TBS->_UserFctLst = new \TbsNoFunctions;

TbsNoFunctions being defined like you explained in you original post. In addition I am customizing the method TbsPicAdd right after it called TbsPicExternalPath with the following code:
        $ExternalPath = str_replace("//","",str_replace("..","",$ExternalPath));
            return false;;

This ensures that image paths are within the image path and do not navigate out of it.

I am not entirely positive that his is covering all potential to do bad with TBS strong templates. Any input on were this approach is lacking would be appreciated.

Thanks again and all best,