Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 9 of 9
  1. #1
    New Coder
    Join Date
    Nov 2012
    Location
    United Kingdom
    Posts
    39
    Thanks
    3
    Thanked 1 Time in 1 Post

    filter & cleaning strings

    Hi,

    I've just started to use PHP, and what's the best way to insert clean data into a database....

    PHP Code:
    $username filter$_POST['username'] );
    mysqli_query($dblink,"INSERT INTO cms_users VALUES (NULL,'".$username."')"); 
    Here's what i have for inserting into database:
    PHP Code:
    function filter$string ) {
    return 
    mysqli_real_escape_stringstripslashestrim$string ) ) );

    And here's what i have to echo:
    PHP Code:
    public function clean$string$html true$nl2br false ) {
    $string stripslashestrim$string ) );
    if( 
    $html ) { $string htmlentities$string ); }
    if( 
    $nl2br ) { $string nl2br$string ); }
    return 
    $string;

    Is there anyway of improving this?

  • #2
    Master Coder felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    6,642
    Thanks
    0
    Thanked 649 Times in 639 Posts
    Use separate prepare and bind statements instead of query - that way the data is kept separate from the SQL

    Also validate it when it is first input as you move it from $_POST so as to make sure that the data looks reasonable and isn't junk.
    Stephen
    Learn Modern JavaScript - http://javascriptexample.net/
    Helping others to solve their computer problem at http://www.felgall.com/

    Don't forget to start your JavaScript code with "use strict"; which makes it easier to find errors in your code.

  • #3
    New Coder
    Join Date
    Nov 2012
    Location
    United Kingdom
    Posts
    39
    Thanks
    3
    Thanked 1 Time in 1 Post
    Quote Originally Posted by felgall View Post
    Use separate prepare and bind statements instead of query - that way the data is kept separate from the SQL

    Also validate it when it is first input as you move it from $_POST so as to make sure that the data looks reasonable and isn't junk.
    I know all that i just chucked it together to find out if there's a better way of cleaning output to stop injection

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    Yeah, as mentioned the prepared statements are a much better option. Since you are already using MySQLi, you can write the prepared statements with little changes.
    Lets do a quick example without functions of what you would do with just the query:
    PHP Code:
    if (ini_get('magic_quotes_gpc'))
    {
        
    $_POST['username'] = stripslashes($_POST['username']);
    }
    $username mysqli_real_escape_string($_POST['username']);
    mysqli_query($dblink,"INSERT INTO cms_users VALUES (NULL,'".$username."')"); 
    And the same using a bind (I'll use OO and procedural here):
    PHP Code:
    if (ini_get('magic_quotes_gpc'))
    {
        
    $_POST['username'] = stripslashes($_POST['username']);
    }

    $username $_POST['username']; // do whatever validation you need to do.

    // Always need the check for magic_quotes until 5.4 is mainstream minimum version
    if ($stmt mysqli_prepare($dblink"INSERT INTO cms_users VALUES (null, ?)"))
    {
        
    mysqli_stmt_bind_param($stmt's'$username);
        
    mysqli_stmt_execute($stmt);
        
    mysqli_stmt_close($stmt);
    }

    // OO
    if ($stmt $dblink->prepare("INSERT INTO cms_users VALUES (null, ?)"))
    {
        
    $stmt->bind_param('s'$username);
        
    $stmt->execute();
        
    $stmt->close();

    Don't do this:
    PHP Code:
    if( $html ) { $string htmlentities$string ); }
    if( 
    $nl2br ) { $string nl2br$string ); } 
    That indicates you are inserting htmlentites and line breaks into your storage. Use htmlentities during display to parse any HTML if you allow it in, and nl2br if you require non-breaking spaces. Don't save the data like this, keep it in its pure form. If you are not wanting HTML at all, you can use strip_tags.

  • #5
    New Coder
    Join Date
    Nov 2012
    Location
    United Kingdom
    Posts
    39
    Thanks
    3
    Thanked 1 Time in 1 Post
    Quote Originally Posted by Fou-Lu View Post
    Yeah, as mentioned the prepared statements are a much better option. Since you are already using MySQLi, you can write the prepared statements with little changes.
    Lets do a quick example without functions of what you would do with just the query:
    PHP Code:
    if (ini_get('magic_quotes_gpc'))
    {
        
    $_POST['username'] = stripslashes($_POST['username']);
    }
    $username mysqli_real_escape_string($_POST['username']);
    mysqli_query($dblink,"INSERT INTO cms_users VALUES (NULL,'".$username."')"); 
    And the same using a bind (I'll use OO and procedural here):
    PHP Code:
    if (ini_get('magic_quotes_gpc'))
    {
        
    $_POST['username'] = stripslashes($_POST['username']);
    }

    $username $_POST['username']; // do whatever validation you need to do.

    // Always need the check for magic_quotes until 5.4 is mainstream minimum version
    if ($stmt mysqli_prepare($dblink"INSERT INTO cms_users VALUES (null, ?)"))
    {
        
    mysqli_stmt_bind_param($stmt's'$username);
        
    mysqli_stmt_execute($stmt);
        
    mysqli_stmt_close($stmt);
    }

    // OO
    if ($stmt $dblink->prepare("INSERT INTO cms_users VALUES (null, ?)"))
    {
        
    $stmt->bind_param('s'$username);
        
    $stmt->execute();
        
    $stmt->close();

    Don't do this:
    PHP Code:
    if( $html ) { $string htmlentities$string ); }
    if( 
    $nl2br ) { $string nl2br$string ); } 
    That indicates you are inserting htmlentites and line breaks into your storage. Use htmlentities during display to parse any HTML if you allow it in, and nl2br if you require non-breaking spaces. Don't save the data like this, keep it in its pure form. If you are not wanting HTML at all, you can use strip_tags.
    Not to insert i'm using filter() and to output i'm using clean()

  • #6
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    Oh then that's okay yeah. Except for the stripslashes, that should be dealt with before it hits storage (its only an issue if magic_quotes_gpc is running and you execute an escape sequence on the inserted data). Magic quotes runtime can be disabled at runtime, so before you select simply issue an ini_set('magic_quotes_runtime', 0); just in case its enabled (also gone as of 5.4). Its corrupted the data if you allow slashes where the do not belong. IE, if I specify a filepath of \\machine\c$, then that would be \\\\machine\\c$ which isn't what I asked for. Strip them out, then sanitize (or don't sanitize and issue a bind). MySQL itself will receive \\\\machine\\c$ as its input type (from the escape string call), but that is to perform the proper escapes to the data itself whilst inserting. If I use both magic quotes and escape, I'd end up with \\\\\\\\machine\\\\c$ as its going in, so that would give me \\\\machine\\c$ once inserted into storage. If that all makes sense. I'm *quite* sure that addslashes on top of addslashes will escape regardless of escaped status, but running in writecodeonline.com issues a \\machine\\c$ on a single addslashes where I'd expect that it should be \\\\machine\\c$ (and codepad is down :/).
    Also, checking on the api, get_magic_quotes_gpc() function does not appear to deprecate. Which is perfect; that is a better option IMO than ini_get. ini_get if overridden during .htaccess level using 'on' instead of 1 or true will result in ini_get failing to provide the proper information on the magic_quotes_gpc. I swapped to using ini_get awhile ago since I wasn't sure what zend was planning when it came to removing magic_quotes (which I actually thought wouldn't happen until 6.0, but here we are).

  • #7
    New Coder
    Join Date
    Nov 2012
    Location
    United Kingdom
    Posts
    39
    Thanks
    3
    Thanked 1 Time in 1 Post
    Quote Originally Posted by Fou-Lu View Post
    Oh then that's okay yeah. Except for the stripslashes, that should be dealt with before it hits storage (its only an issue if magic_quotes_gpc is running and you execute an escape sequence on the inserted data). Magic quotes runtime can be disabled at runtime, so before you select simply issue an ini_set('magic_quotes_runtime', 0); just in case its enabled (also gone as of 5.4). Its corrupted the data if you allow slashes where the do not belong. IE, if I specify a filepath of \\machine\c$, then that would be \\\\machine\\c$ which isn't what I asked for. Strip them out, then sanitize (or don't sanitize and issue a bind). MySQL itself will receive \\\\machine\\c$ as its input type (from the escape string call), but that is to perform the proper escapes to the data itself whilst inserting. If I use both magic quotes and escape, I'd end up with \\\\\\\\machine\\\\c$ as its going in, so that would give me \\\\machine\\c$ once inserted into storage. If that all makes sense. I'm *quite* sure that addslashes on top of addslashes will escape regardless of escaped status, but running in writecodeonline.com issues a \\machine\\c$ on a single addslashes where I'd expect that it should be \\\\machine\\c$ (and codepad is down :/).
    Also, checking on the api, get_magic_quotes_gpc() function does not appear to deprecate. Which is perfect; that is a better option IMO than ini_get. ini_get if overridden during .htaccess level using 'on' instead of 1 or true will result in ini_get failing to provide the proper information on the magic_quotes_gpc. I swapped to using ini_get awhile ago since I wasn't sure what zend was planning when it came to removing magic_quotes (which I actually thought wouldn't happen until 6.0, but here we are).
    So i could remove stripslashes() as long as i've disabled;
    PHP Code:
    ini_set"magic_quotes_runtime"); 
    If so then i've got it thanks.

    PHP Code:
    public function filter$string ) {

    global 
    $db;

    return 
    mysqli_real_escape_string$db->connectionstripslashestrim$string ) ) );



  • #8
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    That's right. Since magic_quotes_runtime is also gone, its easier to simply disable that and go from there. Ini is nice since if you set an invalid value (such as magic_quotes_runtime in 5.4+), it doesn't actually cause an error.

    Don't do this: global $db; . Globalization is problematic to debug, especially since it will never trigger an error should the variable not be declared. Pass $db to the function as an argument instead. If you choose OO approach, you can signature the datatype with public function filter($string, MySQLi $db);. Reserve global for only when you cannot alter the signature of the function.

  • #9
    New Coder
    Join Date
    Nov 2012
    Location
    United Kingdom
    Posts
    39
    Thanks
    3
    Thanked 1 Time in 1 Post
    Quote Originally Posted by Fou-Lu View Post
    That's right. Since magic_quotes_runtime is also gone, its easier to simply disable that and go from there. Ini is nice since if you set an invalid value (such as magic_quotes_runtime in 5.4+), it doesn't actually cause an error.

    Don't do this: global $db; . Globalization is problematic to debug, especially since it will never trigger an error should the variable not be declared. Pass $db to the function as an argument instead. If you choose OO approach, you can signature the datatype with public function filter($string, MySQLi $db);. Reserve global for only when you cannot alter the signature of the function.
    Ok, thankyou, i have a better understanding of this now thanks.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •