1

Okay, I'm using the following code (where $password = the post password variable). This is part of a large form validation code, and this line of code seems to trigger when it shouldn't. I'm afraid some part of it is deprecated. I've tried entering pass123A, Password12, and 1Password, and they all trigger this code. Why?

elseif(preg_match("/^[a-zA-Z0-9]$/", $password) == 0)
echo('Error - the password can only contain alpha-numeric chars!');
Petr R.
  • 1,247
  • 2
  • 22
  • 30
James G.
  • 2,852
  • 3
  • 28
  • 52
  • 1
    What does your question have to do with MySql? – peterm Aug 03 '13 at 07:25
  • 3
    That RegExp will only match one character. Try adding a "+" after "]" and remove unnecessary "^" and "$" for your particular case: /[a-zA-Z0-9]+/ – Alejandro Iván Aug 03 '13 at 07:27
  • 1
    *Why* are you constraining passwords like this? – DCoder Aug 03 '13 at 07:39
  • I believe SQL cannot contain certain characters (like non-standard), so I wanted to avoid invalid characters being entered. @DCoder – James G. Aug 03 '13 at 07:44
  • Stop that. [Sanitize user input](http://stackoverflow.com/questions/60174/best-way-to-prevent-sql-injection-in-php) before passing it into SQL queries. Restricting input like you're doing is a tell-tale sign of amateur systems and a big red honking "easy target" sign for all the script kiddies. – DCoder Aug 03 '13 at 07:49

2 Answers2

3
preg_match("/^[a-zA-Z0-9]$/", $password)

...will only match single character passwords.

preg_match("/^[a-zA-Z0-9]*$/", $password)

...should work better.

Maybe I should note that this will also match an empty password, but I assume that you check length separately.

EDIT: If you're restricting passwords due to SQL insecurities, you should really change over to PDO or MySQLi and use parameterized queries, that will allow you to store any string without special handling for special characters (like '), which will make SQL all over your site more secure.

Further, if you're storing passwords in clear text anyway, you should look into hashing them :)

Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • As I said in a comment above, is that "^" really necessary? Just because if all accepted characters are alphanumeric, without a particular initial one, "^" is not necessary, isn't it? Note that I'm not saying it won't work, I want to know if that's necessary or not. – Alejandro Iván Aug 03 '13 at 07:32
  • And a blank password! :) – vee Aug 03 '13 at 07:34
  • 1
    @AlejandroIván If you remove the `^` and `$`, it will match anywhere in the string, not the whole string. In other words, `/[a-zA-Z0-9]+/` will match any string that has _any_ alphanumeric character in it. We want to match a string where _all_ characters are alphanumeric. – Joachim Isaksson Aug 03 '13 at 07:39
  • To show the difference, `echo preg_match("/^[a-zA-Z0-9]+$/", 'a!'); echo preg_match("/[a-zA-Z0-9]+/", 'a!');` will give a match on the latter, not what we want. – Joachim Isaksson Aug 03 '13 at 07:41
  • Yes, I have a check length, this is one of 4 checks on the password. – James G. Aug 03 '13 at 07:47
0

You can use like this: +$

if (...)
   // do anything
elseif(!preg_match("/^[a-zA-Z0-9]+$/", $password))
   echo('Error - the password can only contain alpha-numeric chars!');

Use +$ instead of *$.

* allow empty string. If $password send as empty, not match.

Bora
  • 10,529
  • 5
  • 43
  • 73