Slashdot Mirror


PHP and SQL Security

An anonymous reader writes "PHP and SQL Security are being proven more weak every day. Uberhacker.Com is running a PHP and SQL security research project to raise awareness of secure scripting. The site hosts guides to secure PHP programming, forums, and scripting challenges to see who can create the most secure scripts."

3 of 305 comments (clear)

  1. Guides to Secure Programming? by JumboMessiah · · Score: 5, Informative

    Other than the scripting challenge, what's on this site? I've read the guides to hacking, but it's all a bunch of kindergarden material. Seems if you follow the guides you'll certainly have insecure PHP scripts with all kinds of SQL injection. How about posting some real articles on secure PHP scripting...

  2. SQL Injection in PHP by uss_valiant · · Score: 5, Informative

    AFAIK SQL injection can be prevented by binding the parameters to the SQL statement and not putting them within SQL.
    An example:
    It's easy to inject some malicious SQL when using the following PHP code:
    mysql_query("INSERT INTO FOO('Bar') VALUES('$some_post_param');");
    But if you prepare the SQL statement with parameters and bind the variable $some_post_param to the statement, it will be secure.
    see mysql manual for mysqli_stmt_bind_param() aka bind_param
    $stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)"); $stmt->bind_param('sssd', $code, $language, $official, $percent);

    I know this concept from Perl DBI, but in PHP I haven't seen anyone (phpBB, ...) using bind_param. Why is this? Performance? Keeping the code short and simple?

    As for general webserver security: use PHP and perl as cgi, use suEXEC, run the webserver as nobody/www, put the users into chroot jails, but by all means, don't use PHP safe_mode On.

  3. Re:No. by mfh · · Score: 5, Informative
    > Always check user input as much as is possible. Probably at least two-thirds of my programming is input data verification.

    Good. You are off to the right start, but with better function programming, you will find yourself writing more feature code than purification code.

    Things to look for:
    • Push 99% of all expected/selectable data into tables with a record_id, so you can easily purify the incoming data:

      function npurify(&$text){
      if(!is_numeric($text)) $text = 1;
      }

      Protects against SELECT SQL injection attacks.

    • Snuff out > and < chars so that they can't contain the Script HTML tag when purifying data. Replacing these characters with their html entities usually works; ie:
      > becomes &gt;
      < becomes &lt;
    • Convert data in your database to base_64 and gzdeflate it:
      $data = base64_encode(gzdeflate($data));
      This will prevent the problems with escaping quotes and apostrophes for SQL, and it will kill any SQL injections in your data.
    • Use better logic for testing incoming data;
      if($this) {perform action}... will limit your chances of having to cope with scipt injections because you are only testing for the existence of a condition, and not the value of the data.
    • Run bitchecking against acceptable alphabets for purification of character values. Gauge to have good CPU usage of this sort of thing.

      // blanks out unaccepted characters
      $alphabet = '`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz01234567890~!@#$%^&*()_+=-,.<>?/|;:\'"'.chr(92 ).chr(10);
      $sizestr = strlen($text);
      $sizestr--;
      for($i = 0; $i <= $sizestr; $i++) {
      if(strstr($alphabet, $text[$i])) {
      continue;
      }else{
      $text[$i] = ' ';
      }
      }

    • Code a good link converter, so you don't have to accept HTML in posts, and you don't need to accept any HTML.
    • There are likely more, but these are the big ones.

    > Always escape text which is going into an SQL query

    I prefer to write my own SQL text, based on input values. That way you are never using data submitted for the SQL query. The only time they would really submit values would be when they are sending in a username and password, but in that case, you should be extremely stringent in purification by only accepting alphanumeric usernames and passwords (ie: run the alphabet function above, but erase all non-alphanumeric chars from the $ALPHABET var).

    > Use htmlspecialchars() on any text that's being output, to stop users putting rogue HTML

    htmlspecialchars() doesn't always work. I prefer using the example above, by limiting the characters allowed and disallowing HTML in the form of post body/subject data. Converting everything to base64 will make it nearly impossible to script attack the database, too.

    > Put database usernames, passwords, pathnames and other similarly important but site-specific data in a define()

    I disagree, because I use the $_SESSION array instead, which can not be changed by a user if the session cookie is server-side. Sessions can be scooped by sniffers, but that can be managed by your host's security, to prevent it. Certainly change the locale for session data from /tmp/, because that narrows down hack attempts, making it all the more harder to compromise the system.

    > Never include() or require() something that isn't a hard-coded string

    To me, this isn't totally required if you have suitable purification, but that extra bit of paranoia is welcomed, because it shows true fear and that is acceptable in any kind of programming. That sort of humility is welcomed because it demonstrates a compassion for the task at hand.

    > Be hugely care

    --
    The dangers of knowledge trigger emotional distress in human beings.