Concerning security; Should I check every page for how many variables are sent, the size of variables that has been sent and block GET if it is not needed in the page for example.
I mean maybe someone send very very large text for many many times as GET variables to overload my server.
Is it possible? what can I do about it?
Using GET request you can't send huge amount of data (Apache has a default of 8000 characters, check browser limitations here). And if you don't use anywhere $_GET parameters, than it will be mostly no impact for server. What matters here is requests per second. Normal user will not generate lots of request.
If you are looking for security holes, start from Uploaded files execution restrictions (like PHP code in image.jpg) and other insecure access to files, XSS attacks, weak passwords generation and so on.
There was a big problem with how POST/GET values were handled in most languages, including PHP that could result in DOS attacks via specifically crafted requests. It was first discussed in this talk (slides are available here).
You can also read about it here and here. The main idea was that POST/GET are arrays, and that arrays are stored using hashtables. An attacker could create a DOS by purposefully creating collisions (data has same hash value), which results in a lot of computations.
But this isn't something that should be handled at application level, so you as a PHP coder do not have to worry about it. The problem described above is an issue of how PHP handles hashtables, but you can also prevent it by limiting the size of POST/GET requests in your PHP configuration.
If you are worried about DDoS, this also would not have to be handled by your application code, but externally, eg by a firewall.
My answer somewhat links your question to your comment:
No, I'm worried about hackers
Security wise I think the first thing you should check and optimize is the site structure. The problem you mentioned is very specific and to a certain degree may help, however probably won't be their primary attack.
You could always limit the GET requests (by default is somewhere around 8KB for most servers) somewhere in the server configs. You may also create a custom 414 explaining the reason for the shorter request length.
All in all, if it's security that you're aiming for, I'd start off elsewhere (the broader picture) and then slowly tackle my way until I hit the core.
Related
I've developed a site with basic search function. The site accepts input in GET params and the site is hosted on a shared hosting server. Thus there are limits on SQL execution.
My goal is to stop [or at least lower the chance] of processing automated search query so the site does not reach the SQL limit for bogus search queries where there is no real user.To prevent this I've used CSRF in the landing page from where search is initiated.
What else can I try to make sure that the search is performed only for real users and not for automated/bot search. I've thought of CAPTCHAs but asking to confirm CAPTCHA for every search query will make it really worse.
Welcome to the eternal dichotomy between useability and security. ;)
Many of the measures that are used to detect and block bots, also impact usability (such as the extra steps required by opaque captchas). None of which solve the bot problem 100% either (ala captcha farms).
The trick is to use a reasonable mix of controls, and to try hard not to impact the user experience as much as possible.
A good combination that I have used with success to protect high-cost functions on high-volume sites is:
CSRF: this is a good basic measure in itself to stop blind script
submission, but won't slow down or stop a sophisticated attacker at
all;
response caching: search engines tend to get used for the same thing
repeatedly, so by caching the answers to common searches, you avoid
making the SQL request altogether (which avoids the resource
consumption, and also improves regular usage too);
source throttling: track the source IP and restrict the number of
operations within a reasonable window (not rejecting any outside
this, just queueing them and so throttling the volume to a reasonable
level); and
transparent captcha: something like Google's CAPTCHAv3 in
transparent mode will help you drop a lot of the automated requests,
without impacting the user experience.
You could also look at developing your search function to search an XML file instead of via the database. This would enable you to search as many times as you like without any issues.
As most programmers I try to program my applications in the safest way possible but this we know that does not guarantee security at 100%. Therefore I think it is also appropriate to have methods to monitor if we may be being attacked. So this is my question.
(My websites are made with PHP and MySQL)
In the case of SQL injection I think this can be done in two ways, but if there are other ways I would also like to know them.
Parsing access/error logs. Does anyone have or know a script that adequately analyzes the access logs (apache) to detect possible attacks? And notify to the administrator automatically with all details.
Analyze HTTP params at real time. It would be a script that analyzes in real time the content passed by GET / POSt and notify (e.g. via email) to the administrator of the website
For example, I do not know much about SQLi attacks but I think it's common for the 'SELECT', 'UINON',...(Others?) strings to appear in query strings and params.
In this way we can analyze the attack and see if it succeeds or not, and then take the consequent actions.
Thanks for your attention!
Edited: Simple bash script
I have made a simple system for analyzing the Apache access_log files and communicate results by email. Which is detailed in this question:
Linux bash to iterate over apache access_log files and send mail
In addition, another one using AWK. The only one resource I've found related about that:
https://www.unix.com/shell-programming-and-scripting/248420-sql-injection-detection.html
(But I have not been able to make it runs in my case)
Oh boy.
Alright, where to start?
For starters, remember that bad hackers are usually financially motivated. You know your website has been injected if you wake up one morning to a red error message from Chrome or Firefox, and you open it anyway to find that your website is now among the more popular places to find free cruises and viagra online.
Sites that score well with SEO are more likely to be hacked than sites that do not. More users means more exposure. Password protected sites don't get hacked as often, but the password protection itself does not necessarily mean any added security. If you're vulnerable, you're vulnerable, and you need to be on top of it.
First and foremost, remember to filter your variables. Never trust anything that comes in from a browser. IT'S ALL SUSPECT. That's means filtering anything that counts as a super global, GET POST, REQUEST, etc. I wouldn't even trust sessions, honestly. Filter it all. More on this can be found here: http://php.net/manual/en/function.filter-var.php
Something else to think about is file uploading. Bad guys love uploading files, and taking over your server. Most common method is exploit files disguised as images. You're going to want to resample every image that comes in. GD Works, but I like Imagick better, personally, more options. More on that here: http://php.net/manual/en/book.imagick.php You're also going to want to make sure that your site can't upload images or any other type of file from pages that you don't explicitly designate as form or upload pages. You would be shocked how often I see sites that can upload from the index, it's insane.
Another method you can deploy for this, is use your php ini to set a global include, and open up any file in a $_FILES array that comes in. Open up the first million spaces in the file, and scan it for php reserved words, and unix shell scripting. If you find one, kill the upload, exit or die, whatever you like to do there.
Apache has a setting for forensic logs. Forensic logs will capture all GET and POST stuff, but the issue with it, and the reason it's not exposed by default is that your log get big, and quickly. You can read up on it here: https://httpd.apache.org/docs/2.4/mod/mod_log_forensic.html
Lastly, you're going to want to evaluate your site for injection vulnerabilities and cross site scripting. Cross site scripting isn't the issue it once was, given the way browsers are constructed these days. All those little details that make life harder for us as a developers actually make us more secure.
But you do want to check for SQL vulnerabilities, especially if you're writing code from scratch. There are a couple reasonably solid plugins for Chrome that make pen testing a little easier.
Hackbar: https://chrome.google.com/webstore/detail/hackbar/ejljggkpbkchhfcplgpaegmbfhenekdc?utm_source=chrome-ntp-icon
HackTab:
https://chrome.google.com/webstore/detail/hack-tab-web-security-tes/nipgnhajbnocidffkedmkbclbihbalag?utm_source=chrome-ntp-icon
For Firefox, there's scrippy
https://addons.mozilla.org/en-US/firefox/addon/scrippy/?src=search
Hope that helps.
Good luck.
Therefore I think it is also appropriate to have methods to monitor if we may be being attacked.
The biggest waste of time ever.
ANY site gets "attacked" 100% of time. There are freely avalable scripts that allow any stupid schoolboy to scan whole internet, probing sites just by chance. You'll grow bored the very next day after scouring these logs of your detection system.
In your place I would invest in the protection. Other vectors than you could think of. For examle, all recent breakings I was a vitness of were performed by means of stealing ftp passwords stored on the webmaster's PC. And I can assure you that there are much more attack vectors than a blunt SQL injection. Which is a simplest thing to protect from, with only two simple rules to follow:
Any variable data literal (i.e. a string or a number) should be substituted with a parameter, whereas actual value should be sent to the query separately, through bind/execute process.
All other query parts that happen to be added through a variable, should be explicitly filtered through a hardcoded list of allowed values.
Well, I have a completely AJAX driven site. I inserted a jQuery code that affects all forms and queries site-wide. It's to the point, even though I want to change it, I fathom and accept the idea of a website that utitlizes a single function to process all queries (search, links, & profile, etc....)
How do you accomodate speed and security to such a platform? My php files can be accessed directly from their location's link. That is a threat. Help me; as well as AJAX, I need validation and '777' protection.
Before you read my answer read also this (as answer to a comment on your question) : Possible to view PHP code of a website?
Don't put speed and security in the same box. A website can be secure and fast at the same time.
I would secure a folder with 777 access (why not 755?) with an empty 0Kb index.html file (yes, even if you have inside a bunch of .php files!) ad put an .htaccess with restrictions deny from all that allows a folder to be accessed internally but not from 'outside'.
Than I would NEVER send sensitive data through the requests, but rather a client-side transformed Hashing algorithm like MD5 or SHA1 to compare data and validate on server-side. So don't ever ever send sensitive data in it's pure state over the yellow wire.
Need more security? https
Regarding a "single function" that drives your JS client-end of the site, well, if well formatted the browser doesn't care if it's one or hundreds, a good code is a readable code. Performance wise there's lots of suggestions on the www how to speed up your code.
To add to a really good #Tim's comment/tip, you can still open your console in Firebug (Net) and inspect every single piece of information that is sent from your Page to the server (and vice-versa!!) and act accordingly.
I recently heard that a website can be DDoS'ed through the those doing the attack submitting forms with i.e 2MB data (in characters), lot's of times very rapidly. Is this statement true? If so, is there anything I can do in PHP to prevent this, i.e set the form data limit down?
DDoS'ing by submitting large amounts of data would require some vulnerability in data processing, otherwise it is not really plausible since the attackers upload speed becomes a bigger factor. It would be much easier to attack with using slowloris or ping floods.
Using data an outdated server can be DDoS'ed by using variable parsing problem aka the Hash Collision attack (not only PHP). It is discussed on the 28th Chaos Communication Congress which can be watched here.
There may be more than 1 thing that was going on in the background that would have led to this DoS. I am assuming the OP is using DDoS instead of just DoS. Anyway, the reasons why this could have happened are because, the code spent too much time on a single request, too much logging(ie the server writes to the log every-time it gets a bad request) or a plain old bottleneck on the server side. And I believe 2 MB is a moderate size for a POST request. If going below that doesn't affect your functionality, go ahead and reduce it.
See my question here, which is along the same lines : https://serverfault.com/questions/413718/tomcat-denial-of-service-due-to-large-packets
I currently have a custom session handler class which simply builds on php's session functionality (and ties in some mySQL tables).
I have a wide variety of session variables that best suits my application (primarily kept on the server side). Although I am also using jQuery to improve the usability of the front-end, and I was wondering if feeding some of the session variables (some basics and some browse preference id's) to a JS object would be a bad way to go.
Currently if I need to access any of this information at the front-end I do a ajax request to a php page specifically written to provide the appropriate response, although I am unsure if this is the best practice (actually I'm pretty sure this just creates a excess number of Ajax requests).
Has anyone got any comments on this? Would this be the best way to have this sort of information available to the client side?
I really guess it depends on many factors. I'm always having "premature optimization ..." in the back of my head.
In earlier years I rushed every little idea that came to my mind into the app. That often lead to "i made it cool but I didn't took time to fully grasp the problem I'm trying to solve; was there a problem anyway?"
Nowadays I use the obvious approach (like yours) which is fast (without scarifying performance completely on the first try) and then analyze if I'm getting into problems or not.
In other words:
How often do you need to access this information from different kind of loaded pages (because if you load the information once without the user reloading there's probably not much point in re-fetching it anyway) multiplied by number of concurrent clients?
If you write the information into a client side cookie for fast JS access, can harm be done to your application if abused (modified without application consent)? Replace "JS" and "cookie" without any kind of offline storage like WHATWG proposes it, if #1 applies.
The "fast" approach suits me, because often there's not the big investment into prior-development research. If you've done that carefully ... but then you would probably know that answer already ;)
As 3. you could always push the HTML to your client already including the data you need in JS, maybe that can work in your case. Will be interesting to see what other suggestions will come!
As I side note: I've had PHP sessions stored in DB too, until I moved them over to memcached (alert: it's a cache and not a persistent store so may be not a good idea for you case, I can live with it, I just make sure it's always running) to realize a average drop of 20% of database queries and and through this a 90% drop of write queries. And I wasn't even using any fancy Ajax yet, just the number of concurrent users.
I would say that's definately an overkill of AJAX, are these sessions private or important not to show to a visitor? Just to throw it out there; a cookie is the easiest when it comes to both, to have the data in a javascript object makes it just as easily readable to a visitor, and when it comes down to cookies being enabled or not, without cookies you wouldn't have sessions anyway.
http://www.quirksmode.org/js/cookies.html is a good source about cookie handling in JS and includes two functions for reading and writing cookies.