Using a Kohana View class, I want admin users to be able to edit HTML templates and the easiest way to do this is to let them edit the template file directly i.e. load it in a textarea and save file on submit.
But a malicious user could potentially write php code inside this textarea and call static functions that may cause malicious behaviour. How can I restrict PHP to only evaluate simple variables in this editable template and disallow function calls and other types of logic?
Example:
view/template.php
Hey $firstname,
Best regards,
$admin
Don't parse the php. Read it into a string using file_get_contents and do a str_replace with a list of known variables.
e.g.
$replace = array(
'$firstname' => $firstname,
'$admin' => $admin
);
$template = file_get_contents('view/template.php');
$template = str_replace(array_keys($replace), array_values($replace), $template);
This obviously gets more complicated if you want to let them do anything more advanced than your example, but that's what things like smarty are for.
Another option is to use some templateing engine like mustache.
Related
I have built a custom CMS. Recently, I added the ability to create pages dynamically. I used CKEditor for the content of these pages.
I would also like to run some php functions that may be included in the content of the page stored in mysql.
I DO NOT want to store actual PHP code in the database, but rather function names perhaps. For example, in a page stored in the database I may have.
<?php //begin output
hello world!
check out this latest news article.
news($type, $id);
//end output
?>
What is the best way to find and execute this existing function without using EVAL if its found in the output? I was thinking along the lines of wordpress style short codes. Maybe [[news(latest, 71]] ? Then have a function to find and execute these functions if they exist in my functions.php file. Not really sure the best way to go about this.
I'm not searching for any code answers, but more of a best practice for this type of scenario, especially one that is safest against possible injections.
I found a solution from digging around and finding this thread
How to create a Wordpress shortcode-style function in PHP
I am able to pass short codes like this in CKEditor
[[utube 1 video_id]]
Then, in my page that renders the code:
print shortcodify($page_content);
using this function:
function shortcodify($string){
return preg_replace_callback('#\[\[(.*?)\]\]#', function ($matches) {
$whitespace_explode = explode(" ", $matches[1]);
$fnName = array_shift($whitespace_explode);
return function_exists($fnName) ? call_user_func_array($fnName,$whitespace_explode) : $matches[0];
}, $string);
}
If the function name exist (utube) it will fire the function.
Only problem Im having at the moment is not matter where I place the [[shortcode]] in my editor, it always executes first.
For example, in CKEditor I put:
Hello world! Check out my latest video
[[utube 1 video_id]]
It will always put the text under the video instead of where it is in the document. I need to figure a way to have the short code execute in the order it is placed.
I am building a website using php. I would want to separate the php from the html. Smarty engine, I guess does that, but right now its too complicated for me. Looking for a quick fix and easy to learn solution, one which is an accepted standard as well. Anyone helping please.
Consider frameworks or choose a template engine
Use a framework. Depending on your project, either a micro framework like Slim or something more complete like Laravel.
What I sometimes do when writing complex systems with quite much php code is separating it the following way (don't know your exact project, but it might work for you):
You create a php file with all the functions and variables you need. Then, you load every wepgage through the index.php file using .htaccess (so that a user actually always loads the index.php with a query string). Now, you can load the html page using file_get_contents (or similar) into a variable (I call this $body now); this variable can be modified using preg_replace.
An example: In the html file, you write {title} instead of <title>Sometext</title>
The replacement replaces {title} with the code you actually need:
$body = str_replace('{title}', $title, $body);
When all replacements are done, simply echo $body...
Just declare a lot of variables and use them in the template:
In your application:
function renderUserInformation($user)
{
$userName = $user->userName;
$userFullName = $user->fullName;
$userAge = $user->age;
include 'user.tpl.php';
}
In user.tpl.php:
User name: <?=$username?><br>
Full name: <?=userFullName?><br>
Age: <?=$userAge?>
By putting it in a function, you can limit the scope of the variables, so you won't pollute your global scope and/or accidentally overwrite existing variables.
This way, you can just 'prepare' the information needed to display and in a separate php file, all you need to do is output those variables.
Of course, if you must, you can still add more complex PHP code to the template, but try to do it as little as possible.
In the future, you might move this 'render' function to a separate class. In a way, this class is a view (a User View, in this case), and it is one step in creating a MVC structure. (But don't worry about that for now.)
Looking for a quick fix and easy to learn solution
METHOD 1 (the laziest; yet you preserve highlighting on editors like notepad++)
<?php
// my php
echo "foo";
$a = 4;
// now close the php tag -temporary-
// to render some html in the laziest of ways
?>
<!-- my html -->
<div></div>
<?php
// continue my php code
METHOD 2 (more organized; use template files, after you passed some values on it)
<?php
// my php
$var1 = "foo";
$title = "bar";
$v = array("var1"=>"foo","title"=>"bar"); // preferrable
include("template.php");
?>
template.php
<?php
// $var1, $var2 are known, also the array.
?>
<div>
<span> <?php echo $v["title"]; ?> </span>
</div>
Personally, i prefer method 2 and im using it in my own CMS which uses lots and lots of templates and arrays of data.
Another solution is of course advanced template engines like Smarty, PHPTemplate and the likes. You need a lot of time to learn them though and personally i dont like their approach (new language style)
function renderUserInformation($user)
{
$userName = $user->userName;
$userFullName = $user->fullName;
$userAge = $user->age;
include 'user.tpl.php';
}
I am a newbie coder trying to build a simple web app using PHP. I am trying to send an HTML email that has a variable that will change each time it is sent. The code to initiate the email is 'email.php' and contains:
$body = file_get_contents('welcome/green2.html.php');
Within the 'green2.html.php' file, I have a variable called $highlight that needs to be populated. The $highlight variable is defined within the 'email.php' file. I had tried to simply add within the 'green2.html.php' file, however it is not being parsed. I get a blank space where the variable should be when it is output.
Also, I have done an include 'welcome/green2.html.php' within the 'email.php' file. When I echo it, the $highlight var is shown on the resulting page, but not if I echo $body.
Any help would be much appreciated!
Have you tried the str_replace function? http://php.net/manual/en/function.str-replace.php.
Add a placeholder in HTML (for instance #name# for name, #email# for email), and then use the string replace function once you've loaded the content of the file.
$bodytag = str_replace("#name#", $name, $myfile);
Loading a file via file_get_contents() will not cause it to be parsed by PHP. It will simply be loaded as a static file, regardless of whether it contains PHP code or not.
If you want it to be parsed by PHP, you would need to include or require it.
But it sounds like you're trying to write a templating system for your emails. If this is what you're doing, you'd be better off not having it as PHP code to be parsed, but rather having placeholder markers in it, and then using str_replace() or similar functions to inject variables from your main program into the string.
Hope that helps.
Use http://php.net/manual/en/function.sprintf.php put a %s in your code instead of the variable read the content and put the string into the sprintf with the variable you want to put that's it. Hope this will help.
I'm having a hard time saving my template to a database and download the contents to view using Smarty.
I followed the tutorial on Smarty.net on how to make a custom retrieve type.
My original method was save the tpl markup to the db then download it and pass it as a variable to a smarty assigned variable and in my text.pl do something like {$source}
but this parses it as a string and smarty won't compile it.
the tutorial on smarty website didn't help and just leaves me with more questions...
this is what i tried based on the tutorial
function db_get_template($tpl_name, &$tpl_source, &$s)
{
$tpl_name = "index.tpl";
$tpl_source = nl2br($defaults->get_default_theme('theme_data'));
return true;
}
function db_get_timestamp($tpl_name, &$tpl_timestamp, &$smarty)
{
$tpl_timestamp = (int)time();
//$tpl_timestamp = (int)$defaults->get_default_theme('modified_on');
return true;
}
function db_get_secure($tpl_name, &$smarty)
{
// assume all templates are secure
return true;
}
function db_get_trusted($tpl_name, &$smarty)
{
// not used for templates
}
$s->registerResource("db", array(
"db_get_template",
"db_get_secure",
"db_get_trusted"
));
$s->display("db:index.tpl");
i'm not sure where db:index.tpl is being pulled from. I don't know where the markup is suppose to be loaded into...
I feel dirty even suggesting this, but:
Here's a more relevant manual page than the page you were referencing.
In particular, pay attention to the string: prefix to the "filename" passed in the display method call. You can simply pull the template data out of your database (a horrible idea, IMNSHO) and pass it to Smarty that way. No need to build your own custom resource thing unless you really want to do it that way.
I, for one, would urge you to keep it as stupid, ugly and obvious as possible, as to remind yourself about how much of a horrible, no-good idea this is. I'd like to remind you that Smarty compiles to PHP, and placing Smarty code in the database is an effective gateway to arbitrary code execution, a severe security vulnerability.
I am creating a custom form building system, which includes various tokens. These tokens are found using Regular Expressions, and depending on the type of toke, parsed. Some require simple replacement, some require cycles, and so forth.
Now I know, that RegExp is quite resource and time consuming, so I would like to be able to parse the code for the form once, creating a php code, and then save the PHP code, for next uses. How would I go about doing this?
So far I have only seen output caching. Is there a way to cache commands like echo and cycles like foreach()?
Because of misunderstandings, I'll create an example.
Unparsed template data:
Thank You for Your interest, [*Title*] [*Firstname*] [*Lastname*]. Here are the details of Your order!
[*KeyValuePairs*]
Here is the link to Your request: [*LinkToRequest*].
Parsed template:
"Thank You for Your interest, <?php echo $data->title;?> <?php echo $data->firstname;?> <?php echo $data->lastname;?>. Here are the details of Your order!
<?php foreach($data->values as $key=>$value){
echo $key."-".$value
}?>
Here is the link to Your request: <?php echo $data->linkToRequest;?>.
I would then save the parsed template, and instead of parsing the template every time, just pass the $data variable to the already parsed one, which would generate an output.
You simply generate the included file, you save it in a non-publicly accessible folder, and you include inside a PHP function using include($filename);
A code example:
function render( $___template, $___data_array = array() )
{
ob_start();
extract( $___data_array );
include ( $___template);
$output = ob_get_clean();
echo $output;
}
$data = array('Title' => 'My title', 'FirstName' => 'John');
render('templates/mytemplate.php', $data);
Note the key point is using extract ( http://php.net/extract ) to expand the array contents in real vars.
(inside the scope of the function $___data['FirstName'] becomes $FirstName)
UPDATE: this is, roughly, the method used by Wordpress, CodeIgniter and other frameworks to load their PHP based templates.
I'm not sure if understood your problem, but did you try using APC?
With APC you could cache variables so if you echo a specific variable, you could get it from cache.
You do all your calculations, save the information in some variables, and save those variables in the cache. Then, next time you just fetch that information from cache.
It's really easy to use APC. You just have to call apc_fetch($key) to fetch, and apc_store($key, $value, $howLongYouWant2Cache) to save it.
You best bet would to simply generate a PHP file and save it. I.e.,
$replacement = 'foobar';
$phpCodeTemplate = "<?php echo '$replacement'; ?>";
file_put_contents('some_unique_file_name.php', $phpCodeTemplate);
Just be very careful when dynamically generating PHP files, as you don't want to allow users to manipulate data to include anything malicious.
Then, in your process, simply check if the file exists, is so, run it, otherwise, generate the file.