Tackle SQL injection [closed] - php

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I was wondering if there is a standard way to tackle SQL injection. I'm asking because I started working at a company and they want me to make the website sql injection safe. Is there way to e.g scan the whole website or procedure to tackling SQL injection in a software that already exists?

I wrote about SQL injection defenses extensively in a presentation SQL Injection Myths and Fallacies (or listen to me present it in a free webinar at Percona.com).
There's basically no silver bullet, but there are several standard methods of defense.
Penetration Testing
There are a variety of free intrusion detection tools available, such as WebScarab or w3af. These can be a good first step as a black-box testing technique for finding the first layer of vulnerabilities in your website.
Another good article on the subject is Web Application Security: Testing for Vulnerabilities from IBM DeveloperWorks.
Code Analysis
Can we scan the code of a whole website to detect SQL injection vulnerabilities? Yes, there are many code analysis tools available. Which one is best for you depends on the code language you use, and your development environment.
NIST has a pretty huge list of Source Code Security Analyzers.
But even if you use intrusion detection and code analysis tools, remember the old wisdom about testing: Testing shows the presence, not the absence of bugs. That is, any testing is bound to be incomplete, so don't rely only on automated testing.
Code Fixes
Once you find a vulnerability, fix it. There are several coding techniques that help:
Escaping or filtering application variables before copying them into SQL code.
Preparing SQL queries with parameters in place of dynamic values.
Whitelisting content that can't be escaped or parameterized (like valid table names or column names).
These defenses are each very useful, but none work in every situation, so you must learn how to use each of them.
There's no substitute for careful code reviews. Basically, for any SQL query that uses dynamic content for part of the query (i.e. copying application variables or any external input into the SQL string), you must make sure that the content has been made "safe" by one of the defense methods I listed above.
Perl has a feature that supports this, for example. Every Perl variable has a meta-attribute of being "tainted" or not, and therefore unsafe to be copied verbatim into SQL (or executed as code with eval or even output to HTML, risking XSS issues). A variable is tainted if it takes any of its value from external, untrusted content. Or if the variable takes its value from another tainted variable (it's infectious). You can "untaint" a variable by filtering it through a regular expression matching function (this assumes you are responsible for making a sensible regular expression that strips off dangerous content).
Other languages don't have this tainted-variable concept, but you can do something similar by manual analysis, tracing the source of every variable that is copied into SQL strings.
Monitoring
Assuring 100% security all the time is incredibly hard. Even if you correct 99.9% of your app's inept handling of SQL, the last case could be the opening a hacker needs. And of course one of your inept developers might introduce another vulnerability tomorrow.
Any security plan has to include constant monitoring for suspicious website behavior. Many of the worst SQL injection disasters were so bad because they went undetected for months while the attackers siphoned away valuable data.
So you have to keep logs of SQL queries, and watch for patterns of invalid queries. For example, keep a whitelist of known SQL query types that your application code runs. If any SQL queries appear in the log but don't match the whitelist, it might be an illicit query run by an attacker. For more on this idea, see Using the Percona Toolkit to Detect and Even Prevent SQL Injection Attacks.
There are also SQL injection proxy products like GreenSQL that can help to monitor or whitelist SQL traffic transparently.

Related

Understanding the basics on PHP and MySQL security [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have always avoided learning PHP and MySQL because of what I have read on the internet about PHP not being a secure language and because of the security risks with databases (SQL injections etc).
The main thing I want to understand is the type of damage usually caused by poor PHP/MySQL code. In other words, what are we putting in risk when poor code is written, the information in the database or the entire server?
I know this may be a complex topic but I just want a brief explanation of what information is usually affected when a database or a PHP script is compromised.
When a database is compromised, does this mean that the entire server could be at risk or just the database and its content?
When a PHP script is compromised, does this mean that the entire server could be at risk or just the script and any content related?
What is the most important thing to keep secured when creating a database, the connection to the database?
Sorry for such basic questions but I need to understand this before I move on.
On SQL injection... when data is concatenated directly into a command, there is the potential for the data to be confused as the command. This is true with just about anything, but we see it a lot in the form of SQL injection attacks on web applications. For instance:
$evil_user_input = '0; DELETE FROM someTable WHERE 1=1';
mysql_query('SELECT * FROM someOtherTable WHERE fieldA = ' . $evil_user_input);
In practice, you can only run one query at a time so you have to get crafty, but the point here is that without escaping for the use in SQL, what should be data can be ambiguous. This goes beyond security. Suppose you have a field where a user types a quote mark. Now you have broken SQL and your code crashes.
1- When a database is compromised, does this mean that the entire server could be at risk or just the database and its content?
2- When a PHP script is compromised, does this mean that the entire server could be at risk or just the the script and any content related?
Now when a database is compromised, or when your script is compromised, it is impossible to generalize as to what the issue is. It all depends on what the attack was. You can't say for sure that anything is ever truly isolated as many attacks rely on many pieces. When something happens, you need to use your logs and other evidence to figure out what happened, and then fix it.
3- What is the most important thing to keep secured when creating a database, the connection to the database?
Use prepared/parameterized statements correctly and you don't have to worry about SQL injection attacks. The connection to the database server itself should be over secure tunnels. Most database wire protocols are not secure themselves... they are built for speed. If you're accessing data over localhost, there is no tunneling needed.

making php web application secure

to protect my project from attacks (example: SQL injection) im using the below for query
parameter pages(*.php?query=value) :
$id=strip_tags($id);
$id=mysql_real_escape_string($id);
if(is_numeric($id) && strlen($id)<=3) //id are numbers maximum of 3 digits
Apart from this im using client(JavaScript) & server side(php) validations, strip_tags() to filter data as required.
Passwords are encrypted using bcrypt()
All messages are encrypted using mcrypt_ecb()
Pages can only be accessed when isset($_SESSION["id"]) ie logged in.
error_reporting(0);to hide errors.
$_POST instead of $_REQUEST
mysql_real_escape_string(); for every input
actually my project will be used by college and im tensed about the security because backtrack makes it easy to penetrate, so im trying hard to make it safe. (i know it's a vast question, but any kind of help will be very useful) but as a student i want to know what else im missing to make it safe ?
Firstly:
Avoid PHP's MySQL functions like a plague
Use PHP's MySQLi functions instead at the very, very minimum or PDO instead. MySQLi and especially PDO functions, are better security-wise. But, of the two, PDOs are the best deal as they offer you higher abstraction with prepared statements which greatly increases your defense against SQL injection attacks:
Most SQL statements in PHP applications use variable input to
determine the results of the SQL statement. To pass user-supplied
input to an SQL statement safely, prepare a statement using parameter
markers (?) or named variables representing the variable input. When
you execute the prepared statement, you bind input values to the
parameter markers. The database engine ensures that each input value
is treated as a single parameter, preventing SQL injection attacks
against your application. Compared to statements issued through
PDO::exec(), prepared statements offer a performance advantage because
the database management system creates an access plan for each
prepared statement that it can reuse if the statement is reissued
subsequently.
Also, avoid using some of the older depreciated PHP functions.
Next, generally, if you're using PHP or any language that creates dynamic requests, that implies user input on some level, and most oftentimes, a subsequent interaction with the database. Rule 1 of web programming: never, ever under under any circumstances trust user input. At all. Everything entered must be cleaned, validated to avoid security problems. You can do this natively with PHP, but honestly it takes a lot of work and a lot of attention to detail - which of course, expands your development time.
If this is not an academic exercise or one dealing with self-training - try to use a framework if you can - it potentially can save you many headaches later down the road as good frameworks can take care of some of the overhead of dealing with escapes, validation and the like. What that means is that if you go commando and write your own code with no framework: most, if not all of the functionality you'll be implementing would be done for you and chances are - done better in a framework.
Plus, they make PHP development easier, and occasionally, fun. Of course, not all frameworks are created equal, and all frameworks have security issues, too. But, this is something you will have to keep in mind and keep yourself informed at all times, religiously.
If this is an academic exercise, or a self-learning one, read this:
Reasons to NOT use a PHP Framework?
A lot of the top StackOverflow PHP posts and Programmers.StackExchange posts can help you with your journey.
Here's a few to start with:
(This one's more of an overview of what most of these links discuss)
http://www.acunetix.com/websitesecurity/php-security-1/
PHP Session Security
Exploitable PHP functions
What's the best method for sanitizing user input with PHP?
https://stackoverflow.com/questions/325862/what-are-the-most-common-security-mistakes-programmers-make
What common web exploits should I know about?
Read up on security practices in your field. It's ever evolving.
If you're interested in frameworks, here are a few of the popular ones to pique your interest:
Yii
CakePHP
Zend
Symfony
Kohana (highly recommended)
But, either way - good luck!
I'd propose the review OWASP's website for web security related information (or even join OWASP).
This OWASP section provides PHP-related information.
Making a PHP application secure is a pretty complex process. There are lot of thing to think about when you write your application and SQL injection is not the only one threat.
I suggest to refer to the following useful articles:
25 PHP Security Best Practices For Sys Admins
How to secure your php application?
PHP Security Cheat Sheet

SQL Injection conundrum

As we know as usual sites use functions like mysqli_query() and mysql's PHP driver does NOT allow multiple queries in a single->query() call (But you can do as many in phpmyadmin SQL running section) so we cannot directly add DELETE/UPDATE/INSERT but abusing of possibilities to modify data under some circumstances. The 1st thing is that in that case I think 80% of potentially being at risk (maybe lost of data) is gone! & the 2nd one is, rely on this knowledge, why most of injecting tutorials are based and focused on multiple queries?
80% of potentially being at risk (maybe lost of data) is gone!
This assumption is wrong.
why most of injecting tutorials are based on multiple queries?
Because it's just a simple understandable example, a proof of concept. Just like one "If John have 2 apples and Mike five...". If real Mike doesn't feel like to spare his apples, it doesn't mean that arithmetics is all wrong.
SQL Injection Concudrum
There are NO conundrum in injections.
There is no point in musings on injections.
There is no percents of risk to be calculated but just a dichotomy: either you have your application compromised or not.
There is just one simple rule - always format your data properly, and you will forget of injections forever.
PHP for a long while has disallowed multiple queries running for a single query() statement. This is just part of preventing sql injection. You must also escape your inputs, use prepared statements, make your table names and columns hard to guess and such.
The simplest example of an sql injection attack does involve a query that's tricked into executing more than one query, but obviously php prevents a lot of such attacks by the limitation already mentioned. However, things like subqueries are still possible, so it's not fool proof. I don't think it's possible to make sql injections altogether impossible as people keep finding new ways to trick scripts.
The best you can do is know how such attacks are done and write your code according to currently accepted best practices to prevent such attacks. If you've done all this and still get hacked, then probably (but not certainly) it wasn't your sql that was the weakest link in your security. From what I understand, more often hackers succeed using social engineering techniques.
Making an un-hackable system is nigh impossible, so the best you can do is make it difficult to hack and thus, not be the 'low hanging fruit' or, in other words, don't be an easy target.

Detecting potential SQL injection attacks, as well as other security issues

We all know it is nearly impossible to produce a large website without one or two flaws. As such I've written a small monitor that checks Apache access logs for potential SQL injection attacks (amongst other things), and it's working very well. I get an alert whenever someone attempts an attack, and I've had so few false positives that the default action is now to dump them into an iptables drop list. It's even helped me identify a few (non-security) bugs and remove them.
Here's my rules (case insensitive):
PathInjection = \./\.\./(bin|boot|data|dev|etc|home|lib|lib64|media|mnt|opt|proc|root|sbin|selinux|srv|sys|tmp|usr|var)/
Havij = 0x31303235343830303536
r3dm0v3 = 0x7233646D3076335F68766A5F696E6A656374696F6E
LogicBypass = '.*?(\bor|\band|\bxor|\|\||\&\&).*?--
UnionSelect = union[^a-z-_]+((all|distinct)[^a-z-_]+)?select[^a-z-_]
What I'd like to know is, how would you bypass these checks and still produce a valid injection? Can you think of a way to improve them without introducing false positives?
A few notes:
Case sensitivity is switched off.
I'm using MySQL.
The Havij and r3dm0v3 entries are used as a catch-all to prevent use of those automation tools.
I'm checking both raw and urldecoded strings.
I'm not looking for answers like "make more secure code instead".
I'm not looking for a different way to do this, just a way to improve my current logic.
EDIT:
Ok, so people seem to have misunderstood my intent. That's probably my fault, since I didn't fully explain. This is being requested as a tacked-on feature to a monitoring product, and is designed to offer minimal security monitoring. As part of our dialog with the client and our documentation, we're emphasising that this is not a catch-all, nor is it a replacement for proper security infrastructure (e.g. an IDS and firewall). It's simply an informational service to help provide basic threat detection and produce statistics about the number of potential attacks. I'm not trying to write an IDS or firewall. If it were up to me, I'd leave the feature out and tell them to go install a full suite of security infrastructure with its own monitoring systems, but this isn't my call. The current situation is that I've been testing the system on my own site. Right now, I'm just looking for a way to improve the regex strings to make this more effective. Hopefully this clears things up a little.
Edit again, in June 2021.
I posted this question back in 2011. Back when I wrote it I was a junior developer with an interest in security but lacking experience. Since then I've switched careers to security, worked as a pentester for 5 years, and a security researcher for another two. I'm also one of the top reputation users on Security StackExchange.
The answers given here are mostly correct - there's far more value in deploying something like ModSecurity with appropriate rules, since they've already done the work. A tacked on homebrew solution is not going to compare to a project with almost two decades of maturity.
The one major caveat, though, is that I was not making the decisions. Junior developers usually have neither the privilege nor latitude to veto product decisions made by management, especially those made at the request of a customer. One can certainly explain why an idea is bad, and provide supporting material, but that often doesn't translate into changed decisions. Being able to refuse a task from your employer without consequence is an unusual privilege - the concept is a complete fantasy in the context of most employment.
My advice for folks who respond to these types of question is this: explain why it is ill-advised, but be sympathetic and helpful to those who are in a difficult position. Actually answer the question, wherever possible, so that a best-effort solution can be implemented if all else fails. In the context of security features, it's also worth considering that if the alternative is no protection or detection at all - even if that alternative is artificially being imposed by external actors - a weak capability is almost always better than no capability at all.
I don't remember what I ended up implementing for this. It was so long ago. But if you're here now, looking for answers, I recommend using ModSecurity. They now have connectors for Apache, nginx, and IIS, so you can install it on any of those web servers. If changing the server configuration is problematic, you could instead run nginx as a reverse proxy with ModSecurity enabled, so that users hit the nginx server and it proxies the requests to your actual web server. This can also be done with Apache instead.
If you're looking for a more programmatic approach, ModSecurity has language bindings for C, C++, and Python. The ModSecurity API can also be consumed via any language that has interoperability support for C APIs (e.g. P/Invoke in .NET, or JNI in Java).
ModSecurity works on rules. One of the best free rule sets out there is OWASP Core Rule Set (CRS). The rules are significantly more powerful than simple regex patterns. This makes them very effective, but it also means that you probably shouldn't try to build your own ModSecurity-like internal feature that consumes the rules, because you'd need to put in a ton of work to support all the necessary features.
If you need to parse ModSecurity logs into a format that can be automated upon, take a look at ModSecurity Log Utilities.
Hopefull this info is of use to someone in future.
You're talking about writing an IDS. Unless your product is an IDS, just get and install one. Snort is well-known and has a free version.
I'm not looking for a different way to do this, just a way to improve my current logic.
Sometimes when it comes to security, the wrong approach simply is. How would I mess with your current logic? Unicode or hex encoding.
Here is a nice example of IT threat detection using deep-neural-network vector embedding and a similarity search engine.
Can you think of a way to improve them without introducing false positives?
I wouldn't think of improving this silly approach at all. I'd rather improve the site security itself.
We all know it is nearly impossible to produce a large website without one or two flaws.
I disagree with that. At least for SQL injections. Injections are quite silly thing and protection is not a big deal.
sql injection is top rated web Application attack these days. There are many insecure code over the net and also there are several ways to protect application from sql injection attacks. sql injection can occur when an application uses input to construct dynamic sql statements or when it uses stored procedures to connect to the database. Methods of sql injection exploitation are classified according to the DBMS type and exploitation conditions Vulnerable request can implement Insert, update, delete. It is possible to inject sql code into any part of sql request Blind sql injection Features of sql implementations used in various dbms. Successful sql injection attacks enable attackers to execute commands in an application's database and also take over the server.
my recommendation:
Basically, make sure your web server is up-to-date with latest security fixes/patches.
Make sure you have filter every user input and output as proper encoding like UTF-8.
Read the full testing guide: https://www.owasp.org/images/8/89/OWASP_Testing_Guide_V3.pdf
try tom imlement web application scanner , check this link http://trac.ush.it/ush/wiki/SecurityTools
I do ex. watchfile now IBM aapscan tools http://www-01.ibm.com/software/rational/offerings/websecurity/ to scan all my web application
check google more how to protect against sql injection
Microsft http://msdn.microsoft.com/en-us/library/ms998271.aspx
http://www.sans.org/ "sql injection"
WASC: http://projects.webappsec.org/SQL-Injection
OWASP: http://www.owasp.org/index.php/SQL_Injection
CodeProject http://www.codeproject.com/KB/database/SqlInjectionAttacks.aspx

How should be test with phpunit for xss + sql injection?

How should be test with phpunit php web application for xss + sql injection?
I thinking to find program that output xss+ other attacks to test my application forms.
This program/service should be all time updated with new xss and other new attacks.
Does such service/program exist, if not how it done today?
Please give some examples if you can.
(I use php 5.3 + zend framework + mysql)
Edit:
I asking about testing!and not prevent techniques that I also know.
Thanks,
Yosef
I don't think you can easily do unit tests for this kind of thing. It would require that your application is written in a way conducive to mocking its component parts and definitely involve a great deal of continuous manual work (making sure there's tests and mocks for everything, testing for the myriad flavors of attacks, etc etc).
The only certain thing is that if you can get some automated tool of broad scope that's always up-to-date, whoever gave it to you didn't charge enough.
The forms of protecting against such attacks are pretty well known and easy to utilize:
Always escape variables in sql, or better yet use prepared statements
If you do not need to accept and preserve HTML input, always htmlspecialchars any variable that goes into HTML (note that there are many formats such as BBCode, MarkDown, Textile etc whose sole purpose is to allow a useful subset of formatting options without opening Pandora's box)
If you absolutely, most certainly need to accept, store and serve HTML data then there's HTMLPurifier that can help -- but do that only as a last resort
Therefore, I 'd say that it's much better value for your time to make sure that you follow these practices/use these tools.
Furthermore, if you funnel all access to these two subsystems (sql and HTML output) through a well-defined part of your application (database access methods that escape all input no matter what; HTML output functions that in the same manner escape input variables and inject them into a provided "HTML template" that you subsequently echo) then it becomes easy to unit test these subsystems. Decent PHP frameworks already do this.
At this point, the only real chance of introducing a vulnerability is by circumverting or misusing these subsystems. In my opinion you are better off spending effort on specifying and following good coding practices that writing unit tests to prevent vulnerabilities in your business logic (unit tests for you sanitization code are of course another thing entirely).
Finally, there are automated SQL injection tools and XSS-related tools that you can use to probe web applications. But unless someone hires you to do penetration testing, it's better to use these as you would use protection in sex: use it, but don't count on it.
I would not write unit tests for XSS or SQL injection detection.
What I would do is:
To prevent XSS, escape all user output with one of:
htmlspecialchars
filter extension (PHP 5.2+)
escape (Zend Framework)
http://htmlpurifier.org/ (External
library)
To prevent SQL Injection, use PDO and placeholders for everything.
ie)
"SELECT * FROM users WHERE uid = $_POST['id']";
becomes
"SELECT * FROM users WHERE uid = ?";
or
"SELECT * FROM users WHERE uid = :id";
Edit
You might also want to try some browser addons such as:
https://addons.mozilla.org/en-US/firefox/addon/hackbar/
https://addons.mozilla.org/en-US/firefox/addon/xss-me/
https://addons.mozilla.org/en-US/firefox/addon/sql-inject-me/
https://addons.mozilla.org/en-US/firefox/addon/access-me/
SQL injections are one of those classes of problems that can only really be found by auditing your code. You should be looking for places where you're dynamically building queries rather than using prepared statements - those are your SQL injection vectors. Change those to prepared statements, and you remove the risk of SQL injection.
Unit testing will help you with logic errors, but won't help you find security problems such as that. The only solutions are vigilance and code reviews/audits.
UPDATE: I almost forgot! You should check out PHP_CodeSniffer for doing automated auditing of your code. It should help you detect at least some instances of where people are doing potentially dangerous and insecure things in code, and you can extend it to detect more problems than the basic install will by default.
Use frameworks like sqlmap
Get the XSS Me add-on for firefox and run it against your pages to test.

Categories