Website security - help me suck less - php

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.

Related

Is there anything I need to worry about besides SQL injections and XSS attacks?

I'm finishing up my first "real" PHP application and I am trying to make sure it is secure. I'm kind of afraid that since I'm not an "expert" PHP programmer that I might be missing something huge, so I would like to give you some information about my application and hopefully you can tell me whether or not that is the case. So here we go:
I'm using a CMS to handle user authentication, so I don't have to
worry about that.
After discovering PDO shortly after starting work
on my application, I ported all of my code over to using prepared
statements with PDO.
I am escaping all form and database data (even stuff I think is safe) which is being output with htmlentities().
My application does use a session variable and cookie variable, but the function of both is very unimportant.
I have designed my form processing functions in such a way that it doesn't matter if the form were somehow altered, or submitted from off-server (i.e. I always check the data submitted to ensure it's valid).
I have done my best to make all error messages and exception messages polite but very obscure.
I'm forcing pages with sensitive information (such as the login page) to be served over https.
When I first starting writing my application, I didn't know about prepared statements, which is kind of a huge deal. Have I missed anything else?
OWASP maintains a list of the Top 10 Most Critical Web Application Security Risks (warning, PDF download). This is from 2010, but I think it still applies, perhaps even moreso now.
Injection and XSS are the top two, but you should certainly be aware of the other 8. If you are using an existing CMS, many of these may already be considered, but the more popular the CMS the more you risk running into vulnerabilities because of black hats trying to find holes in it.
If you are not storing critical data like credit cards, order history, addresses, and even emails, then I wouldn't worry too much about your site being affected as long as you are taking the basic precautionary measures (and it sounds like you are).
If you are concerned about security issues, a good resource is the OWASP - Top 10 Application Security Risks
The most important thing to take care in web applications(specially PHPs') is Data Validation of all the inputs taken from the user which are further saved in your database.
For a secure application, all the transactions should be done on HTTPS. For a secure cookie management Secure and HTTPOnly cookie should be implemented.
Some more points I don't see mentioned yet. Most of these are not related to code - I am not sure if you only wished for things related to code, but I'll mention them anyway.
Backups (user data). should be self-evident
Version control. If you have a big bug, you want to have access to the previous version.
Audit trail, alarms and logging. If you do get into trouble, how will you find out? Are you able to track down what happened? if you know something is wrong but don't fully know what, are you able to diagnoze the issue?
Hosting. Where are you hosting? Do you have adequade bandwidth and monitoring? What happens if you get DOSed? Are you able to block out unwanted traffic?
Caching. Can you change it if needed?
There's always one thing left. Availability :) There are three aspects of security:
Confidentiality (Noone can read what they don't have access to)
Integrity (Noone can change any data what they should have to and you have to be able to detect if it happened even so)
Availability (The data, application whatever has to be available)
You pretty much did a nice job and took care of the first two (credentials, prepared statements, htmlentities...) but none of them will help against a DoS attack. You should be able to detect if someone slaps your site and ban the attackers ip from your server. Although this can be done in PHP (still much better to kick the attacker at the first line of php than let them initialize the framework, database connections etv.) it can be done mre effectively in lower layers (for example: nginx/apache, iptables, snort).
However what you're asking for that usually comes to the matter of risk management. In a real application you're not able to be prepared for all the possible attacks, edge cases etc. What you need to do is classify all the risks by the probability and the impact ( http://www.jiscinfonet.ac.uk/InfoKits/infokit-related-files/Resources/Images/risk-matrix ). With this you can focus on the most important (highest) risks first and probably you can completely ignore the lower bottom part.
SQL Injection and XSS are the most prominent Hacking methods.
You are covered from SQL Injections if you use prepared statements.
Also, if htmlentities() on everywhere you display HTML you should be safe.

Javascript to PHP Security

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.

Guide to Securing JQuery AJAX Code?

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.

What is the best and most secure way to encrypt Ajax data?

I'm developing a website where people will be able to register and access different data via Ajax (powered by jQuery). This is all simple and i shall have no problems doing. the issue is that the data showed by Ajax needs to be secure and not available to be parsed through remote scripts. I can encrypted the data through a AES (in PHP) and decrypt successfully in javascript, but the javascript code will always be visible to everyone (after login). I can use an obfuscator and javascript encryption, but both ways, even mixed, are not secure enough and decryptable. I would prefer avoiding SSL connections, since I am trying to prevent registered users from accessing the information and the SSL connection would only prevent unregistered users from accessing the data.
Registered users will be able to earn money therefore very interested in cheating the code, this is why it has to be bulletproof.
Unfortunately the system needs definitely Ajax (the whole working principle needs to be based on Ajax). The ideal solution would be a way to save the encryption key on a place that can be saved by php and accessed by javascript, but not by users, remote script parsers etc.
Does anyone know a way to create a secure Ajax connection for this purpose?
I really appreciate all your help.
You want something that browsers do not do.
You've asked for: "The ideal solution would be a way to save the encryption key on a place that can be saved by php and accessed by javascript, but not by users, remote script parsers etc."
The design of the web browser and javascript engine in the browser is such that any Javascript that the web browser can execute can be seen by a human who wants to look at it, steal it, borrow it, whatever. Period. There is NO such place that can be accessed by Javascript, but not by users or remote script parsers. You will have to rethink how your app works if this is a problem. Most likely, you need to keep the secret stuff on the server and do more work on the server and less work on the client in order to protect what you want to protect. If you think about it, a browser is just a remote script parser so if you prevent remote script parsing, you prevent a browser. If you allow a browser, you allow a remote script parser.
You can obfuscate your Javascript to your heart's content if you want. That will make it a little more work for a human to understand and do something useful with it, but it will only be an additional obstacle that any determined and competent person can defeat if they really want to. If this secrecy is really important to you, then you need to rethink the design of the app so that secret information is not required in the browser and the browser just works as a display and interaction engine.
Just so I'm clear here. Any code that can be executed by a browser must, by definition, be something that any user or any tool can download and inspect. You can use SSL to protect data from snoopers in transport, but it ultimately has to be readable as Javascript for the browser to be able to execute it.
You can't do exactly what you want. It's like a cheat-proof game design. You CAN make it HARDER, even MORE hard, but NOT 100% secure. You've got to solve the problem froma different approach, like, whatever that is, examine the actions at server-side (e.g. in a stateful manner) and try to detect any non-human behavior. But it's only a matter of someone creating a realistic bot that mimicks the behavior of humans. Encryption is used for preventing 3rd parties -- other than the server and the client -- from eavesdropping/capturing data, NOT for the client. I'm not saying give up on the whole thing, but try a different approach to secure the system. I want to help more, but don't know what exactly you are trying to achieve.
authentication is the only ways to do it.
Just get your users to authenticate (login) and send them the random seed and salt you've used to encrypt their data.
Without the seed/salt, even though a malicious user can decrypt your data it will still be garbage.
If you want javascript to use a piece of data then clients use that data.
If you don't want data to be re-used set up a server-side system where each chunk of data is only valid once.
Proper authentication should solve all these problems.
I want the users to be able to see the data only when Ajax displays them
Then load the data when ajax get's it and not before. Or only partially load data and off-load any sensitive work to the server.
i think the best practice is to make your code (production code) too mush complex to read and edit
you should rename all your variable with letters [a-z] you should not declare ny function always use function(){} inside of another to make it more logical complex this way
the client can still see the code but has nothing to do with it
EDIT: I realize now it's a terrible advice

What security issues should I look out for in PHP

I just starting out learning PHP, I've been developing web apps in ASP.Net for a long time. I was wondering if there are any PHP specific security mistakes that I should be looking out for.
So, my question is what are the top security tips that every PHP developer should know?
Please keep it to one tip per answer so people can vote up/down effectively.
(In no particular order)
Always check that register globals are OFF
Always check that magic quotes are OFF
Make sure you understand SQL injection attacks
Turn OFF error reporting in production
EDIT: For the "newbies" out there this is a basic why (and since I have time to explain this):
Register globals is an aberration. It's the ultimate security hole ever. For example, if register_globals is on, the url http://www.yourdomain.com/foo.php?isAdmin=1 will declare $isAdmin as a global variable with no code required. I don't know why this "feature" has made it's way to PHP, but the people behind this should have the following tattooed on their forehead: "I invented PHP Register Globals" so we can flee them like pest when we see them!
Magic quotes is another dumb idea that has made it's way to PHP. Basically, when ON PHP will escape quotes automatically (' become \' and " become \") to help with SQL injection attacks. The concept is not bad (help avoid injection attacks), but escaping all GET, POST and COOKIE values make your code so much complex (for example, have to unescape everytime when displaying and data). Plus if one day you switch this setting OFF without doing any change to your code, all your code and/or data is broken and (even more) vulnerable to injection attacks (yes even when ON you are vulnerable).
Your databse data is your most valuable thing on your site. You don't want people to mess with it, so protect yourself and read things about it and code with this in mind.
Again this can lead to security concerns. The error message can give hints to hackes on how your code works. Also these messages don't mean anything to your visitors, so why show them?
Avoid using register_globals.
Warning: This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
Cross Site Scripting (XSS) Wiki, Google
Cross Site Request Forgery (XSRF/CSRF) Wiki, Google (thanks Rook)
Session Fixation Wiki, Google
SQL Injection (SQLi) Wiki, Google
Turn off error messages in Production environments
Keep any "include" code in a directory that is not web-accessible (either deny access or keep it outside of the webroot)
Here's an article I wrote about storing passwords in a secure way, and if you don't feel like taking my word for it, check the links at the bottom.
Also linked in my article, but given its own separate link here, is a paper published by M.I.T. called The DOs and DON'Ts of Client Authentication on the Web [PDF]. While some of its info (recommendation to use MD5 hash, for one) is somewhat out of date simply because of what-we-know-now versus what-we-knew-then, the overall principles are very strong and should be considered.
One of Rooks' links reminded me of another important set of restrictions
Turn off Register Globals (This is the default now, so I hadn't mentioned it before)
When dealing with file uploads, be sure to use is_uploaded_file() to validate that a file was uploaded and move_uploaded_file() instead of copy() or rename().
Read this section of the PHP Manual if you need to know why (and you do).
Since I've now mentioned him twice, check out Rooks's Answer (https://stackoverflow.com/questions/2275771/what-are-the-most-important-safety-precautions-that-a-php-developer-needs-to-know#2275788) as it includes a link to a document which contains (Non-PHP-Specific) information on the most important security concerns (and this therefore probably the right answer).
here is a link of good PHP security programming practices.
http://phpsec.org/
Most of the security issues revolve around user input (naturally) and making sure they don't screw you over. Always make sure you validate your input.
http://htmlfixit.com/cgi-tutes/tutorial_PHP_Security_Issues.php
Always sanitize and validate data passed from the page
In conjunction with #1, always properly escape your output
Always turn display_errors off in production
If using a DB backend use a driver that supports/emulates prepared statements and use without prejudice :-)
don't use "Register Global Variables" and filter user input for xss and injections
Language Vs Programmer. You can write the most serious vulnerability and you won't get a warning or error message. Vulnerabilities can be as simple as adding or removing 2 characters in your code. There are hundreds of different types of vulnerabilities that affect PHP applications. Most people think of XSS and Sql Injection because they are the most popular.
Read the OWASP top 10.
If you're using a mysql database make sure you call mysql_real_escape_string when sending data to the database
There are tons of safety precautions. I can recommend a book Chris Shiflett: PHP and Web Application Security.
http://phpsecurity.org/
Have a look at the Suhosin Hardening Patch, and check out the security vulnerabilities that it addresses.
The PHPSec Guide gives a good overview.
Most of the security issues related to PHP come from using unparsed "outside" (GET/POST/COOKIE) variables. People put that kind of data directly into file paths or sql queries, resulting in file leakage or sql injections.
OWASP provides a lot of insight into security issues that are the biggest problems in applications today. It is nice to see that they have a PHP dedicated page available
http://www.owasp.org/index.php/PHP_Top_5
Always Close you SQL Connection.
Always Release SQL results.
Always Scrub all variables your putting into a database.
When deleteing or dropping from sql use limit 1 just in case.
When developing make sure you have a lock on things to keep the undesirable out. If its open and you know not to load the page right now because it could break something, doesn't mean other people do.
Never use Admin or Root as your server log in name.
Whenever possible, use prepared statements (tutorial. It's almost a must whenever dealing with user input (I say "almost" because there are a few use cases where they don't work), and even when not dealing with input, they keep you in the habit. Not to mention they can lead to better performance, and are a LOT easier, once you get into the swing of things, than piecemeal sanitizing.
Often introductory tutorials don't talk at all about checking data from users. Like all programming environments, never trust the data you get from users. Learn to use functions like is_numeric(), isset(), and mysql_real_escape_string() to protect your system.
There are also features that allow you to access remote files, and other creative things. I'd avoid those until you have a good understand of how and when they work (often they are disabled for security reasons).
Use POST method for data passing from one page to another.
Use trim while getting data like trim($_POST).
Also, use strip_tags for variables before you passing into the queries.
I am suggesting you use any framework link Codeigniter, Laravel, YII, Cake PHP because they maid framework with all securities
I suggest Codeigniter for small projects and Laravel for big projects.
Always use POST and not GET for important Data...

Categories