I can't seem to find an almost exact question so I might as well ask away.
Is it really a standard practice to send variables from Javascript to PHP? I'm planning to send array to PHP after some several assessment within Javascript - passing variables here and there...only to be combined again as an array, and as I've said, will be passed to PHP. Am I missing something? I hardly see any tutorials to do this, mostly the other way around - that is, PHP array to Javascript. Makes me think, maybe it just isn't being advised to do Javascript to PHP due to security reasons.
Simply put, will sending Javascript array to PHP that will later on be saved to database be dangerous? I haven't really FULLY read how to do it, just scanned the very few that I could find...json stringify, $_POST, json encode, json decode. If it is fine to do JS to PHP passing, and since it is related to my question anyway, can someone point me which of those mentioned is best for better security? Thanks!
Security isn't really an issue at this point: JavaScript runs on client side, so anything that could go wrong here could be easily faked by an attacker. You can't trust the client anyway, as #Jan puts it in the comments above. Also, everything you do on the JavaScript end can be eavesdropped and manipulated by the client - that's why you can't do a password check in JavaScript, for example. So, the environment JavaScript operates in is fundamentally insecure, anyway.
Security comes into play when the server accepts and uses the data. You need to have all necessary protections in place so the data can't harm your server - for example, remove any SQL injections by using escaping or prepared statements, deal properly with invalid input characters, etc.
Two exceptions to the rule come to mind:
If you are on a SSL (https://) connection, make sure your JavaScript sends the data that way too
Sending the browser to a new location with sensitive GET parameters:
http://www.domain.com/newpage?username=pekka&password=superman85069
is less secure than POSTing a form, because the URL may be cached.
Related
Do I always need to validate user input, even if I'm not actually saving them to a db, file, or using them to include files etc..
Say I just wanted to echo out a request variable or I was using it to send email, is there any need to validate or sanitise it? I've always heard people say that all user input should be checked before doing anything with it, but does it actually pose any threat, if I'm not doing any of the above?
I wouldn't recommend it.
my rule is - NEVER TRUST USER'S INPUT.
lets say that your'e working on a team.
as you wrote, you build a simple form that submit the data to php file and than mail it.
after 3 weeks another team mate wants to use that form.
he's assuming that the data in the php file is clean . he dont know that you dont filtered it.
this is a crack for troubles.
Do I always need to validate user input, even if I'm not actually saving them to a db, file, or using them to include files etc..
Everything you are going to do with user supplied data depends on the context in which you are going to use it. In your single sentence you are already talking about 3 different contexts (db, file, include). Which all will need a different strategy to prevent things for that specific context.
Say I just wanted to echo out a request variable or I was using it to send email, is there any need to validate or sanitise it?
There are more things you can do besides validating and sanitizing. And yes you should handle this case (which is another context btw). Basically you should handle all user data as if it is malicious. Even if you are "just echoing it". There are numerous things I could do when you are "just echoing".
Considering we are in the context of a HTML page I could for example (but not limited to) do:
<script>location.href='http://example.com/my-malicious-page'</script>
Which can be for example an exact copy of you website with a login form.
<script>var cookies = document.cookie; // send cookieinfo to my domain</script>
Which can be used to get all your cookies for the current domain (possibly including your session cookie). (Note that this can and imho should be mitigated by setting the http only flag on the cookies).
<script>document.querySelector('body')[0].appendChild('my maliscious payload containing all kinds of nasty stuff');</script>
Which makes it possible to sideload a virus or something else nasty.
<!--
Fuck up your layout / website. There are several ways to do this.
I've always heard people say that all user input should be checked before doing anything with it
This is mostly wrong. You only need to decide how you are going to handle a piece of data once you know what you are going to do with it. This is because you want to prevent different things in different situations. Some examples are (but not limited to): directory traversal, code injection, sql injection, xss, csrf.
All above attack vectors need different strategies to prevent them.
but does it actually pose any threat, if I'm not doing any of the above
yes totally as explained above. All data that is coming from a 3rd pary (this means user input as well as external services as well as data coming out of the database) should be treated as an infectious disease.
I am creating a web application that uses JQuery's AJAX calls as it deals with all of the browser inconsistencies.
However, as the code is very much easily readable from the browser I have has concerns about what security measures I can use to protect the web application from attack.
I will be obviously doing authentication checks for the server side code to ensure that they have access to the data that they are trying to access. However, I have also been trying to look into ways of stopping CSRF attacks as well as looking into ways of 'obscuring' the code so it is not easily readable via View Source in the browser.
What steps should I be taking to ensure that security is at a good level?
Also is injecting data into a jquery script via PHP a bad idea?
Thanks!
There's no easy answer to your main question. You should read the OWASP guide on CSRF prevention and go from there.
And there's plenty of options out there for obfuscating javascript, but none of them will increase the security of your code. If an attacker really wanted to read your obfuscated code, he could just pick through it by hand or write a parser for it and simply de-obfuscate it. Not a viable security technique.
Also is injecting data into a jquery script via PHP a bad idea?
As long as you have no problem with the world seeing that data, no it is not a bad idea. If the data is sensitive, you'll probably want to keep it server-side, or hash it with a salt and then insert the hashed value into the script. Of course, this hash is rather unusable client-side because you must not include your salt in anything client-side (this would defeat the purpose of obfuscating the data in the first place). If you want to make use of that data, you'll need to ajax it back to your server and process it there.
I'm building a PHP framework, and in it I have a request object that parses the url as well as the $_GET, $_POST and $_FILE superglobals.
I want to encourage safe web habits, so I'm protecting the data against SQL injection, etc.
In order to ensure users of this framework are accessing the safe, clean data through the request object, I plan to use unset($_GET, $_POST, $_REQUEST); after parsing those variables.
I will document this in the method comments, and explain in the framework documentation that this is happening.
My question is: Would this be desirable behavior? What are the potential pitfalls that I have not foreseen?
I know this was answered already, but here's my $0.02.
I would not unset or clear the input arrays. However, what I have done is to replace them with an object. So instead of having the raw array, I replace it with an object that implements ArrayAccess and Iterator. That way the vast majority of code which uses the native arrays will still work quite well with the object.
The rationale is that at least you can verify that the code paths are operating correctly via tests. You can replace those objects with a mock object to throw an exception during testing so that you can detect improper access to those arrays (if you do determine it to be "bad practice"). So it lets you run during production without putting un-necessary restrictions, but also lets you turn it on to verify best-practices during testing.
And while I do agree with #JW about escaping, you should be filtering input. Filter-in, Escape-out. Any time data comes into your program (either via user input or from a DB), filter it to expected values. Any time data goes out (either to the DB or to the user), you need to properly escape it for that medium. So using a request object that enables easy filtering of the submitted data can be very valuable.
An example using a fluent interface (which you may or may not want):
$id = $request->get('some_id')->filter('int', array('min' => 1));
And that doesn't include the benefits of compensating for differing platforms and configurations (for example, if magic_quotes_gcp is enabled or not, etc)...
Anyway, that's just my opinion...
I'm not sure what the point would be of preventing access to the $_GET or $_POST arrays. There's nothing harmful in them. If you're creating a framework for preventing SQL injection or cross-site-scripting, you should escape the data when creating an SQL query or HTML document.
Escaping GET/POST data at the beginning is too early; you don't know how the data will be used, so you can't escape or encode it properly.
Having said that, you still may have some valid reasons to want people to access GET/POST data through your code. In that case, I still wouldn't unset them. You may end up incorporating third-party code which relies on them. Instead, just encourage your users to avoid them (like they should avoid global variables in general).
I'd maybe expose a method (maybe hidden or super counter-intuitive ;)) to get the raw data, in the off chance that your sanitization routines corrupt data in some unforeseen manner. To protect the user is one thing, but to completely lock them from their ability to retrieve data in the most raw manner may lead to frustration and, as a result, those people not using your framework :)
Keep in mind this increases your maintenance costs...if anything is ever added, removed or changed with the super globals in PHP, you will need to update your framework.
Sounds like magic_quotes style thinking. Except, at least magic_quotes was 99% reversible at runtime. Your "cleaned" data might be lossy, which really sucks.
I'm a bit behind the times when it comes to website security. I know the basics - validate all incoming data, escape data being saved to the db, use a salt for passwords, etc. But I feel like there's a lot I'm missing that can bite me in the butt. This is especially true with my slow migration to .NET. I'm just not sure how to replicate what I know in PHP in .NET. So, below are some things I've been thinking about that I'm sure I need help with.
Problem: Securing sessions
PHP: Use session_regenerate_id() whenever a user does something important.
.NET: No idea how to replicate that here.
General: What else am I missing?
Problem: XSS
PHP: Use htmlentities() to convert potentially dangerous code into something that can be rendered (mostly) harmlessly.
.NET: I believe in MVC, using <%: %> tags in a view does the same thing.
General: Is there more I can do to block JavaScript? What about denying HTML entirely? How would one secure a textarea?
Problem: Remote Execution
PHP: Use regEx to find and remove eval() function calls.
.NET: Unsurprisingly, no idea.
General: Again, is there more I should look for?
Problem: Directory Traversal (probably related to the above)
I'm just not sure how worried I should be about this. Nor am I sure how to block it.
Suggestions, links to articles (with code examples), etc. are most welcome, and would be greatly appreciated.
session_regenerate_id
I don't think there is an equivalent. Sessions are short lived, so if the attacker will get into the session in time, that should also happen after you change the access level.
Something additional is that sessions aren't meant to authenticate the user in asp.net. When using custom authentication you use Forms Authentication.
Above said, anything you do is subject to a man in the middle attack. This is the case for lots of sites, so cookie hijacking is a problem all around.
When doing anything special, require the user to enter their password again / which should be done over https. If you need to do a series of special operations, you can do that once but from then on requests/cookies need to be sent over https. In this context, you could emit a modified forms authentication cookie, that allows access to the special operations and has require https on.
I believe in MVC, using <%: %> tags in a view does the same thing.
Yes, that's kind of the equivalent to <%= Html.HtmlEncode(someString) %> / with something extra to prevent double encoding (should look into that).
Use regEx to find and remove eval() function calls.
In .net you don't have such a shorthand with so broad access. If you are not explicitly doing anything out of the ordinary, you are likely ok.
Directory Traversal (probably related to the above)
Use MapPath and similar. It actually prevents going outside of the site folder. This said, avoid receiving paths altogether, as you can still give unintended access to special files inside the asp.net folder. In fact, this is part of what happened to a Microsoft handler in the padding oracle vulnerability out there - more on my blog
You can add CSRF to the list.
Use the anti forgery token: http://blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/
padding oracle attack:
Apply the work arounds & then the patch as soon as its out.
Learn about all that I mention here: asp.net padding oracle: how it relates to getting the web.config, forging authentication cookies and reading other sensitive data. Understanding all that's in there is important, specially if you use any of the features i.e. you don't want to be the one putting sensitive data in the view state :)
You can add CSRF to the list. They tend to be prevented by adding a hidden token in the form of your application, possibly matching a cookie, and then checking they both match when processing the form data submitted.
I'm new to PHP and I'm following a tutorial here:
Link
It's pretty scary that a user can write php code in an input and basically screw your site, right?
Well, now I'm a bit paranoid and I'd rather learn security best practices right off the bat than try to cram them in once I have some habits in me.
Since I'm brand new to PHP (literally picked it up two days ago), I can learn pretty much anything easily without getting confused.
What other way can I prevent shenanigans on my site? :D
There are several things to keep in mind when developing a PHP application, strip_tags() only helps with one of those. Actually strip_tags(), while effective, might even do more than needed: converting possibly dangerous characters with htmlspecialchars() should even be preferrable, depending on the situation.
Generally it all comes down to two simple rules: filter all input, escape all output. Now you need to understand what exactly constitutes input and output.
Output is easy, everything your application sends to the browser is output, so use htmlspecialchars() or any other escaping function every time you output data you didn't write yourself.
Input is any data not hardcoded in your PHP code: things coming from a form via POST, from a query string via GET, from cookies, all those must be filtered in the most appropriate way depending on your needs. Even data coming from a database should be considered potentially dangerous; especially on shared server you never know if the database was compromised elsewhere in a way that could affect your app too.
There are different ways to filter data: white lists to allow only selected values, validation based on expcted input format and so on. One thing I never suggest is try fixing the data you get from users: have them play by your rules, if you don't get what you expect, reject the request instead of trying to clean it up.
Special attention, if you deal with a database, must be paid to SQL injections: that kind of attack relies on you not properly constructing query strings you send to the database, so that the attacker can forge them trying to execute malicious instruction. You should always use an escaping function such as mysql_real_escape_string() or, better, use prepared statements with the mysqli extension or using PDO.
There's more to say on this topic, but these points should get you started.
HTH
EDIT: to clarify, by "filtering input" I mean decide what's good and what's bad, not modify input data in any way. As I said I'd never modify user data unless it's output to the browser.
strip_tags is not the best thing to use really, it doesn't protect in all cases.
HTML Purify:
http://htmlpurifier.org/
Is a real good option for processing incoming data, however it itself still will not cater for all use cases - but it's definitely a good starting point.
I have to say that the tutorial you mentioned is a little misleading about security:
It is important to note that you never want to directly work with the $_GET & $_POST values. Always send their value to a local variable, & work with it there. There are several security implications involved with the values when you directly access (or
output) $_GET & $_POST.
This is nonsense. Copying a value to a local variable is no more safe than using the $_GET or $_POST variables directly.
In fact, there's nothing inherently unsafe about any data. What matters is what you do with it. There are perfectly legitimate reasons why you might have a $_POST variable that contains ; rm -rf /. This is fine for outputting on an HTML page or storing in a database, for example.
The only time it's unsafe is when you're using a command like system or exec. And that's the time you need to worry about what variables you're using. In this case, you'd probably want to use something like a whitelist, or at least run your values through escapeshellarg.
Similarly with sending queries to databases, sending HTML to browsers, and so on. Escape the data right before you send it somewhere else, using the appropriate escaping method for the destination.
strip_tags removes every piece of html. more sophisticated solutions are based on whitelisting (i.e. allowing specific html tags). a good whitelisting library is htmlpurifyer http://htmlpurifier.org/
and of course on the database side of things use functions like mysql_real_escape_string or pg_escape_string
Well, probably I'm wrong, but... In all literature, I've read, people say It's much better to use htmlspellchars.
Also, rather necessary to cast input data. (for int for example, if you are sure it's user id).
Well, beforehand, when you'll start using database - use mysql_real_escape_string instead of mysql_escape_string to prevent SQL injections (in some old books it's written mysql_escape_string still).