I am writing my own download tracker and i want to offer users the ability to show a custom message on the download page. I want to allow html and javascript, so users can write a paragraph or use an ad code etc.
I am storing my settings in a config file (not the best way I know)
Example: <?php define("WAIT_MESSAGE", "htmlcodehere"); ?>
The problem is that quotes or slashes mess up the config file and the settings page will not load. I've looked into add slashes to try and escape these characters but it just adds multiple slashes.
What would be the best way to store html content/javascript in my config file?
EDIT: Have tried a few methods, but with all them quotes are escape each time i click save to update the config file \"hello\" becomes \"hello\" etc
You should NOT trust your users so mutch that you let them post and save JavaScript and HTML on your site.
Allowing users to actually insert HTML/Javascript/PHP in to your page is a very bad thing to do
Having said all that the problem is one that plagues us all from time to time. What you need is to store the HTML code in some format that is not going to change the meaning of the code above.
This problem is usually resolved by converting any such characters to their equivalent HTML entities so that you can safely store the
Take a look at http://php.net/manual/en/function.htmlspecialchars.php and http://www.php.net/manual/en/function.htmlspecialchars-decode.php for more info.
Have you tried it like with single ' ?
<?php define('WAIT_MESSAGE', '<p>Please wait.. your download starts shortly</p>'); ?>
That is not safe at all. Someone could easily inject PHP into it.
What you can do (which is a bit hacky), is to base64_encode() the data, and base64_decode() it when you need to use it. Doing that will get rid of the quotes/special characters problem, and the security problem.
Once you've written the base64_encoded HTML in the config file, to use it, you'll do:
<?php
echo base64_decode(WAIT_MESSAGE);
?>
Personally I would hold any editable values within a database to be safe,
but if you really want/need to edit a php config file then perhaps this is the safest way.
<?php
/*Function to check if magic_quotes is enabled.
(Stops double slashes happening)
*/
function check_magic_quotes($value){
if (get_magic_quotes_gpc()) {
return stripslashes($value);
} else {
return $value;
}
}
/*Form was posted,
You should also do a check to see if logged in and have rights to edit*/
if($_SERVER['REQUEST_METHOD']=='POST'){
//Check for magic quotes and then base64_encode the string.
$value = base64_encode(check_magic_quotes($_POST['configVal']));
/*Use heredoc to create the php line for the config & insert the
base64 encoded string into place*/
$config=<<<CONFIG
<?php define("WAIT_MESSAGE", '$value'); ?>
CONFIG;
file_put_contents('someConfig.php',$config);
}
//When you want to include the config
include('someConfig.php');
/*To echo out the config value: base64_decode it,
and then htmlentities encode it, to protect from XSS*/
echo 'This was included: '.htmlentities(base64_decode(WAIT_MESSAGE));
//Basic form with current value when someConfg.php has not been included
$config = file_get_contents('someConfig.php');
preg_match("#\"WAIT_MESSAGE\", '(.*?)'#",$config,$match);
?>
<form method="POST" action="">
<p>Config Value:<input type="text" name="configVal" value="<?php echo htmlentities(base64_decode($match[1]));?>" size="20"><input type="submit" value="Update"></p>
</form>
Related
I have already searched an answer here and with google, but I don't found something. Because I'm having trouble ask the right question to find something.
What is the best way for this problem:
My Page: edit_data.php
I have a form (method="post" action="save.php"). On submit I store the data in a MySQL table.
In save.php:
MySQL insert (return the new id of dataset)
if success I call edit_data.php?id=<new_id>
if error I call error.php?msg=<error message>
The problem is that I lose the data on error.
This is what I want:
- go back to edit_data.php
- show the error directly there
- and I want that all fields contains their original data
I cannot take $_GET, because the data are too big.
Does anyone have an easy solution for me?
Thank you
Is there any reason you can't use $_SESSION? That way, all your data will be saved for the duration of the session, or until you delete it.
Make sure that every PHP document contains session_start(); before any headers are output, this also goes for any blank space before your <?php tag.
To put all your $_POST data in a $_SESSION['POST'] you could do something like,
<?php
session_start();
foreach($_POST as $key=>$val) {
$_SESSION['POST'][$key] = $val;
} ?>
Then you can access your previous POST variables by accessing $_SESSION['POST']['KEYNAMEHERE']
PS: $_GET and $_POST are interchangeable here
If $_GET is to big, you can edit your php.ini file.
Please note that PHP setups with the suhosin patch installed will have
a default limit of 512 characters for get parameters. Although bad
practice, most browsers (including IE) supports URLs up to around 2000
characters, while Apache has a default of 8000.
To add support for long parameters with suhosin, add
suhosin.get.max_value_length = in php.ini
http://www.php.net/manual/en/reserved.variables.get.php#101469
Max size of URL parameters in _GET
I'm making a small CMS for practice. I am using CKEDITOR and is trying to make it avaliable to write something like %contactform% in the text, and then my PHP function will replace it with a contactform.
I've accomplished to replace the text with a form. But now I need the PHP code for the form to send a mail. I'm using file_get_contents(); but it's stripping the php-code.
I've used include(); to get the php-code from another file then and that works for now. I would like to do it with one file tho.
So - can I get all content from a file INCLUDING the php-code?
*UPDATE *
I'll try to explain in another way.
I can create a page in my CMS where I can write a header and some content. In the content I am able to write %contactform%.
When I get the content from the database I am replacing %contactform% with the content from /inserts/contactform.php, using file_get_contents(); where I have the form in HTML and my php code:
if(isset($_POST['submit'])) {
echo 'Now my form is submitted!';
}
<form method="post">
<input type="text" name="email">
<input type="submit" name="submit">
</form>
Now I was expecting to retrieve the form AND the php code active. But If I press my submit button in the form it's not firing the php code.
I do not wan't to show the php code I want to be able to use it.
I still have to guess, but from your update, I think you ultimatly end up with a variable, which contains the content from the database with %contactform% replaced by file_get_contents('/inserts/contactform.php').
Something like:
$contentToOutput = str_replace(
'%contactform%',
file_get_contents('/inserts/contactform.php'),
$contentFromDatabase
);
If you echo out that variable, it will just send it's content as is. No php will get executed.
Though it's risky in many cases, if you know what you're doing you can use eval to parse the php code. With mixed code like this, you maybe want to do it like the following.
ob_start();
eval('; ?>' . $contentToOutput);
$parsedContent = ob_get_clean();
$parsedContent should now contain the results after executing the code. You can now send it to the user or handle it whatever way you want to.
Of course you'll have to make sure that whatever is in $contentToOutput is valid php code (or a valid mixture of php with php-tags and text).
Here is a link to the symfony Templating/PhpEngine class. Have a look at the evaluate method to see the above example in real code.
yes...
$content = file_get_contents( 'path to your file' );
for printing try
echo htmlspecialchars( $content );
From reading the revised question, I think the answer is "You can't get there from here." Let me try to explain what I think you will encounter.
First, consider the nature of HTTP and the client/server model. Clients make requests and servers make responses. Each request is atomic, complete and stateless, and each response is complete and usually instantaneous. And that is the end of it. The server disconnects and goes back to "sleep" until the client makes a new request.
Let's say I make a request for a web page. A PHP script runs and it prepares a response document (HTML, probably) and the server sends the document to my browser. If the document contains an HTML form, I can submit the form to the URL of the action= script. But when I submit the form, I am making a new request that goes back to the server.
As I understand your design, the plan is to put both the HTML form and the PHP action script into the textarea of the CKeditor at the location of the %contactform% string. This would be presented to the client who would submit the form back to your server, where it would run the PHP script. I just don't think that will work, and if you find a way to make it work, you're basically saying, "I will accept external input and run it in PHP." That would represent an unacceptable security exposure for me.
If you can step back from the technical details and just tell us in plain language what you're trying to achieve, we may be able to offer a suggestion about the design pattern.
I want to make a programming environment. I will explain it with an example.
One programmer will write that code;
<html>
<head>
<?php definedMetaTags(); ?>
</head>
</body>
Programmer will save this file and then upload to my system. That file will be executed at server side and then they system will turn generated code back.
That definedMetaTags() function will be already written in the system.
An example of Compiler.php:
<?php
require_once("definitionsForProgrammer.php");
include("uploadedfile.php");
?>
My question is that I want to allow that uploadedfile.php only what functions I want. Else, maybe that programmer writes some codes what I want him/her to do. (Deleting files, mysql connection, etc.)
Is there any way to allow a code only specific functions, variables, constans?
If the goal is to allow a user to insert placeholders that will be replaced by some PHP function execution, then there's no need to treat the uploaded file as PHP code:
<html>
<head>
{[definedMetaTags]}
</head>
</body>
Then Compiler.php would look like this:
<?php
require_once("definitionsForProgrammer.php");
$macros = array();
$macros['definedMetaTags'] = definedMetaTags();
$output = file_get_contents("uploadedfile.php");
foreach($macros as $macro=>$value) $output = str_replace("{[$macro]}", $value, $output);
echo $output;
?>
The definedMetaTags() function would need to be reworked so that it returns the tags as a string instead of printing them directly to output.
This method would allow you to define any number of macros without exposing yourself to all the security risks the others here have mentioned.
If you're aiming for security and you want to let them to write functions, then the short answer is: no.
Essentially you're asking for a PHP sandbox which will let you constrain what code can be executed. PHP would have to support this at a fundamental level for it to work. For example, supposing you took the approach of saying "I only allow the user to write a function named 'foo'". Inside that function, though the user can do all kinds of bad things like making system calls, downloading other code and executing it, etc. In order to prevent this you'd need to implement checks at a much lower level in the system.
If you're willing to restrict the scope only to variable definitions then yes you can do it. You can use token_get_all() and token_name() to examine the file to make sure that it doesn't have any code that you don't want in it. For example:
foreach (token_get_all(file_get_contents("uploadedfile.php")) as $token) {
if (is_array($token)) {
echo token_name($token[0]), " ";
} else {
echo $token;
}
}
If you don't like any tokens you see, don't include the file. You could theoretically guard against bad functions this way as well, but it'll require a fair amount of effort to properly parse the file and make sure that they're not doing something bad.
references:
http://www.php.net/manual/en/function.token-get-all.php
http://www.php.net/manual/en/function.token-name.php
http://www.php.net/manual/en/tokens.php
Well, if i'm understanding your question correctly. If you include("uploadedfile.php"); you will acquire everything in it.
What you could do is break your code up into related sections (whether it be via classes or just function definitions in a file) then only include the file/class that you want.
(let me know if that's not what your asking)
With my data files I use with sites I usually include some PHP code in them to prevent them being directly accessed, such as below..
<?php
if (defined("VALID")) {
?>
html code here
<?php
} else {
die('Restricted Access.');
}
?>
Now this works fine when I do a simple include..... however I am using one of these files to do some replacements in & hence need to make use of file_get_contents(); however when using this, not only do I get the HTML code, I obviously also get the PHP code returned with it..... this ends up going in the source, which I do NOT want.
Is there any way around this? Perhaps stripping the PHP code? Any better ways/suggestions?
If you want to make replacements on an output of a script try using output buffering.
Instead of file_get_contents('your-php-script.php') do this:
ob_start();
include('your-php-script.php');
$contents = ob_get_clean();
// do your replacements on a $contents
echo preg_replace("~<\?php(.*?)\?>~", "", $contents);
This should work to erase the PHP code in the file.
Why dont you use a hashed string in a session cookie to check it? I think its the best solution. So add to the cookie a hashed value, then check for that value on the file you need to check if its valid and voila!
Hope it helps!
I'm new to PHP and I'm trying to do something that may be bad practise and may well be impossible. I'm basically just hacking something together to test my knowledge and see what PHP can do.
I have one webpage with a form that collects data. That is submited to a PHP script that does a bunch of processing - but doesn't actually display anything important. What I want is that once the processing is done, the script then tells the browser to open another page, where the results are displayed.
I know I can use header('Location: page.php'); but I can't work out how to provide POST data with this. How can I do that? Alternatively, is there another way to tell the browser to open another page?
EDIT: What I'm taking from the responses is that it's possible to do this using various hacks but I'd be better off to just have the processing and the display code in one file. I'm happy with that; this was an experiment more than anything.
You could store that data in the session e.g. in the first file that handles the post
session_start();
$_SESSION['formdata'] = $_POST; //or whatever
then you can read it on the next page like
session_start();
print_r($_SESSION['formdata']);
or you could pass it through GET: (but as per comments this is a bad idea)
header('Location: page.php?' . http_build_query($_POST));
If you do that make sure you do additional processing/validation on page.php as a malicious user could change the variables. also you may not need the whole post transmitted to the next page
Edit
I should make clear that I think the second option is possibly worse, as you are limited by the size of data you can send through get and it is possibly less secure as users can more obviously manipulate the data.
Is it really necessary to call another page after the processing is done? I'd probably do the following:
<form method="post" action="display.php">
...
</form>
display.php:
if ($_POST) {
require_once(process.php);
process($_POST);
display_results;
}
with process.php containing the code necessary for processing the post request.
Alternatively, you could use something like the cURL library to pass the results of the processing to a page specified by yourself. Don't know if that's really what you're after though.
You could use JavaScript as a dirty work-around:
<form id="redirect_form" method="post" action="http://someserver.com/somepage.php">
<input type="hidden" name="field_1" value="<?php echo htmlentities($value_1); ?>">
<input type="hidden" name="field_2" value="<?php echo htmlentities($value_2); ?>">
<input type="hidden" name="field_3" value="<?php echo htmlentities($value_3); ?>">
</form>
<script type="text/javascript">
document.getElementById('redirect_form').submit();
</script>
(the script should be below the form)
There's no way to redirect the user's browser to an arbitary page and sent a POST request. That would be a bit security risk, where any link could cause you to make any form submission to an arbitrary site without you having any kind of clue about what was going to happen.
In short, it's not possible
AFAIK this is usually done as a two-step process:
On form.php, POST the data to script process.php
The process.php script processes the data but never outputs anything itself, it always calls header("Location: asdasd") to redirect to a success.php or failure.php page (if applicable)
Do it all in one script and just output different HTML for the results.
<?php if($doingForm) { ?>
html for form here
<?php } else { ?>
html for results
<? } ?>
This problem has vexed me for some time. My custom CMS does some quite complex processing, uploading and manipulation, and so sometimes ouputs quite lengthy error and information messages, which aren't suitable for converting to GET data, and I have always wanted to avoid the reload problem on data INSERT, but not yet found an adequate solution.
I believe the correct way to go about this, is to create message arrays for each possible state - each message or error you could want to display, and then you only need to send error/message numbers which are a lot easier to handle than long data strings, but it's something I have always shied away from personally as I find it a bit tedious and cumbersome. Frankly, this is probably just laziness on my part.
I quite like the SESSION variable storage solution, but this raises the question of how do you ensure the SESSION data is properly destroyed?
As long as you ensure you are only sending information (messages/errors) and not data that should/could be stored (and thus potentially sensitive) this should be an avoidable problem.
I hope i got your qestion right.
You might try this:
Adjust your form to look like this:
form method="POST" action="process_data.php"
2.
Then you create the file process_data.php, wich surprisingly processes the data.
And in this file you use header:
For example:
$head = sprintf("page.php?data1=%d?data2=%d",$data1,$data2);
header($head);
I hope i could help.