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.
Related
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.
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 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 8 years ago.
Improve this question
How much important is it to secure the URL parameters naming? Is ?user_id=3 less secure then ?uid=3 or ?u=3 or just /user/3? Should I really consider making parameters hard to guess?
Obscurity is no security at all. The only reasonable factors to consider are readability/prettiness of links. If you have 200-character links, they are not memorable, and are kind of hard to paste, and consume a lot of space (e.g. can't send through SMS, and they're hard to type on a mobile); on the other hand, it's easier to have confidence in a link if you can understand its semantics.
The userid should be a session variable, and the session id should be in a cookie.
Some security information says to avoid all URL variables, but that is just security through obscurity. The point is, if it comes through to the user from any source $_GET, $_POST, $_COOKIE, $_SERVER, $_REQUEST, $_FILE... You need to sanitize it. By:
Using a white list wherever possible
Using RegEx and type checking all input before used
If it will be displayed, remove HTML
using strip_tags() [if there are some allowed tags]
or htmlentities() [prefered]
Use prepared statements (mysqli or PDO are common libraries that can do prepared statements for MySQL databases) for all database queries to prevent SQL injection
Use nounce to prevent XSFR attack and accident form resubmission
If its a file check mime type (not just the mime type in the $FILE array) before moving it
TL;DR: Using mod_rewrite is hide variable's real names might not be a terrible idea, and may make your urls "prettier" to the user -- but it is not a huge security gain.
In general, I have found that consideration of implementation is critical. Is this going to be used by you and a couple friends? It's probably less important, in that case, to worry about what you're naming URL variables.
If the data is sensitive, don't put it in the URL at all - this includes information specific to users, like passwords (which you shouldn't have in plain text anyway), password hashes, email addresses, private information, etc. I don't worry too much about usernames. If the info is important/sensitive, POST it rather than GET.
Using the .htaccess with some rewriteRules can make URLs much easier to remember - for example, website.com/page/1 is considerably more user-friendly than website.com?page=1, particularly when you get more than 1 variable in there. .htaccess rewriterules are not difficult to make, and can help your website look considerably more professional.
In terms of variable NAMES in the url, it again depends on usage. For example, "user=username" would be fine, or even "u=uname" or "uid=username" are acceptable, but if you're worried the user might easily find and change something, that's a big indicator that there's a problem: Not because the user could change something there, (even POST isn't secure, users can POST anything they want) but because your backend should be built to handle it, even IF your users change things in the POST/GET.
TL;DR: Putting GET variables in the URL bar is a courtesy to users. If they will appreciate or make use of it, do it - it's a nice touch. Users don't want you to put sensitive information there, and users don't want it to be too long. Any and all security should be done in the backend, where the user can't tamper with it.
It's a very good question. I do not think it needs to be - or can be - really secure to be honest.
And both have advantages. eg
Make it short and the url will be short. (too long urls can be a problem if you put urls together dynamically)
Make it long and its easier to debug things later.
:)
I've searched around and found a way to do exactly this. But I'm hesitant because I occasionally read that its a "security risk". Unfortunately, nobody ever elaborates on why. I, personally, can't think of any security risk that wouldn't involve an attacker already having permissions they shouldn't. The MySQL/PHP servers are running on the same machine. so there's no public requests between the MySQL and PHP.
The PHP script triggered, will make an API call to a web service on a third-party CRM/ESP that keeps a simplified version of certain tables on a their server. Our marketing team could then log into the CRM's GUI and send emails, gather information, and plan marketing campaigns without the need to bother the dev team.
The tables on this server do not mirror ours, they contain only information they would need. The reason I want to use triggers is to keep their information as up-to-date as possible and have that logic in one place, instead of scattered throughout the project.
UPDATE:
I always sanitize/validate any Forms that touch MySQL. I never store PHP in my tables. I never use FTP (SFTP using a .pem instead of a password).
The script that will be executing will be a single file I created that won't change which is going through the same framework I'm using (zend). The only variables passed to the script will be the row's id (which will be validated as an INT).
I'm thinking of not doing this because of performance. And making PHP execute Asynchronously is possible, but difficult and not worth my time to implement. But I'm still curious, Other than the performance penalty, how would the security concerns be any different than say a web service? I mean you definitely have to sanitize/validate just like you would a web service, so given that, what concerns would there be?
There are different ways your app can be compromised, such as SQL injection, a sniffed FTP password, or a vulnerability in the code itself. It is generally a good idea to keep these things as localized as possible to prevent a breach in one area from cascading.
For example, say that you are storing sensitive data in your database. Typically, you would encrypt this data somehow, using a salt and key that is not stored in the database itself. Then, if your database is compromised by SQL injection, the attackers may cause damage, but they will not be able to steal the sensitive information. However, if you are executing PHP stored as text in your database, the attacker will certainly realize this and update it to execute his code, from whence he can figure out how you are encrypting the sensitive data and unencrypt it.
In short, SQL injection is very common (even if you are following best practices, nobody says the intern who walks in next year will) and it is therefore not safe to execute code stored in a database.
EDIT: after reading your link more closely, I need to restate some things. I don't see a particular security risk in this, but this seems to really contravene the separation of data and logic. Further, mysql is not async and there is no way that this can possibly scale under load...
I Just noticed that my mysql_real_escape_string function is not inside a '' in some of my php scripts and it was vulnerable to injections and things like sleep(30) executed on my production site.
I am going the PDO route and implementing the prepared statements after lots of reading here. but this is not implemented yet.
Few questions, I see in my logs that lots of injections where done by people online but I can not see any damages. the user that the site runs to do sql queries has update/select/delete/insert only privileges.
But I am woried things like sleep(30) and what not works and if they did any damages I am not seeing?
Can you tell me where to check for damages or was I safe for at least major damages?
Can they have changed hidden mysql settings or system settings?
By the way, I tried to run latest updates on centos 6+ linux and php.
Thanks
edit:
just to clarify, the database is empty almost and i am not worried about the data being there and the passwords are hashed sh512. so the data inside is not important since this is a new application i am writing. but i am worried if they changed anything on the system or the db i should be worried about. some of the injections i see have java etc but the log is huge and its going to take time to go over it. i also see some schema strings in the injections.
now the question is can they have read my schema info or modified them? why does functions like sleep are working if it is a restricted user? what other functions could they have run?
note i have other DBs in the same MySQL. should i be woried about those?
by '' i mean:
select * from dbname where id=scaped_string
i should have put it in quotes
Checking for damage done to your data is dependent on the kind of data you have in your database. If after careful inspection you don't see anything wrong, then there is probably nothing wrong. If your data is of any decent size, this will be difficult or impossible.
There are many automated bots roaming the internet looking for code vulnerable to SQL injection attacks. Their attempts are probably what you are seeing in your logs. Just because an attempt was made does not necessarily mean an intrusion occurred.
Also keep in mind that you won't necessarily have evidence of data being stolen. The best way to determine this would be to take your server logs and replay them on a copy of your current server, checking to see if you get any data back.
Without any further information, we have to assume the worst case: An attacker is able to read, write, and delete arbitrary data in your database, and possibly even files on your file system, which may lead to compromise of your whole server (e.g. command execution via PHP file, privilege escalation, etc.).
Now let’s have a closer look at the possible impact:
Since PHP’s MySQL extension does not allow multiple statements, so called stacked statement attacks are not possible. So the remaining possibilities depend on the actual statement verb and the context, i.e. the clause inside the statement:
SELECT statement:
Reading any accessible data (e.g. sub-queries, unions, boolean-based blind, etc.)
Reading files (LOAD_FILE())
Writing files (… INTO OUTFILE …)
UPDATE statement:
Obviously updating any accessible data, possibly not just in the current table
Reading any accessible data (e.g. sub-queries, boolean-based blind)
DELETE statement:
Obviously deleting any accessible data, possibly not just from the in the current table
Reading any accessible data (e.g. sub-queries, boolean-based blind)
INSERT statement:
Obviously inserting arbitrary data
Reading any accessible data (e.g. sub-queries)
Some of these may not have a direct impact but may be used to exploit other vulnerabilities. In the end, it depends on the actual vulnerable statement.
As far as I know, there is not hidden mysql setting other than sanitizing your inputs to protect your data from being injected.
You said, you saw lots of injections done by people into the site, and yet you can not see any damage, maybe they were just injecting a plain HTML tags, or trying XXS attacks, because the real mysql injection, can delete your tables, update, reset every data subjected to mysql injection, so if I were you, I would implement PDO right away.
If you have anything like admin panel you should check for webshells and other backdoor-like tools on your server, because attacker could easily read your credentials from appropriate table. And, ofcourse, look for any changes in your pages (look for iframes and suspicious JS code).
Worst case scenario is executing INTO OUTFILE in writeable directory and then accesing it via local include or directly.
But, first of all, before worrying you should consider this as most common automated sql-injection checkers (bots you might say) and if you don't see any damage - mose probably there was no intrusion. But be careful - most intruders nowadays don't look for any visible damage, most probably they will inject some malicious code in your pages (like iframes with their exploits).
So, don't be too paranoid, but still cautious :)