www.webdeveloper.com
Results 1 to 15 of 15

Thread: What is the right way to send user/password information to your database?

  1. #1
    Join Date
    Jun 2007
    Posts
    400

    What is the right way to send user/password information to your database?

    I usually have an include file with the following for all of my PHP pages that access the database...

    Code:
    <?php
    $dbhost = 'localhost';
    $dbuser = 'username';
    $dbpw = 'password';
    $dbname = 'databasename';
    
    $connection = mysql_connect($dbhost, $dbuser, $dbpw) 
    	or die("Unable to connect to MySQL");
    
    mysql_select_db($dbname) or die
    ('Could not select database');
    ?>
    But I feel like there has to be something really wrong with keeping a username and password to my database in a text file.

  2. #2
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    18,912
    It's pretty normal to do something like that, keeping the include file outside of the web document root directory tree, so that it cannot be accessed directly via the web. If you are on a shared host, it's still a bit problematic, as someone else with an account on that server might conceivably be able to access it. For a pretty secure solution for this shared-host issue, see http://shiflett.org/articles/shared-hosting and scroll down to the section titled "What Can You Do?". (Note, however, that requires some cooperation and work by your host admin.)
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  3. #3
    Join Date
    Jun 2007
    Posts
    400
    Hmm, well the one I'm worried about is on our own server at work. All the web stuff is in a directory srv/www/htdocs/yada yada yada how far back would I have to pull the file? Out of the www and right into the srv?

  4. #4
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    18,912
    Probably anywhere not in/under the "htdocs" directory would be safe from HTTP requests, though you could check with your sysadmin to make sure.
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  5. #5
    Join Date
    Jun 2007
    Posts
    400
    Quote Originally Posted by NogDog View Post
    Probably anywhere not in/under the "htdocs" directory would be safe from HTTP requests, though you could check with your sysadmin to make sure.
    Um... I think I am our system admin, ha ha. Not really, but our computer department is small and messy and my boss has no clue what was or wasn't set up and everyone who set it up is long gone.

    Well, we do have this new 18 year old kid who is pretty good with Linux, I could ask him I suppose.

  6. #6
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    18,912
    If you want to be sure, just run the following script:
    PHP Code:
    <?php
    echo $_SERVER['DOCUMENT_ROOT'];
    ?>
    If it outputs something like "/srv/www/htdocs", then anything not in or under that directory would be safe, e.g. "/srv/www/includes/database.php" would be fine, as would "/home/users/xvszero/database.php", but you would want to avoid "/srv/www/htdocs/includes/database.php".
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  7. #7
    Join Date
    Apr 2007
    Posts
    133
    you could add this to prevent direct access, but still use as an included file
    PHP Code:
    if(eregi(basename(__FILE__),$_SERVER['REQUEST_URI']))
    die(
    'Direct access prohibited');

    $dbhost 'localhost';
    $dbuser 'username';
    $dbpw 'password';
    $dbname 'databasename';

    $connection mysql_connect($dbhost$dbuser$dbpw
        or die(
    "Unable to connect to MySQL");

    mysql_select_db($dbname) or die
    (
    'Could not select database'); 

  8. #8
    Join Date
    Jun 2007
    Posts
    400
    Would that cause any performance errors? I added it to the site I'm doing at work and it runs fine, but on my startlogic site it seems to slow things down a bit? It could just be my imagination though.

  9. #9
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    18,912
    It would probably simplify it to something like:
    PHP Code:
    if(count(get_included_files) < 2)
    {
       die(
    "Access denied");

    Note however that this is not a 100&#37; sure thing in the (hopefully very rare) case that the web server config gets screwed up in some manner such that the file is served up directly (as HTML or plain text) instead of being sent to the PHP processor. The odds of this happening are probably very, very low, but if you can store the file outside of the web document directory then it becomes a non-issue. In fact, you can use the above sort of code approach and save it outside of the web document root, reducing the odds if it somehow getting served up to any HTTP requests about as close to zero as you can make it.
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  10. #10
    Join Date
    Sep 2008
    Location
    Cali
    Posts
    14

    Password info

    I use constants so that some clown can't pass in a variable named after my db parameters.

    so I use in my application config file:

    define( 'DSN_MYSQL_HOST', 'mysql:host=mysql.host.com;dbname=yourdbname;');
    define( 'DSN_MYSQL_USER', 'user-name');
    define( 'DSN_MYSQL_PASSWD', 'user-password');

    and in my classes that need db access:
    if( !defined('DSN_MYSQL_HOST'))
    die('Please specify DB host on config for DSN_MYSQL_HOST');


    class ContactsDB
    {
    protected static $DSN_HOST_READ = DSN_MYSQL_HOST;
    protected static $DSN_USER_READ = DSN_MYSQL_USER;
    protected static $DSN_PASSWD_READ = DSN_MYSQL_PASSWD;

    protected static $DSN_HOST_WRITE = DSN_MYSQL_HOST_WRITE;
    protected static $DSN_USER_WRITE = DSN_MYSQL_USER_WRITE;
    protected static $DSN_PASSWD_WRITE = DSN_MYSQL_PASSWD_WRITE;

    /** Returns configured PDO object
    *@return PDO
    */
    protected function getConnecionRead(){
    global $logger;
    if( DEBUG)$logger->Info( __CLASS__ .'.'. __FUNCTION__ .'()...');

    Try {
    $oDB = new PDO( self::$DSN_HOST_READ, self::$DSN_USER_READ, self::$DSN_PASSWD_READ);
    $oDB->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    return $oDB;
    }
    catch(Exception $ex){
    $logger->log( __CLASS__ .'.'. __FUNCTION__ .'()', Zend_Log::ERR);
    $logger->log( $ex->getMessage(), Zend_Log::ERR);
    throw $ex;
    }

    return false;
    }
    }

    This way you can't over-write a variable in your script, worry about some include messing up your db connection or some kiddy scripter if you have register_globals set to on in your php.ini

    name your app.config file with a php extension, so even if they do call it directly and bypass whatever secuirty you are trying to use, they just get a blank file. Used to be a problem when everyone named the config.inc or something and the web server servered the inc file and no pre-processor (asp or php) caught it (web server extension registration).

    Not to take you in the wrong direction, but this is a good place to talk about read and write db permissions also. If you can seperate the read and write connection strings it weill help with security and scalablility.

    Scalability via read host and write master host. Just a thought as I just re-wrote a few dozen apps to seperate this after mysql came to a crawl and I put up a replication partner for reads. It actually wasn't mysql, but the server it was running on, but now I have a failover and backup mysql server.

    Security because if somebody injects sql into a sql select scipt somehow, they only have db read permissions in that method, as you used the read only connection string.

  11. #11
    Join Date
    Sep 2008
    Location
    Cali
    Posts
    14
    forgot, pdo is just a db wrapper API in php 5 (a PECL extension). Same ideas apply using mysql_connect, etc. The try catch only works in php 5 too. Just wanted to post real world code.

    err..... the log method is Zend Framework log (Zend_Log), so you don't need to use that either, but it helps in debugging php 5 (More from experience ... allows you to answer, why did the script not work at 3 am 2 weeks ago).

  12. #12
    Join Date
    Sep 2008
    Location
    Cali
    Posts
    14
    Might as well post the logger setup in case you want to play with it.

    if( !isset( $logger) || !($logger instanceof Zend_Log)){
    require_once('Zend/Log.php');
    require_once('Zend/Log/Writer/Mock.php');
    $logger = new Zend_Log();
    $logger->addWriter( new Zend_Log_Writer_Mock());
    };
    I include this in every class file as there is no telling which app is running it, and if I have declared the logger yet. Kind of a pain, but same idea as log4net (.net) or log4j (java) .

    This is ugly, but I put it in my config file for the logger:
    require_once('Zend/Loader.php');
    Zend_Loader::loadClass('Zend_Log');
    Zend_Loader::loadClass('Zend_Log_Writer_Stream');

    $logger = new Zend_Log();
    $arrDEBUG = array();
    define( 'DEBUG', 1);
    if( DEBUG){
    // create my trace object
    require_once( 'ui/myTracer.php');
    $oTracer = new myTracer();

    Zend_Loader::loadClass('Zend_Log_Writer_Array');
    $mockWtr = new Zend_Log_Writer_Array( $oTracer->LogArray); //('php://stderr');
    $logger->addWriter($mockWtr);

    $logWtr = new Zend_Log_Writer_Stream('php://output');
    $logger->addWriter( $logWtr);
    }
    else{
    Zend_Loader::loadClass('Zend_Log_Writer_Null');
    $logWtr = new Zend_Log_Writer_Null();
    $logger->addWriter( $logWtr);
    }

  13. #13
    Join Date
    Jun 2008
    Location
    Right Behind You
    Posts
    215
    Quote Originally Posted by NogDog View Post
    It would probably simplify it to something like:
    PHP Code:
    if(count(get_included_files) < 2)
    {
       die(
    "Access denied");

    Simplest
    PHP Code:
    if(count(get_included_files)<2)die; 

  14. #14
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    18,912
    Quote Originally Posted by ayvegh View Post
    Simplest
    PHP Code:
    if(count(get_included_files)<2)die; 
    Shortest !== simplest in all cases, but if you want to play that game:
    PHP Code:
    count(get_included_files())-1||die; 
    PS: You left out the "()" at the end of "get_included_files()".
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  15. #15
    Join Date
    Jun 2008
    Location
    Right Behind You
    Posts
    215
    Quote Originally Posted by NogDog View Post
    Shortest !== simplest in all cases, but if you want to play that game:
    PHP Code:
    count(get_included_files())-1||die; 
    Ouch, got me.
    Quote Originally Posted by NogDog View Post
    PS: You left out the "()" at the end of "get_included_files()".
    Nope, you did first.

    All in good fun, my friend.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

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



Recent Articles