I am planning on using Tinymce but I am a little stumped on the security issues it will bring as I will be allowing logged users to create blogs on the site.
I will be allowing them to place image sources and URL links so they can link stuff to other websites to create a better blog and experience for the reader and possibly allow them to add a embedded video if it is not to hard to accomplish on a safe scale.
I understand that i am able to use mysqli_real_escape_string but I am unsure whether that will effect image sources and URL links and what security risks come with using mysqli_real_escape_string if it does allow users to insert images and URLs.
Is there better methods out there to get the service that I would like to give my writers and readers of the blogs that are created.
I understand that there will always be a certain degree of a security issue if I allow logged users to create blogs but I am unsure what levels of security I should use and the effects it will have on the finished blog.
Thanks for you time.
You could try HTML Purifier.
You should also consider converting your code from mysqli to PDO for better security.
I'm using Symfony2 / Twig / Doctrine.
I'm looking at security on my site and in particular preventing XSS attacks, but I can't see what more I can do.
Persistent
I use Doctrine and always ensure I make user input safe, refusing HTML, web addresses and email addresses etc. (if applicable, e.g. a comment box). I also use Twig (which I believe escapes output).
Reflective
My understanding is that anyone could send an email to someone with a link to any website that also injects JavaScript. That JS can of course do anything. That JS could have a login form be submitted to any web address and there is nothing you can do (other than hope stupid people don't click links from random people to my site's login page).
So unless you can prevent JS being injected, then what more can I do?
I don't believe you can prevent a site from running a JS script on another server (my valid JS comes from a CDN anyway which is on another server) and I don't think you can prevent a HTML form being submitted to another server.
I do believe that cross domain protection does prevent the injected JS calling an Ajax request though - but I haven't done anything about this, I just think that is how modern browsers work.
Is anything else in my hands? As long as I have done eveything else possible that's enough for me.
I suppose I'm wondering why there isn't much I can do about this when some people make a living out of advising on XSS protection. Maybe it's because I use Symfony2 / Twig / Doctrine?
Just looking for help to clarify my understanding.
Content Security Policy solves the problem of injected javascript by banning any inline javascript and validating content sources.
Info: https://developer.mozilla.org/en-US/docs/Security/CSP/Using_Content_Security_Policy
Browser support: http://caniuse.com/contentsecuritypolicy
is there any HTTP-header to disable Javascript for a specific page?
My website delivers user-generated HTML-content (that is why I cannot just use htmlenitities) and I would like to prevent scripting (JavaScript injections).
I already use HttpOnly-cookies being set for authentication on the main domain only, while user content is only displayed on subdomains where the cookie cannot be read.
The problem is that there are still too many possibilities to execute JavaScript - for example using event attributes like onclick and Internet Explorer has even a property in CSS to allow JavaScript executions (expression) which I had never heard of before. Another interesting idea I have read of, was about throwing an exception in order to block the code following.
One more idea would be defining a list containing all allowed tags and additionally an array with each allowed attribute name but this is very hard work and I guess this would not cover all possible injections.
I guess I am not the only person having this problem, so does anybody know a possiblility covering all possible harmful code - at least in modern browsers?
A simple imaginary header similar to X-Scripting: disabled would make life so much easier!
Yes, there is an experimental HTTP header called the Content Security Policy that allows you to control where JavaScript comes from, which can make XSS impossible. However it is currently only supported by Chrome and Firefox.
It is a good idea to enable HttpOnly-cookies, however this will prevent exactly ZERO attacks. You can still exploit XSS by reading CSRF tokens, and carrying out requests with an XHR.
There are many ways of obtaining XSS, and a Vulnerability Scanner like ShieldSeal (down) will find (nearly) all of them. Skipfish is an open source vulnerability scanner that is very primitive, but its free. This is how most web applications deal with wide spread vulnerabilities. (I work for ShieldSeal and I help build their vulnerability scanner and I love my job.)
When an issue is found you should use htmlspecialchars($var) or htmlspecialchars($var, ENT_QUOTES) to sanitize input. ENT_QUOTES can prevent an attacker from introducing an onclick or other JavaScript event.
Is there a way to make a mobile web page secure? (Encrypting or some secure way of make information secure)
I have heard that mobile web development environment is much different from formal web development.
I would like to make a mobile web page secure with mobile-web-only-tags (HTML), if possible.
Or any recommendations with server-side way (PHP) to make a page secure?
Depending on what your site is written in, some extra care may need to be taken. If your site is written completely in Javascript for example, then you must take extra care to prevent any XSS injection. OWASP is the number one source for this (https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet). Avoid document.write to dynamically create HTML, and instead use a templating framework like Mustache.js
If you submit any forms to your server, do client side validation but do not let this be your last line of defense. Like any website, server side validation is your primary defense against SQLi etc, but use the depth of defense tactics. Use SSL when submitting private information.
If you take any user input and then display it again, for example in a search form, then ensure you remove any HTML from that input.
Mobile web development is not very different from desktop dev, the same security principles are important and always apply. Also, your point about making a website secure using HTML tags is misguided. HTML does not provide security, it's merely a markup language.
I'm creating a PHP CMS, one that I hope will be used by the public. Security is a major concern and I'd like to learn from some of the popular PHP CMS's like Wordpress, Joomla, Drupal, etc. What are some security flaws or vulnerabilities that they have they had in the past that I can avoid in my application and what strategies can I use to avoid them? What are other issues that I need to be concerned with that they perhaps didn't face as a vulnerability because they handled it correctly from the start? What additional security features or measures would you include, anything from minute details to system level security approaches? Please be as specific as possible. I'm generally aware of most of the usual attack vectors, but I want to make sure that all the bases are covered, so don't be afraid to mention the obvious as well. Assume PHP 5.2+.
Edit: I'm changing this to a community wiki. Even though Arkh's excellent answer is accepted, I'm still interested in further examples if you have them.
Cross-Site Request Forgery (CSRF)
Description :
The basic idea is to trick a user to a page where his browser will initiate a POST or GET request to the CMS you attack.
Imagine you know the email of a CMS powered site administrator. Email him some funny webpage with whatever you want in it. In this page, you craft a form with the data used by the admin panel of the CMS to create a new admin user. Send those data to the website admin panel, with the result in a hidden iframe of your webpage.
VoilĂ , you got your own administrator account made.
How to prevent it :
The usual way is to generate random short-lived (15mn to hour) nonce in all your forms. When your CMS receive a form data, it checks first if the nonce is alright. If not, the data is not used.
CMS examples :
CMS made simple
Joomla!
Drupal
ModX
More information :
On the wikipedia page and on the OWASP project.
Bad password storing
Description :
Imagine your database get hacked and published on something like wikileak. Knowing that a big part of your users use the same login and password for a lot of websites, do you want them to be easy to get ?
No. You need to mitigate the damages done if your database datas become public.
How to prevent it :
A first idea is to hash them. Which is a bad idea because of rainbow tables (even if the hash is not md5 but sha512 for example).
Second idea : add a unique random salt before hashing so the hackers has to bruteforce each password. The problem is, the hacker can compute a lot of hash fast.
So, the current idea is to make it slow to hash the passwords : you don't care because you don't do it often. But the attacker will cry when he gets from 1000 hash generated per ms to 1.
To ease the process, you can use the library phpass developped by some password guru.
CMS examples :
Joomla! : salted md5
ModX : md5
Typo3 : cleartext
Drupal : switched to phpass after this discussion.
More information :
The phpass page.
Cross Site Scripting (XSS)
Description
The goal of these attacks, is to make your website display some script which will be executed by your legitimate user.
You have two kind of these : persistent or not. The first one comes usually from something your user can save, the other count on parameters given by a request sent. Here is an example, not persistent :
<?php
if(!is_numeric($_GET['id'])){
die('The id ('.$_GET['id'].') is not valid');
}
?>
Now your attacker can just send links like http://www.example.com/vulnerable.php?id=<script>alert('XSS')</script>
How to prevent it
You need to filter everything you output to the client. The easiest way is to use htmlspecialchars if you don't want to let your user save any html. But, when you let them output html (either their own html or some generated from other things like bbcode) you have to be very careful. Here is an old example using the "onerror" event of the img tag : vBulletin vulnerability. Or you have the old Myspace's Samy.
CMS examples :
CMS made simple
Mura CMS
Drupal
ModX
More information :
You can check wikipedia and OWASP. You also have a lot of XSS vector on ha.ckers page.
Mail header injection
Description :
Mail headers are separated by the CRLF (\r\n) sequence. When you use some user data to send mails (like using it for the From: or To:) they can inject more headers. With this, they can send anonymous mails from your server.
How to prevent it :
Filter all the \n, \r, %0a and %0d characters in your headers.
CMS examples :
Jetbox CMS
More information :
Wikipedia is a good start as usual.
SQL Injection
Description :
The old classic. It happen when you form a SQL query using direct user input. If this input is crafted like needed, a user can do exactly what he want.
How to prevent it :
Simple. Don't form SQL queries with user input. Use parameterized queries.
Consider any input which is not coded by yourself as user input, be it coming from the filesystem, your own database or a webservice for example.
CMS example :
Drupal
Joomla!
ModX
Pars CMS
More information :
Wikipedia and OWASP have really good pages on the subject.
Http response splitting
Description :
Like e-mail headers, the http headers are separated by the CLRF sequence. If your application uses user input to output headers, they can use this to craft their own.
How to prevent it :
Like for emails, filter \n, \r, %0a and %0d characters from user input before using it as part of a header. You can also urlencode your headers.
CMS examples :
Drake CMS
Plone CMS
Wordpress
More information :
I'll let you guess a little as to where you can find a lot of infos about this kind of attack. OWASP and Wikipedia.
Session hijacking
Description :
In this one, the attacker want to use the session of another legitimate (and hopefully authenticated) user.
For this, he can either change his own session cookie to match the victim's one or he can make the victim use his (the attacker's) own session id.
How to prevent it :
Nothing can be perfect here :
- if the attacker steal the victim's cookie, you can check that the user session matches the user IP. But this can render your site useless if legitimate users use some proxy which change IP often.
- if the attacker makes the user use his own session ID, just use session_regenerate_id to change the session ID of a user when his rights change (login, logout, get in admin part of the website etc.).
CMS examples :
Joomla! and Drupal
Zen Cart
More information :
Wikipedia page on the subject.
Other
User DoSing : if you prevent bruteforcing of login attempt by disabling the usernames tried and not the IP the attempts come from, anyone can block all your users in 2mn. Same thing when generating new passwords : don't disable the old one until the user confirm the new one (by loging with it for example).
Using user input to do something on your filesystem. Filter this like if it was cancer mixed with aids. This concern the use of include and require on files which path is made in part from the user input.
Using eval, system, exec or anything from this kind with user input.
Don't put files you don't want web accessible in web accessible directory.
You have a lot of things you can read on the OWASP page.
I remember a rather funny one from phpBB. The autologin cookie contained a serialized array containing a userId and encrypted password (no salt). Change the password to a boolean with value true and you could log in as anyone you wanted to be. Don't you love weaktyped languages?
Another issue that phpBB had was in an regular expression for the highlighting of search keywords that had a callback (with the e modifier), which enabled you to execute your own PHP code - for example, system calls on unsecure systems or just output the config file to get the MySQL login/password.
So to sum this story up:
Watch out for PHP being weaktyped ( md5( "secretpass" ) == true ).
Be careful with all code that could be used in a callback (or worse, eval).
And of course there are the other issues already mentioned before me.
Another application level security issue that I've seen CMSes deal with is insufficiently authorizing page or function level access. In other words, security being set by only showing links when you are authorized to view those links, but not fully checking that the user account is authorized to view the page or use the functionality once they are on the page.
In other words, an admin account has links displayed to go to user management pages. But the user management page only checks that the user is logged in, not that they are logged in and admin. A regular user then logs in, manually types in the admin page URI, then has full admin access to the user management pages and makes their account into an admin account.
You'd be surprised how many times I've seen things like that even in shopping cart applications where user CC data is viewable.
The biggest one that so many people seem to either forget or not realise is that anyone can post any data to your scripts, including cookies and sessions etc. And don't forget, just because a user is logged in, doesn't mean they can do any action.
For example, if you had a script that handles the adding/editing of a comment, you might have this:
if ( userIsLoggedIn() ) {
saveComment( $_POST['commentid'], $_POST['commenttext'] )
}
Can you see what's wrong? You checked that the user is logged in, but you didn't check if the user owns the comment, or is able to edit the comment. Which means any logged-in user could post a comment ID and content and edit others' comments!
Another thing to remember when providing software to others is that server set ups vary wildly. When data is posted you may want to do this, for example:
if (get_magic_quotes_gpc())
$var = stripslashes($_POST['var']);
else
$var = $_POST['var'];
So so many..
A number of answers here are listing specific vuls they remember or generic "things i worry about when writing a webapp", but if you want a reasonably reliable list of a majority of reported vulnerabilities found historically, then you wouldn't do much worse than to search the National Vulnerability Database
There are 582 vulnerabilities reported in Joomla or Joomla addons, 199 for Wordpress and 345 for Drupal for you to digest.
For generic understanding of common webapp vuls, the OWASP Top Ten project has recently been updated and is an essential read for any web developer.
A1: Injection
A2: Cross-Site Scripting (XSS)
A3: Broken Authentication and Session Management
A4: Insecure Direct Object References
A5: Cross-Site Request Forgery (CSRF)
A6: Security Misconfiguration
A7: Insecure Cryptographic Storage
A8: Failure to Restrict URL Access
A9: Insufficient Transport Layer Protection
A10: Unvalidated Redirects and Forwards
Four big ones in my mind:
using exec on untrusted data/code (or in general)
include-ing files from remote URL's for local execution
enabling register globals so that get and post variables
get variable values automatically assigned.
not escaping db entered data/ allowing SQL injection attacks
(usually happens when not using a DB API layer)
Disallow POST from other domain/IP So Bots cant login/submit forms.
People, the biggest security breech, is the human stupidity. Trust, review code. You need a special team, which will review anything that added as an extra code in your application, cms's problem are the outsource, the incomings, WordPress, Drupal, Joomla, and other popular cms, like default installations, they are really in a very good point secure. The problem is coming when you leave people to add extra code in your application, without a good review (or better, without penetration testing). This is the point where WordPress and Joomla have the weakness, there re so many plugin n theme devs, there are so many approvals,hundreds of outdated plugins n themes outhere.... So imho, if you are able to build a strong team, a good security plan, train your contributors, and learn them how to code secure, and with all the other comments before mine, then you will be able to move on and say :ei hi that's my cms, and it's a bit more secure than all the other cms on the net ;)
Here's a potential pitfall for forum admins especially, but also anyone who codes up a form with a dropdown selector but doesn't validate that the posted response was actually one of the available options.
In college, I realized that the user's 'country' selector in phpBB had no such validation.
In our school forum, Instead of 'United States' or 'Afganistan', my country could be ANYTHING, no matter how silly, or filthy. All I needed was an html POST form. It took my classmates a few days to figure out how I had done it, but soon, all the 'cool kids' had funny phrases instead of countries displayed under their usernames.
Going to a geek college was awesome. :D