Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 17 days ago.
Improve this question
My PHP application is being attacked by adding a UNION statement to input of username. Specifically, where I check for input of a valid username the sql is modified to be
select username from user where username = '-8546' UNION ALL SELECT CONCAT(0x71626a7071,0x6d6557557a76694b6c4d,0x71786b7a71)#
This has been going on for several days with various variations of the username,with multiple consecutive attepts
This results in me being notified of sql error "The used SELECT statements have a different number of columns".
Because I'm notified of the error, I presume no damage is being done but what is the hacker trying to achieve?
I added code to detect the ip adress of the hacker, $_SERVER['REMOTE_ADDR'], mailed it to me and added it to my list of denied addresses in webmin.
what is the hacker trying to achieve?
The hacker is just trying to find out which web requests they can exploit. They try to use a negative number as the username, which is almost certainly going to get no match. Then they UNION a row with literal values that they can check for. That is, if they can make your website respond that user "qbjpqmeWUzviKlMqxkzq" exists, then they know they have succeeded in exploiting an SQL injection vulnerability.
Once they determine that, they can use that vulnerability to read other more sensitive information.
I agree with the comments above that you shouldn't just block the attacker's IP address. They can just use a VPN to masquerade as a different IP address, and start their attacks again.
What you should do is fix your code. You apparently have some SQL injection flaws in your code, for example using request variables directly in SQL strings.
You should use query parameters instead of copying unsafe variables into your SQL. Query parameters make sure the content is treated as a string literal, not as SQL syntax like UNION..., so any attempted attack will not be successful regardless of their IP address.
This is a problem with a clear and long-known solution. You have no excuse to run code on the internet with SQL injection vulnerabilities.
The significance of UNION in SQL injection is that it can allow the attacker to access other tables and return extra information without breaking a legitimate query, especially if the query in question is only expected to return one row and the client code doesn't notice the presence of extra rows. You are seeing a probe that attempts to determine which such queries will work.
If your site is really allowing arbitrary query execution then you are horribly vulnerable to attack and you should fix that vulnerability as soon as possible. Do not take any reassurance from the fact that you are getting notified of those errors. There could well be a much larger number of successfully injected queries which are leaking information or doing other damage with no errors reported.
Related
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.
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.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I've design this small function and I would like to know if anyone thinks it's safe enough, or if not, why.
function safeSQLI($INPUT){
// Trim un-needed spaces
$safe_input = trim($INPUT);
// Replace any SQL commands
$safe_input = str_ireplace("drop", "", $safe_input);
etc...
// Escape the result
$safe_input = mysql_real_escape_string($safe_input);
// Return the "Safe" result
return $safe_input;
}
Answer: No, it's not safe at all. I am now using PDO and I think I was missing something great before now.
str_ireplace() is generally a bad choice, because it doesn't work recursive. Try the following:
$safe_input = 'DELDELETEETE * FROM users';
Will result in:
DELETE * FROM users
So, your entire function falls back to mysql_real_escape_string() and everything that came before is useless. The point is: It's not impossible to write proper filtering methods, but it can be a real challenge to cover every single case there is.
You want to either follow a whitelisting approach and allow only certain types of content. This is tough to implement in the real world.
Or a blacklisting approach and deny certain characters. Most SQL injection vulnerabilites happen because one can inject additional commands in a string. If you escape the ' (or use mysql_real_escape_string(), you are usually safe). However, it depends on your web app if additional filtering is required or not.
Or use prepared statements.
It does prevent injection, provided you use quotes like you should:
SELECT * FROM `users` WHERE `name`='$username'
For example.
However it is complete overkill. mysql_real_escape_string is sufficient to make an input safe, provided you use the quotes as above.
I spent all day today trying to get some database work done on a server that had been locked down to return "Not Acceptable" HTTP responses if "anything that looked like a database table name was present in the request". Needless to say, it took significantly longer than it needed to, when a simple mysql_real_escape_string would have sufficed.
Not safe at all. Try running this:
echo safeSQLI("drdropop tatableble TABLE_NAME");
That never let you insert a post about SQL in your blog.
I think use prepare statements and mysql_real_escape_string is safe enough.
PS: And you can avoid DDL sentences at BD level, with permissions.
This question already has answers here:
Should I escape an expected integer value using mysql_real_escape_string or can I just use (int)$expectedinteger
(2 answers)
Closed 9 years ago.
I have a PHP script that depending on the value of an id in a GET variable will retrieve different data from a mysql database. The value of the id should be a number at all times. Instead of changing my current mysql query to use PDO, would running isnumeric on the Get variable and exiting the script if it is not a number be sufficient to protect against injection in all or most cases, ie, would it still be possible for some injection sql to slip through isnumeric?
Just a humble comment on the duplicate question issue, I looked at the suggested duplicate question and think that as a beginner it might not be clear on its face that my question is an exact duplicate of that one.
Yes, it would protect in this case. No, it would be a really, really bad idea unless you absolutely know what you're doing and document the choice properly in comments.
There are 2 strategies towards any kind of security:
Denial. Choose the lazy approach that works for the situation at hand instead of fundamentally fixing it. Now wait for the day you forgot this was your 'security', and you change the code and it becomes vulnerable all of a sudden, and kiddie porn is uploaded to your site.
Professionalism. Fix the problem thoroughly, validate the inputs and protect your database layer properly, by either escaping or using prepared statements.
Choose professionalism and thank me a year from now.
Seems like this question has already been answered. And yes, the isNumeric trick essentially would only allow sanitized inputs, thus shielding your application from SQL injection.
This question already has answers here:
How can I sanitize user input with PHP?
(16 answers)
Closed 2 years ago.
I own an online game where you have a status box. Which you can update it on how you're feeling. The problem I have had was that users were putting java script tags into messages and into status. So when another user came to their page, a pop up box would pop up saying haha or whatever they wanted.
I then stopped that by using
$status = mysql_real_escape_string($_POST['status']);
$foo = preg_replace('/[^a-z]/i', null, $status );
That has now stopped any JavaScript being ran but now when someone sends someone a message, it takes the spaces out so for the message "how are you " It will show "howareyou". Of course this is safe but users can't read messeges. Is there any other way from stopping script tags being inserted into the virable but still allow spaces?
I'm also real scared of someone hacking me with XSS. Because before, I was told a user could enter something in a message then when the other user opens it, it will send them there password.....
First of all using mysql_real_escape_string() on all external input prevents all SQL injections - no preg_replace needed at all! But that's only for preventing SQL injection.
In order to prevent scripting / HTML injection on your website, you should always use htmlspecialchars() to escape all text that comes from user input before you present it to a visitor of your site. (e.g. immediately after SELECT from database)
Please take this serious: If you find the time, go and google for SQL injection! It is not complicated and you'll understand it easily. If you create websites - no matter for whom - and store user input in a database, you will observe that someone tries to do SQL injection. It is easy to do, and there is automated software out in the web that can easily try all sorts of SQL injection on hundreds or thousands of websites automatically! And for a client it definitely is not acceptable if the developer doesn't prevent SQL injection at all, so take your time for this issue.
The same goes for script injection! As with SQL injection, preventing this is really very easy. All you have to do is convert all text that comes from user input into HTML, so that when some evil guy enters <script>...</script>, your visitors will simply see exactly this, because for example the < gets converted into < and thus prevents the script from being interpreted by the browser as javascript.
$foo = htmlspecialchars($status);