Code igniter MySQL AES with active records? - php

How would i use code igniters active records to insert/update/select data from a database using mysql's built in aes encrypt/decrypt functions?
I know i could just use the normal sql query, but i'd like to use active records ideally.
Thanks

If you use the code provided previously:
$this->db->set('password',"AES_ENCRYPT('{$data['password']}','my_key')",FALSE);
you should still escape the password before passing it into db->set
use:
$pass = $this->db->escape($data['password']);
That way if the password contains special chars it won't kill the query

You can still use AES_Encrypt if you turn off escaping for that particular clause by passing FALSE as the last parameter:
$pass = $this->db->escape($data['password']);
$this->db->set('password', "AES_ENCRYPT('{$pass}','my_key')", FALSE);
Also point you to the CI built-in Encryption Class, and an article on considering 1-way encryption.

Related

Using slashes in the where clause while comparing values in active record codeigniter

I have the following query
$query="DELETE FROM salesinvoiceitems WHERE invoiceNumber=".$this->put('invoiceNumber');
Here $this->put('invoiceNumber'); always have values like "M\34\SD". Due to slashes in values it doesn't work as expected.
I researched and found the mysql_escape_string can be used for this purpose but its deprecated now as per the manual. So whats my best bet here?
Why not use Codeingiter Active Record instead? An example:
$this->db->where('invoiceNumber', $this->put('invoiceNumber'));
$this->db->delete('salesinvoiceitems');
Taken from Codeigniter documentation:
Beyond simplicity, a major benefit to using the Active Record features
is that it allows you to create database independent applications,
since the query syntax is generated by each database adapter. It also
allows for safer queries, since the values are escaped automatically
by the system.
There's a method in the activerecord called escape, so you should :
$invoice = $this->db->escape($yourVar);
$query = "DELETE FROM salesinvoiceitems WHERE invoiceNumber=$invoice";
Which will protect against sql injection as it escapes the var.
Try this
$query="DELETE FROM salesinvoiceitems WHERE invoiceNumber=".addslashes($this->put('invoiceNumber'));
Try strip slashes
$query="DELETE FROM salesinvoiceitems WHERE invoiceNumber='".($this->put('invoiceNumber')). "'";

PHP PDO PARAMS required if using stored procedures?

I'm new to PHP, but not programming. Have come from an ASP [classic] background. In brief, I'm using PHP 5.4, with FastCGI on IIS7 and SQL Server 2005 Express. I've learnt the fundamentals, and have spent quite some time looking into security.
I'm sanitising both GET and POST input data. My db connection strings are in a separate file placed outside the web root. I'm using PDO prepared statements [though I've heard query+quote perform faster] with named placeholders along with db stored procedures.
I'm trying to understand why I would need to use additional arguments within the bindParam function, particularly data type options "PDO::PARAM_STR, 12" [second argument in that example represent the data length right?].
What are the benefits of specifying the data type and length within the bindParam? Is it needed if I'm using stored procedures in which the data type and length is already specified? Also, I believe I need to use something like "PDO::PARAM_INPUT_OUTPUT" to return a value from a stored proc?
Thanks!
** EDIT **
For some reason, if I use the PDO::PARAM_STR argument, my stored procs don't seem to write data into the db. So I omitted that argument. Here's my code:
$sql1 = $conn->prepare("EXEC insert_platts :userAgent, :userIp, 1, :source");
$sql1->bindParam(':userAgent', $userAgent);
$sql1->bindParam(':userIp', $userIp);
$sql1->bindParam(':source', $source);
$sql1->execute();
Also, rather than returning the identity value from the stored proc, I'm using lastInsertId() instead:
$lastRow = $conn->lastInsertId();
print $lastRow;
No, data type and data length are not needed. I'm using mysql stored procs and the parameters are never typed values, all though I validate them of course. I guess that the reason is extra security and INOUT params. Quote:
To return an INOUT parameter from a stored procedure, use the bitwise
OR operator to set the PDO::PARAM_INPUT_OUTPUT
have you tried this?
$params = array(
':userAgent'=>$userAgent,
':userIp' => $userIp,
':source' => $source
);
$sql1 = $conn->prepare("EXEC insert_platts :userAgent, :userIp, 1, :source");
$sql1->execute($params);
About special characters: are you using correct encodings? I mean, the same encoding in the php app and the DB... sometimes is hard to work with one encoding in the scripts and other in the database.. and very often problems like that arise...

Using a function within a MySQL query

I have the following line of code :
mysql_query("SELECT name FROM details WHERE md5(name) = '".md5($input_name)."'");
This query works just fine , however , when i change the query to the following :
mysql_query("SELECT name FROM details WHERE salt(name) = '".salt($input_name)."'");
The query doesn't seem to work.
The salt function is as follows :
function salt ($name) {
global $salt;
return $salt.$name;
}
where $salt is a global variable ( an md5 hash)
Why doesn't the second query work ?
MySQL has no access to functions you define in PHP. You can only use functions that MySQL defines in a MySQL query, or functions that you have written in SQL. You'll have to rethink what you're doing and express it in a way that does not require MySQL to use PHP functions.
Functions in PHP and functions in MySQL is two seperate things.
When sending MySQL queries, MySQL will be responsible for parsing the string you are sending. And MySQL doesn't know of any of the PHP code you made - and vice versa.
Wouldnt this be easily done by:
$saltinput = salt($input_name)
mysql_query("SELECT name FROM details WHERE salt(name) = '$salitinput'");

What's wrong with these passwords?

When I try to put a new user's password into a MySQL database, it doesn't encrypt it correctly. Here's the code I'm using:
$encPassword = hash('sha256', $_POST['password']);
$query = sprintf("INSERT INTO users(`userName`,`email`,`password`)
VALUES('%s','%s',PASSWORD('%s'))",
mysql_real_escape_string($_POST['userName']),
mysql_real_escape_string($_POST['email']),
mysql_real_escape_string($encPassword))or die(mysql_error());
$sql = mysql_query($query);
When I check the database though, it doesn't store the password as sha256 encrypted. It only has 16 random characters (it should have ~50). What's wrong with it?
Check you have correct column lenght allowed in your table. That's the most common problem. Your field must be at least VARCHAR(64)
I don't think you should use the PASSWORD keyword: http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html#function_password
The PASSWORD() function is used by the authentication system in
MySQL Server; you should not use it in your own applications. For
that purpose, consider MD5() or SHA1() instead. Also see RFC 2195,
section 2 (Challenge-Response Authentication Mechanism (CRAM)),
for more information about handling passwords and authentication
securely in your applications.
But, you've already hashed the password on the 1st line of code. Just insert that directly into the database...
Have you checked the value of $encPassword before the INSERT?
It's because you are using PASSWORD('%s') function in your query, (so you are double hashing your password).
Just insert it as other values ('%s')

How to use $_GET securely?

I need to use a get function to retrieve $title variable from a url.
$title=$_GET["title"];
The $title is later used in a MySQL query.
The question is how to make this secure?
In other words, how to neutralize any malicious codes sent through the URL.
(For a value of "secure" equal to "to prevent it breaking the database"): use any database API that uses bound parameters.
Bound parmeters tend to let the database handle the escaping (so uses escaping routines written by the database authors rather then the language authors) and uses a syntax that is less prone to being forgotten about for that one vital escape then manually escaping each piece of input data with (for example) mysql_real_escape_string.
You might need to take other steps later before you do something with the data in a different context (e.g. to make it safe to insert into an HTML document)
You must use mysql_real_escape_string() to escape all characters that could interfere with you database. If you're displaying this title, you should also make use of htmlentities() or striptags()
As of PHP 5.2, you can use filter_input() and filter_input_array() to sanitize and validate the the $_GET or $_POST data.
For example:
$my_string = filter_input(INPUT_GET, 'my_string', FILTER_SANITIZE_STRING);
Read more about that in this article here.
For SQL queries, it's very recommended that you use PDO with prepared statements to protect from SQL injections. You can read about PDO in the PHP Manual here.
You can use mysql_real_escape_string function (Escapes special characters in a string for use in an SQL statement)
Php Manuel
Use query parameters. There is a number of different ways to connect to mysql from PHP, and they way to use parameters varies a little from framework to framework. Here is an example using PDO:
$dbh = new PDO('mysql:dbname=test;host=127.0.0.1', 'username', 'password');
$sth = $dbh->prepare("select * from table where title = :title")
$sth->execute(array(':title' => $_GET["title"]));
$rows = $sth->fetchAll();
var_dump($rows);

Categories