SitePoint Sponsor

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 25 of 60
  1. #1
    SitePoint Zealot
    Join Date
    Jan 2010
    Posts
    153
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)

    code layout and variable questions

    Hello.

    I have a quick question regarding php code layout and also variables.

    Does it make any difference whatsoever if I choose to lay out my code in sections like this? Note that this is just some example random code.

    PHP Code:
    <?php
    session_start
    ();
    if (isset(
    $_SESSION['username'])) {
    $username htmlspecialchars($_SESSION['username']);
    }
    ?>
    <?php
    require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/connection.php';
    some code here etc
    ?>
    <?php
    echo '$username';
    ?>
    Do the php tags after the first set make no difference at all, and are purely an aesthetic choice to clump together certain parts of the code if I chose to do so?

    Would the connection.php still be 'set' in the later php tag sets or would I have to call it for each? Somehow, I doubt that.

    Also, regarding variables. If I use, like in the above example, htmlspecialchars on the $username variable.. whenever I use the $username variable later in my code, I can just use it as $username, and not have to 're-do' htmlspecialchars, correct? Once it is set, it is set until I change it in that particular page. Even if it were done like this:

    PHP Code:
    <?php
    session_start
    ();
    if (isset(
    $_SESSION['username'])) {
    $username htmlspecialchars($_SESSION['username']);
    }
    ?>
    <?php
    include hiuser.php
    ?>
    <?php 
    // this is hiuser.php
    echo '$username';
    ?>
    Thank you for your input, php masters of sitepoint.

  2. #2
    SitePoint Zealot Cute Tink's Avatar
    Join Date
    Apr 2009
    Posts
    152
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    My amateur opinion on your questions:

    1. Do the php tags after the first set make no difference at all, and are purely an aesthetic choice to clump together certain parts of the code if I chose to do so?

    You can do that, but there might be some efficiency issues from doing that. I never open and close like that. If you want to separate your code sections, perhaps includes would be a better choice, but that might have efficiency issues as well. Typically I separate sections with white space, i.e.:

    PHP Code:
    <?php

    session_start
    ();

    if (isset(
    $_SESSION['username'])) {

       
    $username htmlspecialchars($_SESSION['username']);

    }

    require_once 
    $_SERVER['DOCUMENT_ROOT'] . '/includes/connection.php';

    some code here etc

    echo $username;

    ?>
    Also note, as a general readability practice, when you have a block of code inside something like an if or while statement, you should indent a few characters to help identify what part of the code is inside that if or while statement.

    2. Would the connection.php still be 'set' in the later php tag sets or would I have to call it for each? Somehow, I doubt that.

    It would still be set. Closing the php tags doesn't destroy any variables or connections.

    3. If I use, like in the above example, htmlspecialchars on the $username variable.. whenever I use the $username variable later in my code, I can just use it as $username, and not have to 're-do' htmlspecialchars, correct?

    That much is true. However, you should know that php doesn't parse variables within single quotes. If you want, for some reason, to enclose your variables within quotes, use double quotes. If you prefer single quotes to enclose output, then you need to break them for variables, i.e.:

    Works:
    echo 'Hello there ' . $username;
    echo "Hello there $username";

    Doesn't work:

    echo 'Hello there $username';

  3. #3
    SitePoint Zealot Cute Tink's Avatar
    Join Date
    Apr 2009
    Posts
    152
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    For some reason, I cannot edit. I seem to be wrong about efficiency. It doesn't seem to impact the speed of the script to open and close php. However, it may make it harder to read or find a missing closing brace.

  4. #4
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    The usual reason to use multiple blocks is to permit the use of html between them. Trivial example:
    PHP Code:
    <?php 
    session_start
    (); 
    if (isset(
    $_SESSION['username'])) { 
    $username htmlspecialchars($_SESSION['username']); 

    ?> 
    <html>
    <head>
    <?php 
    require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/connection.php'
    some code here etc 
    ?>
     
    </head>
    <body>
    <?php 
    echo '$username'
    ?>
    </body>
    Your question about escaping a variable is a harder one to explain though.

    htmspecialchars() is a means of 'escaping' (protecting) a variable destined for display in and amongst html on a webpage.

    mysql_real_escape_string() or using PDO/Mysqli prepared statements is a means of escaping a variable destined for storage in a mysql database.

    If you take the following programme flow:

    a) get a variable from a user
    b) display it to a the user in a webpage
    c) store it in a database

    If you escape it at a) and then re-escape it AGAIN at c) you will end up with data in your database which will not match your expectations and can be the cause of very subtle bugs.

    Moving away from the trivial example, lets say you are looking at a variable on a 200 line script which you have not worked on for a few months now.
    PHP Code:
    $username 
    Now ask yourself, has that already been escaped?

    If you insist upon pre-escaping variables maybe in an effort to save time, then at least name them:
    PHP Code:
    $escaped_username 
    Eugh!

    So my answer is no, don't do that as a knee-jerk reaction, it will cause you problems later down the road. Generally escape data as you display it so that your code is implicit.

    If you are reading from a database, and you know that all the variables are to be output onto a page, then yes, consider doing it.

  5. #5
    SitePoint Zealot
    Join Date
    Jan 2010
    Posts
    153
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Ok thank you Cute-Tink and Cups. That really clears things up for me.

    Cups, I will not pre-escape variables like that from now on. What you said makes far more sense to me, but I have one question regarding your theoretical situation of:

    Quote Originally Posted by Cups View Post
    a) get a variable from a user
    b) display it to a the user in a webpage
    c) store it in a database

    If you escape it at a) and then re-escape it AGAIN at c) you will end up with data in your database which will not match your expectations and can be the cause of very subtle bugs.
    I think I understand this, but let me come up with a slightly more detailed example to make sure that I do understand, and/or get some further tips.

    Let's say I have a form that will insert some data into the database. I have dumbed my example code down to shorten my example.

    PHP Code:
    <?php
    session_start
    (); 
    if (isset(
    $_SESSION['username'])) {
         
    $username $_SESSION['username']; // A
    }
    if (isset(
    $_POST['form_submit'])) {
         
    $username mysqli_real_escape_string($link$username); // C
         
    "INSERT INTO database WHERE username = '$username'";
    }
    ?>
    <HTML begins>
    <?php
         
    echo "Welcome htmlspecialchars($username)"// B
    ?>
    <html form goes here with 'form_submit' button>
    </HTML ends>
    Sorry about the purposely dumb code, but the point of it is so that I can understand your ABC example. Would my example cause problems:

    I am not escaping at 'A', but am escaping with htmlspecialchars at 'B' when I display the username in a welcome message, and then escaping at 'C' with mysqli_real_escape_string if/when the user submits the form.

  6. #6
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    You nearly got it right mate.
    PHP Code:
    if (isset($_POST['form_submit'])) {
    // if you are using mysqli - but then again you should
    // ideally be using prepared statements which do the escaping
    // for you automatically
          
    "INSERT INTO database (username) values ( '" mysqli_real_escape_string($username) ."');  //C

    Also, bear in mind this scenario:
    PHP Code:
    <?php

    // you fetch something from your mysql table
    // but you are not sure where it came from, all 
    // you know (trust) is that you did escape it ready
    // for storing as mysql data

    // "select username from mydatabase WHERE id= 1";
    // mysql_fetch_array etc

    }
    ?>
    <HTML begins>
    <?php
         
    echo "Welcome htmlspecialchars("$row[0]['username'] .")"// B
    ?>
    </HTML ends>
    Filter Input Escape Output is the rule (FIEO).

    You may have protected mysql from sql injection attacks when you saved the data, but now you need to protect users of your html from XSS attacks as you display it. (protect = escape).

    I wish I'd been bright enough to ask questions such as this when starting out.

  7. #7
    SitePoint Zealot
    Join Date
    Jan 2010
    Posts
    153
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    So:
    PHP Code:
    <?php
    session_start
    (); 
    if (isset(
    $_SESSION['username'])) {
         
    $username $_SESSION['username'];
    }
    if (isset(
    $_POST['form_submit'])) {
         
    "INSERT INTO database (one, two, three) values ('one', 'two', 'three') WHERE username = ( '" mysqli_real_escape_string($username) ."');
    }
    ?>
    <HTML begins>
    <?php
         echo "
    Welcome htmlspecialchars($username)";
    ?>
    <html form goes here with 'form_submit' button>
    </HTML ends>
    Would be right for the first example?

    But if I was also inserting other data generated by the form only (had not been previously set or escaped), it would be ok to do this?

    PHP Code:
    $variable1 mysqli_real_escape_string($link$variable);
    $variable2 mysqli_real_escape_string($link$variable);
    $variable3 mysqli_real_escape_string($link$variable);
    "INSERT INTO database (one, two, three) values ('$variable1', '$variable2', '$variable3') WHERE username = ( '" mysqli_real_escape_string($username) ."'); 
    Finally, let me ask a really "Hi, I'm a newbie" question too. What is the difference between doing (assuming $username had been htmlspecialchar'd for output like in my first example). Just so I understand the changes I am making.

    PHP Code:
    $username mysqli_real_escape_string($link$username);
    "INSERT INTO database (one, two, three) values ('one', 'two', 'three') WHERE username = '$username'"); 
    and

    PHP Code:
    "INSERT INTO database (one, two, three) values ('one', 'two', 'three') WHERE username = ( '" mysqli_real_escape_string($username) ."'); 
    I hope that post wasn't too much of a mess.

  8. #8
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by oknow View Post
    Would be right for the first example?
    Exactly right.

    Sorry, my mistake, I am getting confused with mysql_real_escape_string() - I must admit I am not familiar with mysqli, having moved directly to using PDO when PHP5.1 came out. Maybe someone else can help you with that. I hope I have not lead you astray on that ...

  9. #9
    SitePoint Zealot
    Join Date
    Jan 2010
    Posts
    153
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Not a problem Cups, you have been a truly excellent help.

    Which part do I still need to confirm, though? So that I know where I'm up to.

  10. #10
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    Judging by what I read in the manual about mysqli function (which I am not conversant with)

    This code:
    PHP Code:
    $username mysqli_real_escape_string($link$username);
    "INSERT INTO database (one, two, three) values ('one', 'two', 'three') WHERE username = '$username'"); 
    Is correct,

    whereas this code:
    PHP Code:
    "INSERT INTO database (one, two, three) 
    values ('one', 'two', 'three') 
    WHERE username = ( '" 
    mysqli_real_escape_string($username) ."'); 
    Is incorrect (or if the i was taken off, it would be true for plain mysql_* use).

    Sorry if I have confused you on this score.

  11. #11
    SitePoint Zealot
    Join Date
    Jan 2010
    Posts
    153
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Thanks for taking the time to help me out, and to clarify, Cups. I appreciate it.

    So basically I'm doing everything right? And it does not matter to switch between different escape methods on the same variable throughout my script, as long as I always use the right one for the right job, like in this example:

    PHP Code:
    <?php
    session_start
    (); 
    if (isset(
    $_SESSION['username'])) {
         
    $username $_SESSION['username'];
    }
    if (isset(
    $_POST['form_submit'])) {
         
    $username mysqli_real_escape_string($link$username); // mysqli_real_escape_string for input into database
         
    "INSERT INTO database WHERE username = '$username'";
    }
    ?>
    <HTML begins>
    <?php
         
    echo "Welcome htmlspecialchars($username)"// htmlspecialchars for output to the page
    ?>
    <html form goes here with 'form_submit' button>
    </HTML ends>

  12. #12
    SitePoint Zealot Zurev's Avatar
    Join Date
    Feb 2009
    Posts
    171
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Am I the only one who noticed this bit:
    PHP Code:
    <?php 
         
    echo "Welcome htmlspecialchars($username)"// htmlspecialchars for output to the page 
    ?>
    It won't call htmlspecialchars, it'd need to be:
    PHP Code:
    echo "Welcome ".htmlspecialchars($username);
    // Or if you wanted to continue the string..
    echo "Welcome ".htmlspecialchars($username).", how are you today?"

  13. #13
    SitePoint Zealot
    Join Date
    Jan 2010
    Posts
    153
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Oops, thank you Zurev!

    I've actually been doing it like this:
    PHP Code:
    <?php
         
    echo 'Welcome';
         echo 
    htmlspecialchars($username);
         echo 
    '.';
    ?>
    So I would need to change line 2 to this?
    PHP Code:
    echo .htmlspecialchars($username).; 

  14. #14
    SitePoint Zealot Zurev's Avatar
    Join Date
    Feb 2009
    Posts
    171
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No, line 2 is fine that way.

  15. #15
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by oknow View Post
    Oops, thank you Zurev!

    I've actually been doing it like this:
    PHP Code:
    <?php
         
    echo 'Welcome';
         echo 
    htmlspecialchars($username);
         echo 
    '.';
    ?>
    So I would need to change line 2 to this?
    PHP Code:
    echo .htmlspecialchars($username).; 
    That last code example won't work, because PHP will think that you've missed out something for the full steps to concatenate with.

    You can use either the first example from above, or combine it in to one statement with:

    PHP Code:
    echo 'Welcome' htmlspecialchars($username) . '.'
    Or if you prefer, you can have the one statement spread across multiple lines:

    PHP Code:
    echo 'Welcome'
        
    htmlspecialchars($username)
        . 
    '.'

    PHP Code:
    echo 'Welcome' .
        
    htmlspecialchars($username) .
        
    '.'
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  16. #16
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    With procedural mysqli, I prefer to not have the variable embedded within the string, which PHP then has to decode:

    Code php:
    $username = mysqli_real_escape_string($link, $username);
    $result = mysqli_query("INSERT INTO database WHERE username = '$username'");

    Instead, I prefer to concatenate the variable to the string, so that it's visually easier to see what's going on:


    Code php:
    $username = mysqli_real_escape_string($link, $username);
    $result = mysqli_query('INSERT INTO database WHERE username = "' . $username . '"');

    I might even go so far as to use sprintf:

    Code php:
    $sql = sprintf(
        'INSERT INTO database WHERE username = "%s"',
        mysqli_real_escape_string($link, $username)
    );
    $result = mysqli_query($sql);

    However, if you're going to go that far, you might as well use prepared statements instead.
    All escaping issues are then automatically handled when you bind a parameter to the statement.

    Code php:
    if ($stmt = mysqli_prepare($link, 'INSERT INTO database WHERE username = "?"')) {
        mysqli_stmt_bind_param($stmt, "s", $username);
        mysqli_stmt_execute($stmt);
        mysqli_stmt_bind_result($stmt, $result);
        mysqli_stmt_fetch($stmt);
    }
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  17. #17
    SitePoint Zealot
    Join Date
    Jan 2010
    Posts
    153
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by paul_wilkins View Post
    With procedural mysqli, I prefer to not have the variable embedded within the string, which PHP then has to decode:

    Code php:
    $username = mysqli_real_escape_string($link, $username);
    $result = mysqli_query("INSERT INTO database WHERE username = '$username'");

    Instead, I prefer to concatenate the variable to the string, so that it's visually easier to see what's going on:


    Code php:
    $username = mysqli_real_escape_string($link, $username);
    $result = mysqli_query('INSERT INTO database WHERE username = "' . $username . '"');
    Thank you Paul.

    I'll be truthful, I don't know the difference there due to me never having used concatenation much, or like that specifically, but I am reading about it right now.

    Does anyone have any input on my "escaping-variable-different-ways-throughout-code" question (post #11)? Once I confirm that one way or another, I think my lessons for today are complete!

    You are all a great help.

  18. #18
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by oknow View Post
    Does anyone have any input on my "escaping-variable-different-ways-throughout-code" question (post #11)?
    Last year I summarised input/sanitize/output/escape issues in this Handling Input and Output post in the coding tips sticky thread.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  19. #19
    SitePoint Zealot
    Join Date
    Jan 2010
    Posts
    153
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Thanks again Paul. Reading now.

    Reading this thread over a few times, I'm actually thinking about reworking a lot of my code.

    I might completely remove all entries of the following at the top of all of my pages:

    PHP Code:
    if (isset($_SESSION['username']) && (isset($_SESSION['userid'])) {
         
    $username $_SESSION['username'];
         
    $user_id $_SESSION['user_id'];

    and just use $_SESSION['username/user_id'] whenever I need to input or output the username/user_id.

    I figure, why bother setting them as variables unless I need them to be, ie to prepare them for database insertion, for example:

    PHP Code:
    $username mysqli_real_escape_string($link$_SESSION['username']);
    $result mysqli_query("INSERT INTO database (one, two, three) VALUES ('1', '2', '3') WHERE username = '$username'"); 
    But for any stuff that is just output on my page (welcome messages, menu links, etc) I will just do this:

    PHP Code:
    echo 'Welcome' htmlspecialchars($_SESSION['username']) . '.'
    PHP Code:
    // a user navigation link
    <?php echo '<a href="blah.php?user=' htmlspecialchars($_SESSION['username']) . '">' ?>Blah</a>
    Sorry for rambling on and on, but this thread got me thinking about how I was writing my code in certain ways.. and it seems a bit pointless/redundant to do it the way I am currently doing it. Especially if I am going to be re-setting $username throughout my code with different escape functions anyway, why bother setting it at a point where I'm not even using it yet. Unless there is any reason I shouldn't use the session variables straight up like that?

  20. #20
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by oknow View Post
    Unless there is any reason I shouldn't use the session variables straight up like that?
    The main reason is in terms of encapsulation.

    It's best if you don't have global variables scattered all throughout your code. Not only is it difficult to keep track of what you've used and where, it also becomes a real pain in the butt if you have to change one of those global variable names.

    See for example this article about PHP globals in functions

    To help resolve those issues, assign the global variable to a local variable so that there are less instances of global variables scattered about the place.


    Another reason is something called code smells (wikipedia), which are indications of deeper problems. There's quite a comprehensive list of them over at the code smells (Coding Horror) page.

    In this case, superglobal variables should not be trusted because you cannot guarantee what they contain. Yes it's possible to sanitize and validate them and rewrite the clean version back in to the superglobal, but then when viewing the code later, on you won't know if the superglobal is clean or not.

    Due to the dangerous potential of superglobals, any time you see them in your code you should ensure that they are cleaned and assigned to local variables, and those problems go away. If they appear without being appropriately handled, that should fire off some warning bells to ensure that they are.

    Appropriate handling of them with PHP 5.2 or better

    Code php:
    $username = filter_input(INPUT_GET, 'username', FILTER_SANITIZE_STRING);

    or:

    Code php:
    $username = filter_var($_SESSION['username'], FILTER_SANITIZE_STRING);

    And before PHP 5.2

    Code php:
    $username = '';
    if (isset($_SESSION['username'])) {
        $username = $_SESSION['username'];
    }

    And if your server still has magic quotes enabled, you should follow the advice from this Disabling Magic Quotes page.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  21. #21
    SitePoint Zealot
    Join Date
    Jan 2010
    Posts
    153
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Understood. Aborting that change and making sure everything that I do have is handled as stated. Thank you again!

  22. #22
    SitePoint Zealot
    Join Date
    Jan 2010
    Posts
    153
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Final two questions, I swear! I want to understand, not just 'do' it.

    1 - FILTER_SANITIZE_STRING is a combination of strip_tags and htmlspecialchars?

    2 - Since I am going to be setting my session variables at the top of my page like so:

    PHP Code:
    if (isset($_SESSION['username'])) {
         
    $username filter_var($_SESSION['username'], FILTER_SANITIZE_STRING);

    I can use that directly in my navigation links (in the same page) as just plain echo $username, no need to escape, because it is already escaped every time the page is loaded?

    Unless someone posts the form that is on my page, then $username = mysqli_real_escape_string($link, $username); will be set for the database query, then when the page reloads, my filter_var is applied again.. right ?

    I am assuming that as long as the form query isn't sent that $username will always be safe for html output in the page whenever the page loads, since it is set at the top. And it will only change to be safe for database insertion when it is called to be (eg, upon someone pressing the form submit button).

    I think I understand. Gulp. I hope so! I will be fine after these two questions I promise!

  23. #23
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by oknow View Post
    Final two questions, I swear! I want to understand, not just 'do' it.

    1 - FILTER_SANITIZE_STRING is a combination of strip_tags and htmlspecialchars?
    Here are the types of filters. The sanitize filters is where you find FILTER_SANITIZE_STRING, where it says:
    Strip tags, optionally strip or encode special characters.

    The optional flags on the page can be specified in the third parameter as an associated array. You can see examples of it on the filter_var and filter_input

    Quote Originally Posted by oknow View Post
    2 - Since I am going to be setting my session variables at the top of my page [...] I can use that directly in my navigation links (in the same page) as just plain echo $username, no need to escape, because it is already escaped every time the page is loaded?
    It might be escaped based on when you set the value earlier, but it's a bad practice to escape anything before you actually need to. Why? Because of the danger of double-escaping or triple escaping. Have you ever seen "O\\\'Brian" as a database value?

    You should not escape when values come in to your code.
    Sanitize them, validate them even, but don't escape them. Why? What happens when you want to combine an escaped string with an unescaped one? That just leads to problems.

    Also, escaping is different depending on where the value will go. Is it going to be an SQL statement, an HTML piece of text, some XML, a URL, or destined for email?

    Values throughout your code should be unescaped up to and until they leave your code, as output to their intended destination. Only at the last possible moment should they then be escaped, as is appropriate for where they're going to go.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  24. #24
    SitePoint Zealot
    Join Date
    Jan 2010
    Posts
    153
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Ok, thank you. That really makes sense. I think I have been double escaping a few things and you have helped me to see that.

    I have to sleep now, but tomorrow I might post an example to show what I've been doing wrong, and then post my 'fixed' version of it to make sure that I know how to solve this once and for all.

    Thanks again.

  25. #25
    SitePoint Zealot
    Join Date
    Jan 2010
    Posts
    153
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Ok, hopefully I can clear this up today. I thought I was escaping everything the right way, so let's make sure I learn how before I continue.

    First let me post some example code and then I will ask questions based on that. I had pretty much every page on my site done with this type of escape routine:

    PHP Code:
    <?php
    session_start
    ();
    if (!isset(
    $_SESSION['username'])) {
            
    header('Location: /website/login.php');
    }
    if (isset(
    $_SESSION['username']) && isset($_SESSION['user_id'])) {
        
    $username =htmlspecialchars($_SESSION['username']);
        
    $user_id htmlspecialchars($_SESSION['user_id']);
    }
    require_once 
    $_SERVER['DOCUMENT_ROOT'] . '/includes/database_connection.php';
    require_once 
    $_SERVER['DOCUMENT_ROOT'] . '/includes/functions.php';
    if(isset(
    $_POST['item_submit'])) {
        
    $username mysqli_real_escape_string($link$_SESSION['username']);
        
    $user_id mysqli_real_escape_string($link$_SESSION['user_id']);
        
    $item_name mysqli_real_escape_string($link$_POST['item_name']);
        
    $sql mysqli_query($link"INSERT INTO items (user_id, item_name) VALUES ('$user_id', '$item_name')");
            if (!
    $sql) {
                
    $error 'DATABASE ERROR.';
                include 
    'error.php';
                exit();
            }
            else
            
    header('Location: /website/items.php?user=' htmlspecialchars($username) . '');
    }
    ?>
    <html>
        <ul>
            <li><?php echo '<a href="navigation_link_one.php?user=' htmlspecialchars($username) . '">' ?>navigation_link_one</a></li>
            <li><?php echo '<a href="navigation_link_two.php?user=' htmlspecialchars($username) . '">' ?>navigation_link_two</a></li>
        </ul>
                <form action="add_item.php" method="post">
                
                    <label for="itemname">Item Name:</Label>
                    <input type="textbox" name="item_name"/>
                    
                    <input type="submit" name="item_submit" value="Add Item"/>
                </form>
    </html>
    There are probably some code mistakes as I typed this up purely for examples sake, based on what I have been doing throughout my website. I removed a lot of tags that don't need to be seen etc.

    Hopefully this will teach me a great lesson in how to set up my variables/escaping properly.

    Now let me break break it down into sections.

    I'm assuming, that since the $username variable is automatically htmlspecialchar'd on every page due to my navigation code, that when the user submits a form and $username gets mysqli_special_escape_string put on it - THAT is 'double escaping'?

    Not to mention that since $username is automatically done on every page load in the navigation, it gets done a THIRD time when the user submits an item and they are redirected:

    PHP Code:
    header('Location: /website/items.php?user=' htmlspecialchars($username) . ''); 
    Is that assumption correct?

    All the above said, I should (?) be using filter_var on the following instead anyway. But that would still leave me with some 'double escaping' in the rest of the code, if my above assumptions are correct. I am also thinking that filter_var is for sanitizing, not escaping for direct output, and I could be wrong there too.
    PHP Code:
    if (isset($_SESSION['username']) && isset($_SESSION['user_id'])) {
        
    $username filter_var($_SESSION['username'], FILTER_SANITIZE_STRING);
        
    $user_id filter_var($_SESSION['user_id'], FILTER_SANITIZE_STRING);

    Sorry if that is all annoying to read, I just crawled out of bed after a long night of no sleep (baby).


Bookmarks

Posting Permissions

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