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
Related
I have a public form that publish POST data to a PHP script.
This form is not located on the same domain, and doesn't use PHP either so the protection cannot be built around PHP session.
The goal is to allow only this form to post on that PHP script.
How do I provide more security for checking source of the request tells how to implement CSRF protection using PHP session but I wonder how I could do to protect mine without it? Is it possible?
POST requests are harder to fake compared to GET requests, so you have that going for you, which is nice. Just make sure you're not using $_REQUEST in your script.
You cannot use sessions here, but the principles are the same - you gotta implement some kind of a "handshake" between a form and your PHP script. There are a few different approaches if sessions are not an option.
The simplest thing to do would be to check http referrers. This will not work if the form is on http and script is under https, and also can be overcome using open redirect vulnerability.
Another way to go would be captchas. I know, not user friendly or fashionable these days, but that would make request forgery much harder, as hacker could not make his exploit work behind the scenes without any user input. You should look into reCAPTCHA (google's "I am not a robot" checkbox): https://www.google.com/recaptcha/intro/index.html
This is a tricky situation, because form on one host and script on another is basically CSRF in itself, so you want to allow it but only for one host. Complete security without any user interaction might be impossible here, so just try to make it as hard as possible for a would-be hacker to mess with your script, or suffer on the UX side. Personally i would go with reCAPTCHA.
I have a membership website where users can embed their own code into their profile. I would like to allow them to include embed codes on their profile such as YouTube and Javascript embed codes.
I noticed JsFiddle.net can do this. Does anybody know how to duplicate this security?
Thank you for any help!
Set up a completely separate domain name (e.g. "exampleusercontent.com") exclusively for user-submitted HTML, CSS, and JavaScript. Do not allow this content to be loaded through your main domain name. Then embed the user content in your pages using iframes.
If you need tighter integration than simple framing, window.postMessage() may help, allowing scripts in different frames to communicate with each other in a controlled manner.
Alternatively, Google Caja is an open-source compiler for sandboxing third-party JavaScript, although from time to time, someone has discovered a vulnerability in it.
You may not want to rely on Caja as your sole layer of defense. After all, Facebook did give up on a similar system (called FBML/FBJS) in favor of the iframe sandboxing approach.
I assume you want security from malicious code injection, sql injection, etc.
When the form is submitted you'll need to verify the input server side. As long as you validate it there for what you expect it to be you should be okay. The only validation you do within JavaScript (if any) should be for helping the user add their information to the form and see where they've gone wrong, assistance in other words.
I've used the YouTube API in the past to validate video entries. Not sure if Vimeo has an API, I'd be surprised if it didn't though.
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.
I have a question about security. I have a website programmed with HTML, CSS, PHP, Javascript(jQuery)...
Throughout the website, there are several forms (particularly with radio buttons).
Once a user selects and fills out the form, it takes the value from the selected radio button and sends that to the server for processing. The server also takes the values and plugs them into a database.
My concern is this:
How can I prevent someone from using a developer tool/source editor (such as Google Chrome's Debugging/Developer Tool module) and changing the value of the radio button manually, prior to hitting the submit button? I'm afraid people will be able to manually change the value of a radio button input prior to submitting the form. If they can indeed do that, it will entirely defeat the purpose of the script I am building.
I hope this makes sense.
Thank you!
John
How can I prevent someone from using a developer tool/source editor (such as Google Chrome's Debugging/Developer Tool module) and changing the value of the radio button manually, prior to hitting the submit button?
You can't. You have no control over what gets sent to the server.
Test that the data meets whatever requirements you set for it before inserting it into the database. If it isn't OK, reject it and explain the problem in the HTTP response.
Any data sent from the browser to the server can be manipulated outside of your control, including form data, url parameters and cookies. Your PHP code must know what sets of values are valid and reject the request if it doesn't look sensible.
When sending user input to the database you will want to ensure that a malicious user-entered string can't modify the meaning of the SQL query. See SQL Injection. And when you display the user-entered data (either directly in the following response, or later when you read it back out of the database) ensure that you encode it properly to avoid a malicious user-entered string executing as unwanted javascript in the user's browser. See Cross-site scripting and the prevention cheat sheet
I'll go along with Quentin answer on this.
Client-side validation should never stand alone, you'll need to have some sort of server-side validation of the input as well.
For most users, the client-side validation will save a round trip to the server, but at as you both mention, there is no guarentee that "someone" wouldn't send wrong data.
Therefore the mantra should be: Always have server-side validation
I would say that client-side validation should be used solely for the user's convenience (e.g., to alert them that they have forgotten to fill in a required field) before they have submitted the form and have to wait for it to go to the server, be validated, and then have it sent back to them for fixing. What a pain. Better to have javascript tell you right there on the spot that you've messed something up.
Server-side validation is for security.
The others said it already, you can't prevent users from tampering with data being sent to your server (Firebug, TamperData plugins, self-made tampering proxies...).
So on the server side, you must treat your input as if there were no client validation at all.
Never trust user input that enters your application from an external source. Always validate it, sanitize it, escape it.
OWASP even started a stub page for the vulnerability Client-side validation - which is funny - client-side validation seems to have confused so many people and been the cause of so many security holes that they now consider it a vulnerability instead of something good.
We don't need to be that radical - client-side validation is still useful, but regard it simply as an aid to prevent the user from having to do a server roundtrip first before being told that the data is wrong. That's right, client-side validation is merely a convenience for the user, nothing more, let alone an asset to the security of your server.
OWASP is a great resource for web security. Have a look at their section on data validation.
Some advice worth quoting:
Where to include validation
Validation must be performed on every tier. However, validation should be performed as per the function of the server executing the code. For example, the web / presentation tier should validate for web related issues, persistence layers should validate for persistence issues such as SQL / HQL injection, directory lookups should check for LDAP injection, and so on.
Follow this rule without exception.
In this scenario, I'd recommend that you use values as keys, and look those up on the server side.
Also, consider issuing a nonce in a hidden field every time someone loads a form - this will make it a bit more difficult for someone to submit data without going through your form.
If you have a lot of javascript, it's probably worth running it through an obfuscator - this not only makes it harder for hackers to follow your logic, it also makes scripts smaller and faster to load.
As always, there is no magic bullet to stop hacking, but you can try raising the bar enough to deter casual hackers, then worry about the ones who enjoy a challenge.
Is the XSS attack made by user input?
I have recived attacks like this:
'"--></style></script><script>alert(0x002357)</script>
when scanning a php page without any html content with acunetix or netsparker.
Thanks in advance
Remember that even if you had just a static collection of HTML files without any server-side or or client-side scripting whatsoever, you may still store you logs in an SQL database or watch them as HTML using some log analyzer which may be vulnerable to this kind of URIs. I have seen URIs in logs that were using escape sequences to run malicious command in command line terminals – google for escape sequence injection and you may be surprised how popular they are. Attacking web-based log analyzing tools is even more common – google for log injection. I am not saying that this particular attack was targeted at your logs but I'm just saying that not displaying any user input on your web pages doesn't mean that you are safe from malicious payloads in your URIs.
I'm not 100% sure I understand your question. If I understood you correctly, you used a security scanner to check your web application for XSS vulnerabilities and it did show a problem about which you aren't sure if it really is a problem.
XSS is pretty simple: whenever there is a way to force an application to display unfiltered code a user provided, there is a vulnerability.
The attack code you show above seems to target a style tag that add certain user provided data (eg. a template variable or something similar). You should check if there's such a thing in your app and make sure it's properly filtered.
Blackbox scanners will try this attack even when your html doesn't expect any parameter because there is no easy way for them to know what's going on in your source code), if you don't echo anything or use stuff like PHP_SELF you are fine.
Also take a look at DOM Based XSS to understand how XSS might happen without any server-side flaw.
If the scanner reports a vulnerability take a look at the description and source code, generally it will hilight the vulnerable part of the source code so you can see.
Secondly you can manually test and if executes JS then you can investigate whether it's about your framework, or a vulnerability in the javascript code or in URL Rewrite (maybe you echo your current path in the page) or something like that.
Where did you find this XSS? As far as I am aware if a page does not take any user-input (a process/display it) it cannot be vulnerable to XSS.
Edit:
I think I misunderstood your question - did you mean can XSS occur by entering Javascript in the address bar in the browser? Or by appending Javascript to the URI? If the latter - then the page is susceptible to XSS and you should use a whitelist for any variables passed to your URI. If the former, then no, any client-side changes in the address bar will only be visible to that single user.