Sample login code that was hacked through SQL Injection, though mysql_real_escape_string ...

I am using CodeIgniter and have problems with hacking. Is it possible to make SQL Injection the login code below:

function process_login() { $username = mysql_real_escape_string($this->input->post('username')); $password = mysql_real_escape_string(MD5($this->input->post('password'))); //Check user table $query = $this->db->getwhere('users', array('username'=>$username, 'password'=>$password)); if ($query->num_rows() > 0) { // success login data 

Am I using mysql_real_escape_string incorrectly, or what?

+6
security php sql-injection codeigniter
source share
8 answers

No posted posts are likely vulnerable to SQL injection. Although getwhere () can do stripslashes (), I'm not sure.

It is likely that if SQL Injection exists, then it is in another part of your application. An attacker could use this vulnerability to get the extremely weak md5 () tag, hack it and then log in. Use any member of the sha2 family, sha-256 is a great choice.

If your site is corrupted, I seriously doubt that this is an SQL injection. Its difficult to automate the operation of sql injection to defecate websites, but it is possible. I would make sure that all libraries and installed applications are fully updated. Especially if you have a CMS or forum. You can run OpenVAS crawl of your site to find out if it will find any old software.

+6
source share

Database

Judging by your code, I see that you are not using the latest version of CI (2.0.2 from 06/12).

As pointed out in changelog , the getwhere() function getwhere() now called get_where() ) was left as for version 2.0.
As for the ubiquitous application, you are strongly advised to update the current version, as there were many fixes at the same time, and you should always rely on the safest version.

mysql_real_escape_string is usually considered "sufficient" to provide a high level of security in your queries, but, as happened with its predecessor (mysql_escape_string), it is not 100% safe against all types of attacks, so relying on it is not very good. Despite security, there are still attacks that can get past this filter.
Check, among many, this question on SO for more information on this.

In codeignier: If you are developing your own application, I suggest you at least use the mysqli extensions or, even better, the PDO class; prepared statements are undoubtedly safe and should be approved in everything else.

But we are in the context of structure, and Codeigniter offers 3 great ways to safely query your database by applying the right tool to the correct input without having to worry about it. I'm talking about query bindings and manual escaping using the $ this-> db-> escape () family and Active Record Class
You can find usage examples in the URLs I just linked, or read answers from other peers here, so I wonโ€™t go into the details of each procedure in this post.

Password

As for your password, as already stated by other users, md5() is now an invalid hashing algorithm. There are rainbow tables there that can crack your md5 password in a relatively short amount of time, so you are better off with higher levels of security hashing, such as sha1 () or sha256, sha512 and others

In codeigniter: Codeigniter comes with a security helper class that provides you with a convenient do_hash() function (maybe dohash() in your old installation) that can be assigned a hashing alg. as a parameter (currently I think it only supports md5 and sha1) and sha1 () is used by default.

Other observations

I donโ€™t quite understand why you blame your login for your SQL injections. Are these 2 forms in your entire application?
You do not provide information to find out if you use the $ _GET parameters or follow your own URI segmentation, but I believe that you do this, so I assume that you are safe from this point of view.

You have to make sure that there is no other input form on your site that contains the input coming into the database, otherwise you can protect your login as much as you want, but someone can penetrate the backdoor and read your database table from there and log into your site in a "legal" form.

In addition, there may be another source of intrusion, for example, a compromised cookie. As a piece of advice, when you decide to use the framework (and you do yourself a lot better than developing from scratch and all by yourself), you should use the MOST of your functions, especially when it comes to security. This is a huge and very sensitive issue, so you MUST give this topic your top priority, and a well-designed structure with a huge community and frequent updates is closest to the security you can get.
Therefore, you are advised to update the CI installation (manuals can be found here in your manual. Choose your version and follow the instructions), always use the top tools that you give for each task, and do not think that blocking your door will make you safe from intruding from your windows. Always check and study all possible causes.

Late addition: Don't forget XSS, CSRF, session commit, and other hot security issues.

+5
source share

Check out this old SO question.
I would use:

 $sql = "SELECT * FROM users WHERE username = '?' AND password= '?'"; $dbResult = $this->db->query($sql, array($this->input->post('username')),array($this->input->post('password'))); 
+4
source share

If this is a constant hack, seriously consider posting some entries to write the username / password to a file somewhere. If this is an sql injection through this login fragment, it will appear in this new log file somewhere. And while you are on it, if you want, write down the generated SQL query as well.

In any case, remember that mysql_real_escape_string () only covers the mysql metacharacters: single quote, double quote, semicolon, etc. ... You can still hack the login function using a bilingual parameter. It is impossible to tell if your getwhere function is vulnerable, but consider the case where the password provided is xyz OR (1 = 1). The generated query might look something like this:

  SELECT id FROM users WHERE users=someusername AND password=xyz OR (1=1); 

A perfectly valid query also went through mysql_real_escape_string intact, because it did not contain critical metacharacters.

+3
source share

I understand that Active Records will correctly avoid values โ€‹โ€‹for you. So, with $query = $this->db->getwhere() you DO NOT need to use mysql_real_escape_string() .

But you should always use some kind of controller check. In particular, you can limit the username and password to specific characters using a regular expression. It is always recommended.

In addition, if you often encounter typical attacks, use PHPID. This is an intrusion detection system that will help you prevent an attack from actually causing any damage, as you can cause an error or notification of any kind.

You can also read this safety guide. http://net.tutsplus.com/tutorials/php/codeigniter-from-scratch-security/

+1
source share

If all your functions and accessors do what their names seem to offer, then this script is not vulnerable to SQL Injection.

How to use mysql_real_escape_string ... yes and no. Yes, you have the right idea, but you are actually using it excessively. If you have an MD5 password, then this input is now clean and cannot be used for injection, so calling mysql_real_escape_string is redundant. So this will be good:

 $username = mysql_real_escape_string($this->input->post('username')); $password = MD5($this->input->post('password')); 

As mentioned earlier, MD5 is a rather weak hashing algorithm. Look at the SHA and pop the hash.

To answer the previous answer, if the user enters "xyz OR (1 = 1)" as a password, this does not pose any threat to his script for two reasons.

1) An MD5 hash converts this to a harmless hash (e.g. 'd131dd02c5e6eec4693d9a0698aff95c') by querying something along the lines SELECT id FROM users WHERE users='username' AND password='d131dd02c5e6eec4693d9a0698aff95c';

2) mysql_real_escape_string prevents string injections, that is, injections that require a single or double quote to escape from the expected SQL query, but do not prevent (for example) injection with a numerical input, which you will need to use type casting to block .

It really depends on your call to $ this-> db-> getwhere. If it just builds a query usually without doing anything funny (for example, stripping quotes or treating strings as integers that would still cause an error), etc.), you are simply not vulnerable to this script. If you could give more details about the โ€œtypeโ€ of hacking that you experienced, we could probably give you some tips on where to look. Were you disappointed?

I have not played with CodeIgnitor, but I expect that their built-in input / database functions will not do anything strange, so if you have not edited the getwhere function yourself, you are probably fine in this particular place.

+1
source share

The code you provided is not vulnerable to SQL injection, but you should never put passwords in queries, not even hashed ones, because you cannot be sure that the query is stored in the server log or not, and you usually do not have control over who can have access to this.
Request / download a user record by username, and then compare the password hash in $ _POST with this.

0
source share

The code seems to be injection resistant. You accept the md5 password field, which does not contain any injection in this field. A vulnerability field is a username that you avoid anyway. Are you sure this is an injection attack?

Is there another field, such as access_token fields, passed to prevent CSRF

The following are probable causes of strange behavior:

  • You are using the mysqli driver in the database configuration and escaping the string according to the mysql lib. Try specifying $this->db->conn_id as the second mysql_real_escape_string parameter and check your php logs for warnings.
  • mysql_real_escape_string requires a connection link identifier as the second parameter. If you do not provide it, you will experience strange behavior. I suffered from this with the help of a cognitionist. In my case, mysql_real_escape_string returned empty rows. If the case is the same with you, make sure that you do not have empty passwords and usernames in your users table (very unlikely).
0
source share

All Articles