Security in php, is my code safe? - php

I have 2 questions about security in php,
First:
Is it possible to upload a file with sql injection? (access to load_file and INTO FILE is denied)
Second:
in PDO I need use PDO::quote method, is this method safe for injection?
Here is an example:
$check = "SELECT * FROM table_name WHERE username = ". $database->quote($this->username);

Is it possible to upload a file with sql injection?
This site is for developers, not fraudsters I believe. And as a developer, I do not care of whatever injection variants at all. Even if this particular injection is no possible - a wide range of other injections makes you in no less danger.
The only thing a developer should know is how to properly format his query. Everything else is a useless rubbish. So, it's how to format an SQL query and how to make it properly and unconditionally is indeed what a developer ought to know.
But whatever injection types are none of his business.
The only thing a developer have to know on injections is that an improperly formatted query literal could be exploited.
in PDO I need use quote method
Nope, in PDO you need to use prepared statements instead.
is this method safe for injection?
Although the example you provided is quite safe (for the conventional encodings), the very approach is error-prone and may let you easily slip into injection. As long as formatting facility being alienable - there is still a high risk for it to be moved away from the query building and eventually be lost or improperly used.
The very benefit of a prepared statement is that it does formatting right in place, unconditionally.

Is it possible to upload a file with sql injection? (access to load_file and INTO FILE is denied)
If all of the MySQL file i/o functions are disabled, then generally speaking no it is not possible to upload a file through an SQL Injection vulnerability alone. It may still be possible if there is some other code elsewhere that combined with the SQLi ultimately allows an attacker to "upload a file".
In PDO I need use quote method, is this method safe for injection?
As long as the character set is configured correctly, then PDO::quote is considered secure. As others have pointed out though, a Prepared Statement is preferred.

First:
Is it possible to upload a file with sql injection? (access to load_file and INTO FILE is denied)
Yes it is always possible to upload such file but it is up to you if you check and escape the files that are stored before putting them to db in any format.
Second:
in PDO I need use quote method, is this method safe for injection?
The best way to avoid SQL injections in PDO is to use prepared statements.
Check this topic which covers topic really well
When you bind param to your query you can specify type of it for example PDO::PARAM_STR or PDO::PARAM_INT. This will do proper escaping and you will be more secure against SQL INJECTION

Related

Do I have to sanitize user input with prepared SQL statements?

Is this considered completely safe?
$stmt = $dbhandler->prepare("update sometable set somefield=:somestring");
$stmt->bindParam(":somestring",$_REQUEST["hack_me_please"],PDO::PARAM_STR);
$stmt->execute();
And if not, what could make it safer? I'm assuming there are unknown vulnerabilities in PDO/MySQL/PHP that may be exploited in the future so I'm wondering if there is anything reasonable I can do make my queries safer, or is it out of my hands with prepared statements.
If it is this easy, why is SQL injection still a thing? Shouldn't it have gone the way of polio?
No, it's not necessary to sanitize inputs when using prepared statement to protect sql injections but you may do it if you want for any other reason.
If it is this easy, why is SQL injection still a thing? Shouldn't it have gone the way of polio?
it's easy for those who knows about it, nothing is easy unless you know it. I believe sql injection doesn't happen a lot nowadays.
Your example is completely safe because it passes the user input parameters separate from the query string. The reason sql injection still exists is because a lot of users still use the deprecated mysql_* api/driver and are unaware of the alternatives. Also, even using pdo or mysqli you can still pass user input directly into the query string instead of binding it separately.

How to turn off multiple statements in postgres?

I think it is a good idea to turn off multiple statements like this to prevent this type of sql-injection.
Example of multiple statements:
$query = "UPDATE authors SET author=UPPER(author) WHERE id=1;";
$query .= "UPDATE authors SET author=LOWER(author) WHERE id=2;";
$query .= "UPDATE authors SET author=NULL WHERE id=3;";
pg_query($conn, $query);
Is it possible to prevent multiple statements in posgresql settings or for example using posgre's related PHP code?
Or maybe there is any way of parsing SQL queries before passing them to pg_query in order to detect queries which consists of more than one statement?
No, there is no way to disable multi-statements in PostgreSQL. Nor, as far as I know, is there any way to do so in the PHP Pg or PDO PostgreSQL drivers.
They aren't your problem anyway. Disabling multi-statements might be a (slight) SQL injection harm mitigation, but it wouldn't be any real protection. Consider writeable CTEs, for example, or qualifier removal attacks.
Instead, protect your code properly in the first place. Rigorously use parameterized statements instead of string concatenation, so there's no SQL injection opportunity in the first place. It's not hard to avoid SQL injection, you just have to be a little bit sensible with your coding practices.
Use PDO or pg_query_params for all queries, and make sure you don't concatenate text that's come from outside the immediate scope directly into SQL text, use a parameter. Even if it comes from elsewhere in the application and is considered "trusted" ... later refactoring might change that.
I think it is a good idea
It is, actually, not.
You have to prevent injections, not multiple queries.

Will this SQL injection prevention work in theory?

I plan to prevent SQL injections by using the the $variable and route it to a function that will scan the $variable for any sql commands or any attempts of injections. I will also make a list of common sql commands that people would use inject so it would be detected.
Note: I previously asked a similar question but this time I have a theory I managed to think ;)
The simplest and secure way to prevent SQL injection is to use mysql_real_escape_string() on any untrusted data (eg: $_GET or $_POST). It will escape any special characters so the query will be safe.
If you use mysqli, see http://www.php.net/manual/en/mysqli.real-escape-string.php
More about SQL injection and how can you protect yourself against it: http://www.php.net/manual/en/security.database.sql-injection.php
So, your plan it's not the best way to do it. It unnecessarly complicates things.
No. Blacklisting will inevitably give false positives and almost certainly give false negatives.
Use bound parameters and let the database deal with it for you.

Sql injection prevention techniques still vulnerable?

If I'm using mysql_real_escape_string and addslashes to avoid sql Injection attack in my website is this two are enough to stop SQL Injection so its 100% sure no one can now attack using SQL Injection?
It depends on your query; if you are talking about just the values you want to insert in your database, mysql_real_escape_string is enough, you don´t need addslashes.
If you also are talking about variable table or column names, you'll need white-lists as well as mysql_real_escape_string will not prevent sql injection on these.
So the answer really is: No, it depends on your query.
Don’t use addslashes at all; it’s not appropriate to protect against SQL injections.
Use mysql_real_escape_string only. And if you need to change the character encoding, use mysql_set_charset.
There isn't any simple "magical" way to prevent SQL injection. mysql_real_escape_string is a good start, using PDO (docs) is even better. Above all of that, you need to look at your database structure, look at your queries, look at your data sources, then think it out. Where is data coming from? What would happen if the data isn't what I expect?
The entire structure of your code should be created with a mind toward controlling the flow of your application logic. The best way to prevent SQL injection is to stay aware and in control of what goes in your database.
You should never use addslashes. Just stick with mysql_real_escape_string
Anyway only the death is sure.
And if you fear the death you should use PDO to be less prone to vulnerabilities
http://it.php.net/manual/en/pdo.prepare.php
Depends on what you mean, I suppose.
The mere use of mysql_real_escape_string will not protect you with 100% certainty, if for no other reason than that it is possible to use it incorrectly.
On the other hand, the correct use of mysql_real_escape_string should protect you as close to 100% as you can get.
On yet some other hand, it is probably easier to make mistakes as a programmer using mysql_real_escape_string compared to a parameterized query.
If you are unsure about your code, perhaps posting it and asking about it specifically may be more educational/useful.
Also: Ditto what others are saying regarding addslashes.

PHP SQL injection prevention without parameter binding [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to prevent SQL injection in PHP?
I am working for a video streaming website for my college library. I am using PHP and MySql. I have not used any parameterized queries in this project.
Recently I came to know about SQL injections. Now that my code is almost done and I have to submit the project in the next two days, how can I now ensure that my code is not SQL injection prone?
Converting the whole thing in to a parameterized interface is what I can't do now. What should I do now to avoid SQL Injections on my website?
The basic idea to prevent SQL injections (if not using Prepared Statements) is to escape your data.
When you inject some expected integer value into an SQL query, make sure it's an integer, using intval().
When you have a decimal/numeric field in your table, use floatval().
And when you have a string (char, varchar, text) field in your table, use the function provided by your API to escape strings :
mysql_real_escape_string()
mysqli_real_escape_string()
PDO::quote()
I really recommend that you go back and do it right with parameterized queries. It is the only solid path towards security. It likely won't take too long to do this once you get started.
You should also know that websites are never "finished". When you launch a site, your work has just begun. Fixing security troubles as you learn about them is part of it, and this is no different.
You'll want to make sure any user provided inputs that get used in SQL queries are escaped using the PHP function mysql_real_escape_string and if you are letting people submit text to run htmlentities on the provided text so XXS isn't possible. If possible, white-list user provided input and discard anything else
This is just touching the surface of what you can do but look into query escaping and preventing cross site scripting.
Use PDO (or alternatively mysqli or some abstraction layer) and prepared statements.
Quick example:
$pdo = new PDO($dsn);
$stmt = $pdo->prepare("SELECT name FROM users WHERE id = ?");
$stmt->execute(array($unsafe_id));
$name = $stmt->fetchColumn();
In this example, $unsafe_id will be safe to use. To quote the manual page:
Calling PDO::prepare() and
PDOStatement::execute() for statements
that will be issued multiple times
with different parameter values
optimizes the performance of your
application by allowing the driver to
negotiate client and/or server side
caching of the query plan and meta
information, and helps to prevent SQL
injection attacks by eliminating the
need to manually quote the parameters.
PDO will emulate prepared
statements/bound parameters for
drivers that do not natively support
them, and can also rewrite named or
question mark style parameter markers
to something more appropriate, if the
driver supports one style but not the
other.

Categories