Jump to content

davidannis

Members
  • Posts

    627
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by davidannis

  1. Try something like this:

    //open db here
    $date = date('Y-m-d');
    date_sub($date, date_interval_create_from_date_string('14 days'));
    $query="SELECT * FROM mytable WHERE sent=0 and date<='$date'";
    $result = mysqli_query($link, $query);
    while ($row=mysqli_fetch_assoc($result)){
    //send email
    }
    
  2. A whitelist of IP addresses would be reasonable, but I'd time them out so an IP that got on the list was not there forever. You could require a cookie on the browser that was tied to an IP address storeed on the server. If the user logs in with the same browser and is at the same IP he gets in with just a password, otherwise he gets challenge number 2. Folks with a DHCP server may end up being challenged every time even if they are sitting in the same place though usually your server will see their firewall/router's IP.

     

    A personal rant about secure passwords. I understand the desire to have a long, hard to crack, changing password from the perspective of a system administrator but I am a user too. The tougher the password requirements, the more chance that I'll forget it. After all how many 12 character passwords that require 2 cases, 2 numbers and a special character can I remember, especially if it changes every few months. So, the more secure the password, the larger the chance that I leave it on a post it or use the "I forgot my password, please reset it mechanism" The more frequently the reset password mechanism gets used, the more pressure to make it easy and quick for the user (less secure). So, there is a point at which requiring more secure passwords may create less secure results.

  3. If security is a big concern, another idea is authentication above and beyond the password. Send an SMS or e-mail with a one time code valid for an hour as part of the login process or challenge the user with security questions (mother's maiden name, home phone, account number, etc.). You can choose to use these additional challenges only on new browsers (allow them to set a cookie if they expect to use the computer again).

  4. I am running Zend Server's MAMP on a Mac. Life was good until I noticed an error on logging in to phpMyAdmin:

     

    ERROR: The configuration file now needs a secret passphrase (blowfish_secret)

    Being compulsive (or crazy), I decided to fix the error that actually had caused no problems for months. I edited /usr/local/zend/share/phpmyadmin/config.inc.php and added something between the quotes to the line:

    $cfg['blowfish_secret'] = '';
    

    After I did so, I could no longer log in to phpMyAdmin, any attempts just brought me back to the login page. So, I removed the secret phrase I had added. Now, when I try to log in I get:

     

    Cannot start session without errors, please check errors given in your PHP and/or webserver log file and configure your PHP installation properly.

     

    I see nothing unusual in /usr/local/zend/var/log/error.log or php.log (just a few errors from the last application I tested).

     

    I have tried restarting the browser, restarting mysql, and restarting the system.

     

    Any help greatly appreciated. Next time I'll leave well enough alone.

  5. We need more information (field names) to really help but one strategy is to select from journeys and just show those

    SELECT * From Journeys ORDER BY Pickup
    

    and have a single dropdown with available journeys.

    Another strategy would be to have them select pickup first and then display the SELECT list of destinations that they can go to from that pickup

    SELECT Destination FROM Jouneys WHERE pickupfieldname='$pickupselectedbyuser'
    

    You can create the destination select list on the fly using AJAX.

  6. You should always redirect using a 303 after any successful login, otherwise a few clicks on the back button could be used to sign in.

    The 303 response code is a very good idea, but don't know how to do that in php. Looks like response code is just added to the header() but I'm not sure of the syntax.

     

    Also the from_reg whatever whatever is too specific.  You could generalize that "FROM" and use it for all sorts of different stuff like tracking users' click trends.

    True, but the OP wasn't trying to build a user click tracking system.

     

    Also, getting this from value defined by means of a hidden form input is bad practice. 1. it's now user data. and 2. if it's a path, users can redirect themselves anyplace.

    1. User data can be validated 2. (a) in the example I provided it is just either true or something else so that is not an issue (b) the user can go anyplace by typing in a URL. Unless I am missing something there is nothing magical in going to a URL via a redirect that creates a vulnerability that wouldn't be there if you went there directly.

     

    Using the $_SERVER super variable to capture any referrer URL, and validating it's part of your site, and ensuring it's a suitable location for the user is, imo, just much better.

    That was my original thought too (#2) but SocialCloud pointed out that not all browsers send the http_referrer (#3). The hidden field was a way to make sure it worked in those cases.

  7. Good idea but I'd tweak it a bit.

    You could set a session variable on the registration page.

    $_SESSION['from_registration'] = true;

    The issue I would have with that is you would need to clear $_SESSION['form_registration'] on every other page on the site or you would be redirected back to the registration page, even if you logged in 10 pages after visiting the registration page. What if instead you added a hidden field on the registration page and checked for that in login.php.

    <input type="hidden" name="fromreg" value="true">
    
    if (isset($_POST['fromreg']) && $_POST['fromreg']=='true'){
    header ('Location: regpageuri');
    }
    
  8. something like this in the login script (after you make sure they are logged in):

    if ($_SERVER['HTTP_REFERER']=='url of your registration page here'){
    header ('Location: url of your registration page here');
    }
    

    Note: header must be used before any output to the browser (or you can buffer the output).

  9. I have seen a malformed header cause issues. Most browser will have no problem but who wants to track down a bug that affects one user in a thousand?

     

    1. All used headers have first letters uppercase, so you MUST follow this. For example:

    Location, not location
    Content-Type, not content-type or CONTENT-TYPE

    2. Then there MUST be colon and space, like

    good: header("Content-Type: text/plain");

    wrong: header("Content-Type:text/plain");

    3. Location header MUST be absolute uri with scheme, port and so on.

    good: header("Location: http://www.example.com/something.php?a=1");

    4. It can't be relative:

    wrong:  Location: /something.php?a=1
    wrong:  Location: ?a=1

    It will make proxy server and http clients happier.

    quote stolen from comment on http://php.net/manual/en/function.header.php

  10. Please put these two lines at the top of your program

    ini_set("display_errors", "1");
    error_reporting(-1);
    

    and tell us what error messages you get.

     

    Another issue I noticed that would keep it from working is that when you use header() you MUST have a capital L in location and a space after the :

  11. Thank you Ch0cu3r. I will replace the MDB2 code with standard mysqli. I am much more comfortable with procedural style rather than oo. I have a concern that I will cause problems if I do the database operations in procedural style while the rest of the code is oo but can't think of any particular issue. Is there something I'm missing?

     

    requinix: I started to try t figure out how to fix the static methods (other than to change the error reporting level) but it looks like I can't based ob the answer here: http://stackoverflow.com/questions/19248503/non-static-method-peariserror-should-not-be-called-statically

     

    FWIW, I think that the problem extends beyond the warnings. It is the last line

    MDB2 Error: not found
    

    that makes me believe MDB2 failed to connect to the database.  When I installed MDB2 I failed to install the mysqli driver, which reading the documentation I see I also needed to do. http://pear.php.net/manual/en/package.database.mdb2.intro.php However, trying to install the driver fails

    % sudo ./bin/PEAR install MDB2#mysqli
    WARNING: "pear/Console_Getopt" is deprecated in favor of "pear/Console_GetoptPlus"
    Skipping package "pear/MDB2", already installed as version 2.4.1
    downloading PEAR-1.9.4.tgz ...
    Starting to download PEAR-1.9.4.tgz (296,332 bytes)
    .............................................................done: 296,332 bytes
    
    Warning: mkdir(): File exists in System.php on line 285
    
    Warning: mkdir(): Not a directory in System.php on line 285
    ERROR: failed to mkdir /usr/local/zend/bin/PEAR/ChannelFile
    

    and so I'm throwing up my hands and going to put up the time in to completely rip out MDB2 since it is not being maintained.

  12. If you put square brackets after the field name you'll get an array of values back. You can prefill the brackets with a number if you want.

    Pos: <input type="text" name="pos[0]">
    Firstname: <input type="text" name="firstname[0]">
    ...
    Date: <input type="text" name="date[0]">
    
    Pos: <input type="text" name="pos[1]">
    Firstname: <input type="text" name="firstname[1]">
    ...
    Date: <input type="text" name="date[1]">
    
    

    Then loop through the values

    for ($i=0; $i<=1 ;$i++ ){ 
    $sql="INSERT INTO 2014 (Pos,FirstName, LastName, Prov, Perf, Wind, Gender, Agegroup, Event, DOB, Meet, Venue, Date )
    VALUES
    ('$_POST[pos]','$_POST[firstname][$i]','$_POST[lastname][$i]','$_POST[prov][$i]',...'$_POST[date][$i]')";
    
    if (!mysqli_query($con,$sql))
    {
    die('Error: ' . mysqli_error($con));
    }
    }
    

    You should also sanitize the data with mysqli_real_escape_string before the insert.

  13. I have a site, up and running on the internet and want to run it locally. On my Mac I have Zend CE and can access my database with mysqli without a problem. The existing site uses Pear MDB2 to access the database. So, I installed MDB2 on my local machine and still couldn't access the database through the MDB2 code that works on the web server. I added an array to try to open the database connection on port number 10088 but that doesn't make any difference. I am new to Pear and MDB2. Any help appreciated.

     

    To illustrate the problem I have created code that just opens the database directly and then fails with MDB2. Since it works in the first case, the database, username, etc. are all working.

    <?php
    
    ini_set("display_errors", "1");
    error_reporting(-1);
    
    ini_set('include_path', ini_get('include_path') . ':/home/davidann/php'.':/usr/local/zend/bin');
    
    //Mysqli direct
    include_once('setUnamePass.php');
    $link = mysqli_connect("localhost", DBUSER, DBPASS, DATABASE) or die("Unable to connect!");
    echo 'Success using mysqli directly';
    $result=  mysqli_close($link);
    
    //MDB2
    include_once('MDB2.php');
    define('DB_DSN', 'mysqli://'.DBUSER.':'.DBPASS.'@localhost/'.DATABASE);
    class valuation {
    public function __construct() {
    		//open database connection
                    //$options = array(
                      //  'port' => 10088,);
    		$this->db_connection = MDB2::connect(DB_DSN);
    		if (PEAR::isError($this->db_connection)) {
    			exit($this->db_connection->getMessage());
    		}
    		
    		//set fetch mode to associative
    		$this->db_connection->setFetchMode(MDB2_FETCHMODE_ASSOC);
    	}
    }
    $valuation = new valuation();
    ?>
    

    The output is as follows:

    Success using mysqli directly
    Strict Standards: Declaration of MDB2_Driver_Common::raiseError() should be compatible with that of PEAR::raiseError() in /usr/local/zend/bin/MDB2.php on line 990
    
    Strict Standards: Non-static method MDB2::connect() should not be called statically, assuming $this from incompatible context in /usr/local/zend/apache2/htdocs/NewFolder/NewFolder/ezvaluation2/www/ezvaluation.com/valuation/testdbopen.php on line 22
    
    Strict Standards: Non-static method MDB2::factory() should not be called statically, assuming $this from incompatible context in /usr/local/zend/bin/MDB2.php on line 433
    
    Strict Standards: Non-static method MDB2::parseDSN() should not be called statically, assuming $this from incompatible context in /usr/local/zend/bin/MDB2.php on line 376
    
    Strict Standards: Non-static method MDB2::loadClass() should not be called statically, assuming $this from incompatible context in /usr/local/zend/bin/MDB2.php on line 385
    
    Strict Standards: Non-static method MDB2::classExists() should not be called statically, assuming $this from incompatible context in /usr/local/zend/bin/MDB2.php on line 327
    
    Strict Standards: Non-static method MDB2::fileExists() should not be called statically, assuming $this from incompatible context in /usr/local/zend/bin/MDB2.php on line 335
    
    Strict Standards: Non-static method MDB2::raiseError() should not be called statically, assuming $this from incompatible context in /usr/local/zend/bin/MDB2.php on line 340
    
    Strict Standards: Non-static method PEAR::raiseError() should not be called statically, assuming $this from incompatible context in /usr/local/zend/bin/MDB2.php on line 574
    
    Strict Standards: Non-static method MDB2::errorMessage() should not be called statically, assuming $this from incompatible context in /usr/local/zend/bin/MDB2.php on line 972
    
    Strict Standards: Non-static method PEAR::isError() should not be called statically, assuming $this from incompatible context in /usr/local/zend/bin/MDB2.php on line 743
    
    Strict Standards: Non-static method PEAR::isError() should not be called statically, assuming $this from incompatible context in /usr/local/zend/bin/MDB2.php on line 386
    
    Strict Standards: Non-static method PEAR::isError() should not be called statically, assuming $this from incompatible context in /usr/local/zend/bin/MDB2.php on line 434
    
    Strict Standards: Non-static method PEAR::isError() should not be called statically, assuming $this from incompatible context in /usr/local/zend/apache2/htdocs/NewFolder/NewFolder/ezvaluation2/www/ezvaluation.com/valuation/testdbopen.php on line 23
    MDB2 Error: not found
    
  14. A couple of issues that I see:

     

    1. You are using sha256 to hash the password in the first script but using md5 in the second script. Even correcting the salt won't fix it.

     

    2. This code seems to do the same thing >65,000 times when it only needs to be done once.

                for($round = 0; $round < 65536; $round++){
                    $check_password = hash('sha256', $check_password . $row['salt']);
                } 
    

    3. As already mentioned by Ch0cu3r you need to read the salt. Since you have e-mail address you can do it like you did in the first script except modify the query to

            $query = " 
                SELECT 
                    id, 
                    username, 
                    password, 
                    salt, 
                    email 
                FROM users 
                WHERE 
                    email = :email
            "; 
    

    4. Notice in item 3 I am assuming that you'll use PDO to be consistent with the first script. You don't need to, you can use mysqli, but it is a mistake to use mysql (as you do now) because it is long since deprecated. Change email = :email to email='$email' in the line above if you use mysqli.

     

    5. You need to salt and hash the password the same way you do in your login script. Assuming you choose mysqli you'll need to change the line:

    $q="update users set password='".md5($pass)."' where email='".$email."'";
    

    to

    $newpass=hash('sha256',$pass.$row['salt']);
    $q="update users set password='".$newpass."' where email='".$email."'";
    
  15. Your method is better than I thought but I still don't like it. There are a number of reasons why.

     

    1. Looks to me like you end up with a lot of URLs like http://mydomain.com/index.php?page=contact. The URL is not very search engine friendly. You can get around that with rewrite rules, but that adds yet more complexity.

     

    2. You then have a switch/case with a case for every page in the website. That is unwieldy in a larger site and gives you more opportunities to make errors. and you embed the security logic in a switch/case statement that could easily get more than 1,000 lines long. In your example code, you've got 14 lines (not including blank lines and comments) in a script handling just login, contact, and admin.

     

    I prefer to use an include at the top of each script that does the db connections, session setup, and then check permissions for that script before execution.

     

    I'm sure that there are sites where your approach makes sense, but I know it is not the optimal solution in every case. To claim that using another approach is "dumb" is a bit much.

  16. Let me disagree without saying

     

    That's dumb.

    I assume that the OP is not doing redirects on every page, he is only doing so immediately after checking the login. Using htaccess as the login mechanism often means that you need to keep two user databases because you may want to store lots of information about each user that it is impractical to store in .htaccess and change the behavior of the website based on that information. Rather than having two separate user databases (one in htaccess and one in some SQL database) that need to both be updated every time you add/delete/change a username or password, use one database and use $_SESSION to keep track of whose logged in. Not to mention that the method of using htaccess breaks down when you have a more complex permission structure. Sure it works with two directories when you have Admin users and Normal users but then (as an example) try to give some admins permission to delete posts but not others... Very soon you end up with a very complex set of htaccess files.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.