I want to enable users to edit pages with editor (CKEditor).
The problem is that I want to prevent XSS, so when I'm using:
$this->input->post('content', TRUE)
it also removes some html conent, for example, the following code:
<script></script><p><span style="color:#800000;">text</span></p>
becomes to:
[removed][removed]<p><span
So yes, it prevents XSS, but also removes some necessary html content.
What should I do to fix it?
Don't use their built in XSS functionality. Use HTML purifier to do it for you. That way you have more control over what is and isn't removed.
try this simple way change this code $this->input->post('content', TRUE) into $_POST['content'] its work for me because codeigniter will do XSS filtering when run $this->input
Instead of this you can use below code.
$content = htmlspecialchars($this->input->post('content'));
The save to database and at the time of retrieval, you can use
htmlspecialchars_decode('your html code');
Related
I have a Symfony project where any user can register for an account and then create a page with a form that includes a field content. I want to allow users to insert some html (like bold text, numbered lists and some other elements), which I have done by using a WYSIWYG-editor, CKEditor. I have created a toolbar that only allows the elements I have chosen to be parsed to the database when saving the page. I can show the content of this page by using:
{{ page.content | raw }}
This all works as expected. However, is a user was to copy the post-request, edit in some JS or other HTML and use cURL to send it, this would allow them to insert (harmful) code. My question is: how to prevent this from happening?
I have been reading about 'sanitation' or 'purification' to cleanup user input. Something like HTML Purifier could cleanup the output, which I also considered doing by creating a sort of 'whitelist twig filter' for the elements I do allow. Preferably I would cleanup the input before persisting it to the database. I imagine this is a common issue, but I only find solutions on how to cleanup the output, usually by escaping all HTML, which in my case is also not a solution because I do want to allow some HTML.
You could purify this in your form type, after the user submits the form with the HTML Purifier Library and symfony form events:
use HTMLPurifier;
use HTMLPurifier_Config;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
$object = $event->getData();
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.AllowedElements', ['a', 'b', 'strong', 'ul', 'li', 'p', 'br']);
$config->set('Attr.AllowedFrameTargets', ['_blank']);
$purifier = new HTMLPurifier($config);
$content = $purifier->purify($object->getContent());
$object->setContent($content);
});
So in this example the users content is cleaned up. The HTML.AllowedElements defines which elements should not be removed. After that the entity is ready to be persisted to your database without bad html user content.
The trick is not to manipulate user input. You should validate/reject user input (example: user uploads 10GB of data, or the user starts a div element, but doesn’t end it), but don’t change it. It’s not going anywhere or going to infect anyone by sitting in a database.
When you display the page to the user, that is when you manipulate the data. Like you said, escape your characters: < for <, & for &, and " for “.
I was recently programming for this, and what I did was use an XML parser (luaexpat). In your case, you have PHP that has an XML parser library.
Run the user input HTML through the XML parser. If any unauthorized elements show up, you can either escape them (<) on output or throw an error instead of the content. It is also good to make sure that the content has valid XML, so a user can’t mess up the rest of the page by not closing an element.
Another idea is to store “version identifiers” of post types. If you decide to add more features/attributes or switch to another encoding (like BBCose), write a note in the database so it will be easier to decode the posts. This is another reason why you should NOT change user input, but rather user output in case you start off by denying images, then you decide to allow it later on.
Also whitelist attributes too. Don’t let someone put JavaScript in an attributes (such as <div onclick=“MaliciousCode();”>)
Be sure to look out for SQL injection attacks and HTML injection attacks.
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.
I am providing my users to create their own widgets on their profile pages.Widgets are created by HTML codes by user input.
But Sometimes, if user enter an invalid html code, widget field is corrupting. To avoid this situation, I must be sure the html code that user entered is valid.
My question is how to check a html code validation via PHP or Javascript.
Thanks in advance.
You can use the tidy php extension;
There are a number of things that you can do with it, but for your case I think you could just use the repairString method to get the clean version of the user input and compare it with the initial version,
Something like this:
$tidy = new tidy();
$clean = $tidy->repairString($user_input);
If no changes were made during the repairString method; $user_input and $clean should be the same.
Take a look at this SO question / answers. The DOMDocument-Class may validate your HTML with PHP.
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>
I have the following example of what a user might type into a field for a post name:
<h1><span>They're awesome people</span></h1>
Now because this is a post title I want to remove all that HTML completely before saving it to the database. This is because for a) security reasons and b) if I export this as JSON I don't want to be cleaning up HTML on output for 3rd party users.
I have tried the following in my model:
public function beforeSave() {
if (isset($this->data[$this->alias]['title']))
{
//$this->data[$this->alias]['title'] = Sanitize::clean($this->data[$this->alias]['title'], array('encode'=>true,'remove_html'=>true));
$this->data[$this->alias]['title'] = html_entity_decode(Sanitize::html($this->data[$this->alias]['title'], array('remove'=>true)));
}
return true;
}
As you can see I have tried both Clean and HTML from the Sanitize class to clean out the HTML but both cause a problem in that they escape the quote from they're making it like '. I have tried using the html_entity_decode around the sanitize to clean this up but it still happens. Any ideas on how to do this?
If I do this though:
echo html_entity_decode('They're awesome people');
it works fine so the function is fine, it's a problem with using it in conjunction with the sanitize class in CakePHP.
Thanks
Why not use
Sanitize::paranoid()
Manual
Or even strip_tags
To make Sanitize::html work
Sanitize::html($var, array('remove'=>true, 'quotes' => ENT_NOQUOTES));
it uses htmlentities internaly and default flag is set to ENT_QUOTES.
You should try htmlspecialchars_decode() function.
Edit:
Using only PHP function instead CakePHP library, you can try strip_tags().