Database Security Issues

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jonathan Lamothe

    Database Security Issues

    I'm helping someone to create an online database. All is fine and good
    except for one problem. Here it is:

    In order to provide connectivity to the database, I've created a file called
    database.php which is readable only by the Apache web server.

    It contained the following:

    <?php

    function database() {
    $db = mysql_connect(" localhost", "mtlstats", /* the password */);
    mysql_select_db ("mtlstats", $db);
    return $db;
    }

    ?>

    I quickly realized that even though nobody could read the password from the
    file, there was nothing preventing the other people with accounts on my web
    server, from including this file into one of their own php scripts, and
    hijacking the database. I therefore made a change, so that it would only
    work when called from a file in the /mtlstats directory.

    The file now reads as follows:

    <?php

    function database() {
    if(strpos($PHP_ SELF, "/mtlstats/") === 0) {
    $db = mysql_connect(" localhost", "mtlstats", /* the password */);
    mysql_select_db ("mtlstats", $db);
    return $db;
    }
    return NULL;
    }

    ?>

    Unfortunately, I've discovered that although $PHP_SELF normally returns the
    name of the file being processed by the server, when called from within a
    function, it returns NULL for some reason. Can anyone suggest an
    alternative means of correcting this problem?

    Any assistance would be greatly appreciated.

    --
    Jonathan Lamothe
    Founder of the Anime Void.

  • Daniel Tryba

    #2
    Re: Database Security Issues

    Jonathan Lamothe <jonathan_lamot he@hotmail.com> wrote:[color=blue]
    > <?php
    > function database() {
    > if(strpos($PHP_ SELF, "/mtlstats/") === 0) {[/color]
    [snip][color=blue]
    > }
    >
    > ?>
    >
    > Unfortunately, I've discovered that although $PHP_SELF normally returns the
    > name of the file being processed by the server, when called from within a
    > function, it returns NULL for some reason. Can anyone suggest an
    > alternative means of correcting this problem?[/color]

    RTFM, you need to brush up on your variable skills:

    from

    to

    to

    and


    But the really shortshort version: use superglobals instead....

    eg:
    'PHP_SELF'

    The filename of the currently executing script, relative to the document
    root. For instance, $_SERVER['PHP_SELF'] in a script at the address
    http://example.com/ test.php/foo.bar would be /test.php/foo.bar.

    --

    Daniel Tryba

    Comment

    • Matty

      #3
      Re: Database Security Issues

      Daniel Tryba wrote:
      [color=blue]
      > Jonathan Lamothe <jonathan_lamot he@hotmail.com> wrote:[color=green]
      >> <?php
      >> function database() {
      >> if(strpos($PHP_ SELF, "/mtlstats/") === 0) {[/color]
      > [snip][color=green]
      >> }[/color][/color]

      <moresnip>
      [color=blue]
      > But the really shortshort version: use superglobals instead....
      >
      > eg:
      > 'PHP_SELF'
      >
      > The filename of the currently executing script, relative to the document
      > root. For instance, $_SERVER['PHP_SELF'] in a script at the address
      > http://example.com/ test.php/foo.bar would be /test.php/foo.bar.
      >[/color]

      It's often better to look at the value of $_SERVER['REQUEST_URI'], especially
      if you're doing things with mod_rewrite that involve non-existent folder names
      ....

      Comment

      • Terence

        #4
        Re: Database Security Issues

        Jonathan Lamothe wrote:
        [color=blue]
        > I'm helping someone to create an online database. All is fine and good
        > except for one problem. Here it is:
        >
        > In order to provide connectivity to the database, I've created a file called
        > database.php which is readable only by the Apache web server.
        >
        > It contained the following:
        >
        > <?php
        >
        > function database() {
        > $db = mysql_connect(" localhost", "mtlstats", /* the password */);
        > mysql_select_db ("mtlstats", $db);
        > return $db;
        > }
        >
        > ?>
        >
        > I quickly realized that even though nobody could read the password from the
        > file, there was nothing preventing the other people with accounts on my web
        > server, from including this file into one of their own php scripts, and
        > hijacking the database. I therefore made a change, so that it would only
        > work when called from a file in the /mtlstats directory.
        >
        > The file now reads as follows:
        >
        > <?php
        >
        > function database() {
        > if(strpos($PHP_ SELF, "/mtlstats/") === 0) {
        > $db = mysql_connect(" localhost", "mtlstats", /* the password */);
        > mysql_select_db ("mtlstats", $db);
        > return $db;
        > }
        > return NULL;
        > }
        >
        > ?>
        >
        > Unfortunately, I've discovered that although $PHP_SELF normally returns the
        > name of the file being processed by the server, when called from within a
        > function, it returns NULL for some reason. Can anyone suggest an
        > alternative means of correcting this problem?
        >
        > Any assistance would be greatly appreciated.
        >[/color]

        As long as others have access to the permissions of the account that the
        web server is running as, then they will have access to any of your PHP
        scripts (source code) and any files that your PHP scripts have
        permission to read.

        The trick is to not have users without your trust getting access to your
        webserver's user. It's a system configuration issue.


        Comment

        • Michael Fuhr

          #5
          Re: Database Security Issues

          Terence <tk.lists@fastm ail.fm> writes:
          [color=blue]
          > As long as others have access to the permissions of the account that the
          > web server is running as, then they will have access to any of your PHP
          > scripts (source code) and any files that your PHP scripts have
          > permission to read.
          >
          > The trick is to not have users without your trust getting access to your
          > webserver's user. It's a system configuration issue.[/color]

          One way to protect database passwords is to remove them from the
          code and have the web server set them in an environment variable
          that the code could read. The web server would set a different
          password depending on the user, directory, or whatever condition
          you can think of; with Apache, for example, you could do this with
          SetEnv, SetEnvIf, or mod_rewrite. Although the web server typically
          runs as a non-privileged user such as "www" or "httpd", it usually
          starts as root so it can bind to port 80. The passwords could be
          stored in a file that only root can read, so PHP, CGI, or other
          code running as the non-privileged web server user couldn't read
          the passwords from the file.

          Using the above mechanism, the only way a user could read other
          users' passwords would be by reading the process memory, perhaps
          using /proc/pid/mem on systems that have such a thing, or possibly
          by getting the web server to dump core and then reading the core
          file. The sysadmin should be able to prevent these possibilities
          from happening.

          --
          Michael Fuhr

          Comment

          • Daniel Tryba

            #6
            Re: Database Security Issues

            Michael Fuhr <mfuhr@fuhr.org > wrote:[color=blue]
            > One way to protect database passwords is to remove them from the
            > code and have the web server set them in an environment variable
            > that the code could read. The web server would set a different
            > password depending on the user, directory, or whatever condition
            > you can think of; with Apache, for example, you could do this with
            > SetEnv, SetEnvIf, or mod_rewrite. Although the web server typically
            > runs as a non-privileged user such as "www" or "httpd", it usually
            > starts as root so it can bind to port 80. The passwords could be
            > stored in a file that only root can read, so PHP, CGI, or other
            > code running as the non-privileged web server user couldn't read
            > the passwords from the file.[/color]

            Needlesly complicated. Run the webserver with the priveliges of a
            user. That way the passwds can be in a file only readable to the user

            --

            Daniel Tryba

            Comment

            • Michael Fuhr

              #7
              Re: Database Security Issues

              Daniel Tryba <news_comp.lang .php@canopus.nl > writes:
              [color=blue]
              > Michael Fuhr <mfuhr@fuhr.org > wrote:[color=green]
              > > One way to protect database passwords is to remove them from the
              > > code and have the web server set them in an environment variable
              > > that the code could read. The web server would set a different
              > > password depending on the user, directory, or whatever condition
              > > you can think of; with Apache, for example, you could do this with
              > > SetEnv, SetEnvIf, or mod_rewrite. Although the web server typically
              > > runs as a non-privileged user such as "www" or "httpd", it usually
              > > starts as root so it can bind to port 80. The passwords could be
              > > stored in a file that only root can read, so PHP, CGI, or other
              > > code running as the non-privileged web server user couldn't read
              > > the passwords from the file.[/color]
              >
              > Needlesly complicated. Run the webserver with the priveliges of a
              > user. That way the passwds can be in a file only readable to the user[/color]

              Could you elaborate on how you'd do this on an ISP's web server
              that has thousands of users? Apache 2's perchild MPM looks promising
              for virtual hosts -- if you want to have a virtual host for each
              user -- but according to the documentation it doesn't work yet on
              most platforms, and I wonder how it would scale. It also doesn't
              appear usable in a non-virtual-host setup, such as the ISP might
              have for its SSL configuration.

              --
              Michael Fuhr

              Comment

              • Daniel Tryba

                #8
                Re: Database Security Issues

                Michael Fuhr <mfuhr@fuhr.org > wrote:[color=blue][color=green]
                >> Needlesly complicated. Run the webserver with the priveliges of a
                >> user. That way the passwds can be in a file only readable to the user[/color]
                >
                > Could you elaborate on how you'd do this on an ISP's web server
                > that has thousands of users?[/color]

                With apache it seem that suexec is the way to go (and thus introducing
                new problems like running php as cgi, but the enhanced per user security
                might be worth it).
                [color=blue]
                > Apache 2's perchild MPM looks promising for virtual hosts -- if you
                > want to have a virtual host for each user -- but according to the
                > documentation it doesn't work yet on most platforms, and I wonder how
                > it would scale. It also doesn't appear usable in a non-virtual-host
                > setup, such as the ISP might have for its SSL configuration.[/color]

                On the system I run Apache/PHP I'm the sole user, on the only multiuser
                system I have access to the server isn't Apache, it lacks "native" php
                support so php is run as the user in cgi :)

                --

                Daniel Tryba

                Comment

                • Michael Fuhr

                  #9
                  Re: Database Security Issues

                  Daniel Tryba <news_comp.lang .php@canopus.nl > writes:
                  [color=blue]
                  > Michael Fuhr <mfuhr@fuhr.org > wrote:[color=green][color=darkred]
                  > >> Needlesly complicated. Run the webserver with the priveliges of a
                  > >> user. That way the passwds can be in a file only readable to the user[/color]
                  > >
                  > > Could you elaborate on how you'd do this on an ISP's web server
                  > > that has thousands of users?[/color]
                  >
                  > With apache it seem that suexec is the way to go (and thus introducing
                  > new problems like running php as cgi, but the enhanced per user security
                  > might be worth it).[/color]

                  As you point out, using suEXEC introduces problems of its own. One
                  of PHP's advantages is that it can be parsed directly by the server
                  without having to go through the fork/exec overhead of creating a
                  new process; using suEXEC or any other setuid/setgid mechanism that
                  requires a new process would negate that advantage. On a busy
                  server that could cause serious performance problems.

                  Run some benchmarks and compare the times for server-parsed PHP vs.
                  PHP run as CGI. Running as CGI is horrible.
                  [color=blue][color=green]
                  > > Apache 2's perchild MPM looks promising for virtual hosts -- if you
                  > > want to have a virtual host for each user -- but according to the
                  > > documentation it doesn't work yet on most platforms, and I wonder how
                  > > it would scale. It also doesn't appear usable in a non-virtual-host
                  > > setup, such as the ISP might have for its SSL configuration.[/color]
                  >
                  > On the system I run Apache/PHP I'm the sole user, on the only multiuser
                  > system I have access to the server isn't Apache, it lacks "native" php
                  > support so php is run as the user in cgi :)[/color]

                  This thread was about protecting passwords on a multiuser system,
                  a problem that ISPs and their customers face. Using suEXEC or other
                  setuid/setgid mechanisms can solve the security problem for the
                  user, but for the ISP they can cause unacceptable performance
                  degradation. The mechanism I posted is a way to protect passwords
                  without introducing the performance overhead of creating a new
                  process every time a page is served.

                  --
                  Michael Fuhr

                  Comment

                  • Matty

                    #10
                    Re: Database Security Issues

                    Michael Fuhr wrote:
                    [color=blue]
                    >
                    > This thread was about protecting passwords on a multiuser system,
                    > a problem that ISPs and their customers face. Using suEXEC or other
                    > setuid/setgid mechanisms can solve the security problem for the
                    > user, but for the ISP they can cause unacceptable performance
                    > degradation. The mechanism I posted is a way to protect passwords
                    > without introducing the performance overhead of creating a new
                    > process every time a page is served.
                    >[/color]

                    One way to do it, is to have a group for users with webpages, and make
                    the relevant directories chmod 0705 - then the user can access the directory,
                    apache can access it as nobody, and memebrs of the same group have no
                    access to the directory.

                    Just a thought...

                    Matt

                    Comment

                    • Michael Fuhr

                      #11
                      Re: Database Security Issues

                      Matty <matt+nntp@askm enoquestions.co .uk> writes:
                      [color=blue]
                      > Michael Fuhr wrote:[/color]
                      [color=blue][color=green]
                      > > This thread was about protecting passwords on a multiuser system,
                      > > a problem that ISPs and their customers face. Using suEXEC or other
                      > > setuid/setgid mechanisms can solve the security problem for the
                      > > user, but for the ISP they can cause unacceptable performance
                      > > degradation. The mechanism I posted is a way to protect passwords
                      > > without introducing the performance overhead of creating a new
                      > > process every time a page is served.
                      > >[/color]
                      > One way to do it, is to have a group for users with webpages, and make
                      > the relevant directories chmod 0705 - then the user can access the directory,
                      > apache can access it as nobody, and memebrs of the same group have no
                      > access to the directory.[/color]

                      If the web server can read a file then anybody who uses that web
                      server can potentially read that file. PHP features like safe_mode
                      and open_basedir can help prevent this, as can CGI mechanisms such
                      as suEXEC, but on some multiuser systems implementing such measures
                      isn't a viable option, and the web server may provide other services
                      that wouldn't be restricted these measures.

                      --
                      Michael Fuhr

                      Comment

                      • Chung Leong

                        #12
                        Re: Database Security Issues

                        As others have noted, there's really no easy way you can protect the
                        file in question without making some serious changes to the Apache
                        setup.

                        The only solution I have think of is to encrypt the database password
                        using the login password as the key, and storing it in a associative
                        array on the server.

                        $passwords = {
                        "cleong" => "AB534BE432BEE4 33C...E433C340F ",
                        "ojsimpson" => "7488494782...3 24239424",
                        "jausten" => "8492374837923. ..384274389"
                        ...
                        }

                        When the user logs in, the password provided is use to decrypt the
                        cooresponding entry in the array, yielding the database password. The
                        password is then stored in a cookie on the client-side (can't use a
                        session variable, as session files are accessible through Apache).

                        Jonathan Lamothe <jonathan_lamot he@hotmail.com> wrote in message news:<PBtwb.443 4$dt2.460498@ne ws20.bellglobal .com>...[color=blue]
                        > I'm helping someone to create an online database. All is fine and good
                        > except for one problem. Here it is:
                        >
                        > In order to provide connectivity to the database, I've created a file called
                        > database.php which is readable only by the Apache web server.
                        >
                        > It contained the following:
                        >
                        > <?php
                        >
                        > function database() {
                        > $db = mysql_connect(" localhost", "mtlstats", /* the password */);
                        > mysql_select_db ("mtlstats", $db);
                        > return $db;
                        > }
                        >
                        > ?>
                        >
                        > I quickly realized that even though nobody could read the password from the
                        > file, there was nothing preventing the other people with accounts on my web
                        > server, from including this file into one of their own php scripts, and
                        > hijacking the database. I therefore made a change, so that it would only
                        > work when called from a file in the /mtlstats directory.
                        >
                        > The file now reads as follows:
                        >
                        > <?php
                        >
                        > function database() {
                        > if(strpos($PHP_ SELF, "/mtlstats/") === 0) {
                        > $db = mysql_connect(" localhost", "mtlstats", /* the password */);
                        > mysql_select_db ("mtlstats", $db);
                        > return $db;
                        > }
                        > return NULL;
                        > }
                        >
                        > ?>
                        >
                        > Unfortunately, I've discovered that although $PHP_SELF normally returns the
                        > name of the file being processed by the server, when called from within a
                        > function, it returns NULL for some reason. Can anyone suggest an
                        > alternative means of correcting this problem?
                        >
                        > Any assistance would be greatly appreciated.[/color]

                        Comment

                        • Michael Fuhr

                          #13
                          Re: Database Security Issues

                          chernyshevsky@h otmail.com (Chung Leong) writes:
                          [color=blue]
                          > As others have noted, there's really no easy way you can protect the
                          > file in question without making some serious changes to the Apache
                          > setup.
                          >
                          > The only solution I have think of is to encrypt the database password
                          > using the login password as the key, and storing it in a associative
                          > array on the server.[/color]

                          What login password are you using as the key?
                          [color=blue]
                          > $passwords = {
                          > "cleong" => "AB534BE432BEE4 33C...E433C340F ",
                          > "ojsimpson" => "7488494782...3 24239424",
                          > "jausten" => "8492374837923. ..384274389"
                          > ...
                          > }
                          >
                          > When the user logs in, the password provided is use to decrypt the
                          > cooresponding entry in the array, yielding the database password. The
                          > password is then stored in a cookie on the client-side (can't use a
                          > session variable, as session files are accessible through Apache).[/color]

                          When what user logs in? This solution seems to assume that a single
                          user will be using the database and that the user will be logging
                          in using a password. How would this solution work for an application
                          that needs to access a database for any number of users who won't
                          be logging in?

                          --
                          Michael Fuhr

                          Comment

                          • Matty

                            #14
                            Re: Database Security Issues

                            Michael Fuhr wrote:

                            [color=blue][color=green]
                            >> One way to do it, is to have a group for users with webpages, and make
                            >> the relevant directories chmod 0705 - then the user can access the
                            >> directory, apache can access it as nobody, and memebrs of the same group
                            >> have no access to the directory.[/color]
                            >
                            > If the web server can read a file then anybody who uses that web
                            > server can potentially read that file. PHP features like safe_mode
                            > and open_basedir can help prevent this, as can CGI mechanisms such
                            > as suEXEC, but on some multiuser systems implementing such measures
                            > isn't a viable option, and the web server may provide other services
                            > that wouldn't be restricted these measures.
                            >[/color]

                            Well, really the only way to make it secure, if it needs to be, is to put
                            the site on its own server. If suExec is an option, that's another way to
                            do it.

                            Basically, if you have ${n}x100 users on a server, it's kinda hard to make
                            individual sites that secure, although open_basedir can help in php

                            If you need the security, you pay for it!

                            Matt

                            Comment

                            • Chung Leong

                              #15
                              Re: Database Security Issues

                              Yes, it's a limited solution. The assumption is that you have a small
                              group of trusted users accessing the database. I was trying to come up
                              with something that doesn't require changes to the server config,
                              since I doubt that an ISP would be willing to make them for you. Most
                              likely they'll just tell you to use their single-server or virtual
                              machine package.

                              mfuhr@fuhr.org (Michael Fuhr) wrote in message news:<3fc83f30$ 1_1@omega.dimen sional.com>...[color=blue]
                              > chernyshevsky@h otmail.com (Chung Leong) writes:
                              >[color=green]
                              > > As others have noted, there's really no easy way you can protect the
                              > > file in question without making some serious changes to the Apache
                              > > setup.
                              > >
                              > > The only solution I have think of is to encrypt the database password
                              > > using the login password as the key, and storing it in a associative
                              > > array on the server.[/color]
                              >
                              > What login password are you using as the key?
                              >[color=green]
                              > > $passwords = {
                              > > "cleong" => "AB534BE432BEE4 33C...E433C340F ",
                              > > "ojsimpson" => "7488494782...3 24239424",
                              > > "jausten" => "8492374837923. ..384274389"
                              > > ...
                              > > }
                              > >
                              > > When the user logs in, the password provided is use to decrypt the
                              > > cooresponding entry in the array, yielding the database password. The
                              > > password is then stored in a cookie on the client-side (can't use a
                              > > session variable, as session files are accessible through Apache).[/color]
                              >
                              > When what user logs in? This solution seems to assume that a single
                              > user will be using the database and that the user will be logging
                              > in using a password. How would this solution work for an application
                              > that needs to access a database for any number of users who won't
                              > be logging in?[/color]

                              Comment

                              Working...