How do I ensure user input is CSS and not malicious code? - php

On my website I want to include a text box that will allow the members to change anything they want css wise on their profiles....but I don't want to wake up one morning to find my site has been hacked or someone typoed and destroyed everything or accessed things they shouldn't.
Is there any easy way to verify that the text they input is css only? I saw another question on here that was similar, it had XSS cheat sheet and tips for what to disable (< and ]]> and < ![), but I don't know if that will be enough. I will definitely use that info though.
Essentially I want to just make PHP call any custom css and insert it between script tags for the users profile. I want to allow as much css as possible. Is this the best way to go about it? I don't have the know how to make up a system to generate safe files, or the patience to make up an entire section with options (especially since I want to give members more freedom with their profiles).
Any advice is appreciated, and if anyone knows of some script that does this already that would rock too and help me figure out what to do :D.

When a user is logged in, add a separate <link> element for that user. The href can point to a script that generates the css for the user, for instance customcss.php?userid=1234&version=2 *). The script only needs to return everything the user has entered before. Because you enclose it as a separate CSS file, the browser will always treat it as such and will never run any scripts. Any HTML or Javascript is just treated as invalid CSS.
Note however, that there's little harm anyway in including scripts for that matter, because they will only run in the browser of the logged in user, so they can only hack their own view of your site. If they want to inject Javascript, they can still do that by writing their own browser plugins, so you won't open up a possibility that wasn't there before.
The main thing you need to worry about are
Usability. What if the user makes a mistake and accidentally hides the Body element. How will they be able to reset it?
SQL injection. No matter what you do or do not allow, always make sure your input is sanatized.
PHP injection. Don't execute (eval) user content. Ever.
Hiding user information. Add a code to the customcss.php url to prevent other users from guessing a user id, gaining insight into the customizations of other users.
*) I've added a version number to the CSS url, which you should update in the database each time a user updates their CSS. If you don't do that, the browsers will cache the old CSS and users will start complaining to you, because their changes won't become visible.

I guess this should be enough
$style = $_POST['style'];
$style = strip_tags($style);
$forbiddenStuff = array(
'-moz-binding',
'expression',
'javascript:',
'behaviour:',
'vbscript:',
'mocha:',
'livescript:',
);
$style = str_ireplace($forbiddenStuff, '', $style);
store $style in db , and render on user profile.
Please note that this solution is copied from a well known software and which has a big community, so i hope this should be perfect.

O hai MySpace…
Just give users the ability to specify colours and images from a web form, and construct a user-specific style sheet from that. Allowing users to specify their own CSS in its entirety will just lead to ugly, ugly pages. See: MySpace 1.0.

Related

How to store user content while avoiding XSS vulnerabilities

I know similar questions have been asked but I am struggling to work out how to do it.
I am building a CMS, rather primitive right now, but it's as a learning exercise; in a production site, I would use an existing solution for sure.
I would like to take user input, which can be styled in a WYSIWYG editor. I would also like them to be able to insert images inline.
I understand I can store HTML in the database but how can I safely re-render this. I know there is no problem with the HTML being stored but it is my understanding that XSS become an issue if I were to just simply dump the user-generated code onto a layout template.
So the question put simply, is how can I store and safely rerender user content in cms? I am using Laravel and PHP. I also have a little knowledge of javascript if its required.
For a CMS where you want to allow some tags but not others, then you want something like HTML Purifier. This will take HTML and run it against a whitelist and regenerate HTML that is safe to display back to the user.
A good and cheap way to avoid cross-site scripting is to get your php program to entitize everything from your users' input before storing it in the database. That is, you want to take this entry from a user
Hi there sucker! I just hacked your site.
<script>alert('You have been pwned!')</script>
and convert it to this before putting it into your database.
Hi there sucker! I just hacked your site.
<script>alert('You have been pwned!')</script>
When you pass < to a browser, it renders it as <, but it doesn't do anything else with it.
The htmlentities() function can do this for you. And, php's htmlspecialchars_decode() can reverse it if you need to. But you shouldn't reverse the operation unless you absolutely must do so, for example to load the document into an embedded editor for changes.
You can also choose to entitize user-furnished text after you retrieve it from your database and before you display it. If you get to the point where several people work on your code, you may want to do both for safety.
You can also render user-provided input inside <pre>content</pre> tags, which tells the brower to just render the text and do nothing else with it.
(Use right-click Inspect on this very page to see how Stack Overflow handles my malicious example.)

OWASP Cross Site Scripting rules?

I'm reading about XSS to educate myself on security while working with PHP. I'm referring to this article, in which they talk about XSS and some of the rules that should be adhered to.
Could someone explain Rules #0 and #1 for me? I understand some of what they are saving, but when they say untrusted data do they mean data entered by the user?
I'm working on some forms and I'm trying to adhere to these rules to prevent XSS. The thing is, I never output anything to the user once the form is complete. All I do is process data and save it to text files. I've done some client-side and a lot of server-side validation, but I can't figure out what they mean by never insert untrusted data except in allowed locations.
By escaping do they mean closing tags - </>?
Rule #0 means that you should not output data in locations of your webpage, where it's expected to run instructions.
As shown on your url, do not put user generated data inside <script>tags. For example, this is a no-no:
<script>
var usernameSpanTag = document.getElementById('username');
usernameSpanTag.innerText = "Welcome back, "+<?=$username?>+"!";
</script>
Looks pretty safe, right? Well, what if your $username variable contains the following values:
""; console.log(document.cookie);//
So, on a website what you're going to display is going to be this:
<script>
var usernameSpanTag = document.getElementById('username');
usernameSpanTag.innerText = "Welcome back, "+""; console.log(document.cookie);//+"!";
</script>
So someone can easily steal your user's cookies and elevate their privileges. Now imagine that you're using similar code to say, update which user created the latest post, and shows up via AJAX. That's a disaster waiting to happen if you do something like above (and do not sanitize the username in the first place).
Same applies for <style>,<img>, <embed>, <iframe> or any other tag that lets you run scripts or import resources. Also applies to comments. Browsers ignore comments, but some interpreters like the JSP parser handles HTML comments as template text. It doesn't ignore its contents.
Rule #1 is pretty similar tu rule #0, if you're developing web applications at some point or another you will have to output user generated data, whether it is an email address, a username, a name, or whatever.
If you're developing a forum, probably you may want to give your users some styling options for their text. Basic stuff like bold letters, underlined and italics should suffice. If you want to get fancy, you may even let your users change the font.
An easy way to do it, without too many complications, is just letting users write their own HTML if they choose to do so, so if you output HTML from your users in "safe" locations like between <p> tags, then that's a disaster waiting to happen as well.
Because I can write:
Hey everybody, this is my first post <script src="//malicioussite.io/hackingYoCookiez.js"></script>!
If you don't escape that input, people will only see:
Hey everybody, this is my first post`!
but your browser will also see an external javascript that tells it to send everybody's cookies to a remote location.
So always escape the data. If you're using PHP you can use htmlentities or use a template engine like Twig, that automatically escapes the output for you.

Making a PDF or page viewable only once, and protecting it from being printed or shared

On our Wordpress site we would like to have some pages or files made available only to members who pay a fee to view the material once. The content could be either a site page or a PDF, but the key is we want a member to only be able to see it just that one time, and we also want to be sure the client cannot print, copy or share it.
We realize anything on the screen can be grabbed, and yes, there in theory will always be some who will then run it through an OCR or simply type it out, but the number will be relatively small, especially within our specific group. So with all that said, do you know of a "best" way to protect a page or file from being easily shared or printed?
Thank you!
By the very nature of web content being loaded into your browser it's technically on your system as a temporary file. PDF is meant to be a PORTABLE document.
As for a webpage you can create new print styles that will mess up the printing, and add some javascript to make copying a pain, but this is hacking the intended purpose of web documents.
Another alternative (not that I'm endorsing this!) would be to make the content in Flash! It's always a pain to rip off ;)
You could setup a simple database access table that stores a userid against the page/file URL.
access_id | user_id | resource_url
when the user views a page then you can check against this table, something like:
SELECT access_id
FROM access_table
WHERE user_id = {YOUR_USER_ID}
AND resource_url = "{CURRENT_URL}"
if you get a result then allow access, and delete the row. Next time they try the URL, there will be no result, so deny access.
With pdfs, to implement this you would need a wrapper script that you call with a parameter ($_GET['resource_id']), which contains the above code and then outputs the pdf contents to screen using headers and file_get_contents().
NOTE: This of course wont solve the problem completely as others have mentioned, but should add an extra layer of protection, as it will prevent a URL from being shared

PHP databases - don't want to show javascript code

I have problem with PHP and JavaScript/CSS.
I have database with table. The table has a descriptions of articles. I want to echo the descriptions of the articles from database. Unfortunately many of them has a JavaScript or CSS included ( Then some article text), so when I use echo, it shows all of that code (and after that text). Is there any way to not show the JavaScript/CSS part and show only the text? For example with str_replace and regular expression? If yes, can somebody write me how it should look like?
Thanks for help and let me know if u need more info (code etc.)
Use HTMLPurifier - it will remove the scripts, css and any harmfull content from your articles. Since it is a CPU-intensive operations, it's better to run article trough HTMLPurifer before saving in the database, then to run it each time you are showing the article.
If you're trying to remove tags from a user's post, you can call strip_tags. This will get rid of css links, script tags, etc. It will not get rid of the style attribute, but if you get rid of div, span, p, etc. that won't matter -- there will be no tag for it to reside on.
As has been stated by others, it is generally best to sanitize your input (data from user before it goes into the DB), than it is to sanitize your output.
If you're trying to simply hide the JS and CSS from users, you can use Packer to obfusicate Javascript from less-savvy users, use Packer and use base 62 encoding. The JS will still work but will look like jiberish. Be aware that more knowledgeable users can attempt to unobfusicate the code, so any critical security risks in the JS still exists. Don't think any JS that accesses your databases directly will be safe; instead remove database access from the Javascript for security. If the JS is just to do fancy things like move elements around the page it's probably fine to just obfuscate it.
Only consider this if YOU have complete control and awareness of all JS included with the articles. If this is something your anonmous or otherwise not 120% trusted users can upload, you need to kill that functionality and use HTML Purifier to remove any JS they might add. It is not safe to output user entered JS, for you or your users.
For the CSS, I'm not sure why you want to hide it, and CSS can't be obfuscated quite like JS can; the styles will still be in plain English, best you can do is butcher the class/id names and whitespace; outputting CSS that YOU generated isn't a real security risk though, and even if people reverse engineer it I wouldn't be that afraid.
Again, if this is something anonymous/non trusted users can ADD to your site on their own, you don't want this at all, so remove the ability to upload CSS with an article using the HTML Purifier Darhazer mentioned.
You can try the following regex to remove the script and css:
"<script[\d\D]*?>[\d\D]*?</script>"
"<style[\d\D]*?>[\d\D]*?</style>"
It should help, but it cannot remove all the scripts. Like onclick="javascript:alert(1)".

PHP: Safe to allow users to write custom CSS to customize a webpage on my site?

I am building a web app to allow others to design their own pages. I am using PHP, MySQL.
I was wondering. Is it SAFE to allow users to customize their pages by writing their own CSS code?
So I was thinking of a TEXTAREA field that they can then enter in their CSS code.
I am using PHP filter_var($string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH); to filter the string before it's saved to my database.
So.... allow it or disallow?
Thanks!
No.
IE allows you to include JavaScript files via CSS (behavior attribute) for example. However, if ONLY the user who entered the CSS code will ever see it, it's safe.
If you restrict the allowed attributes it's also safe - but note that you have to restrict values too (again, thanks to IE, which allows dynamic values using JavaScript).
It's safe in the sense that users can override your CSS with their own anyway, with a browser plug-in and so on. Just make sure that one user can't affect the CSS for another user.
Use dedicated escaping functions to sanitise the data for your database, though. e.g. mysql_real_escape_string() for MySQL.
It should generally be safe to allow users to enter their own CSS code for their sites. Browsers already implement their own user agent CSS to enforce a common styling on unstyled elements. (From the CSS2 specification: "a user agent’s default style sheet should present the elements of the document language in ways that satisfy general presentation expectations for the document language") Also, a large part of ensuring accessibility on a site is to allow customer user agent CSS.
Just because this likely can be safely done does not mean it should be, however. Any user could easily set the background image for an element to an inappropriate image on the web, for one example. Providing the ability to do this only opens the door for malicious attacks on your site and should be generally avoided in my opinion.
Sanitize the code is the best practice.
To avoid IE holes, you can use the W3C validator to check the CSS sintax before to save.
http://jigsaw.w3.org/css-validator/api.html
Hope it helps. Ciao!

Categories