Looking for general advice on security

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • tony@tony.com

    Looking for general advice on security


    I'm designing a survey form page that will be fairly complex and am
    becoming confident enough with PHP now to tackle most things.
    (Thanks to everyone here who has helped)

    Before I go too far with this I was wondering if anyone could perhaps
    offer advice or point me to any documents/web pages that could help with
    ensuring the security of the form/page and site. It is likely that the
    form will come under attack I expect.

    Even comments about the best chmod settings are welcome.

    I'd rather not have to wade through another history of the internet book
    with the words "and be security conscious by using SSL" on the last page
    which is what most adviice I've found so far boils down to.

    I've located standard advice such as using PHP strip-tags on input fields
    and other PHP specific stuff but was wondering how best to get
    interactive with the security.

    Are there any PHP libraries perhaps that help with this?

    I'm thinking of things like verifying users ID while they are online
    without having them email and preventing bots from getting in and things
    like that.

    Any input on this would be most welcome.

    thanks

    tony
  • Schraalhans Keukenmeester

    #2
    Re: Looking for general advice on security

    tony@tony.com wrote:[color=blue]
    > I'm designing a survey form page that will be fairly complex and am
    > becoming confident enough with PHP now to tackle most things.
    > (Thanks to everyone here who has helped)
    >
    > Before I go too far with this I was wondering if anyone could perhaps
    > offer advice or point me to any documents/web pages that could help with
    > ensuring the security of the form/page and site. It is likely that the
    > form will come under attack I expect.
    >
    > Even comments about the best chmod settings are welcome.
    >
    > I'd rather not have to wade through another history of the internet book
    > with the words "and be security conscious by using SSL" on the last page
    > which is what most adviice I've found so far boils down to.
    >
    > I've located standard advice such as using PHP strip-tags on input fields
    > and other PHP specific stuff but was wondering how best to get
    > interactive with the security.
    >
    > Are there any PHP libraries perhaps that help with this?
    >
    > I'm thinking of things like verifying users ID while they are online
    > without having them email and preventing bots from getting in and things
    > like that.
    >
    > Any input on this would be most welcome.
    >
    > thanks
    >
    > tony[/color]

    Consider using https for starters, if the page collects more or less
    sensitive information.

    It may be a good practice from security point of view to have ALL your
    form-vars parsed by a separate handler/filter first before handing them
    to your operational code. In other words, there should never be any
    referral to $_POST["anyname"] (or $_GET) in your actual processing code.
    The handler should:

    Check type consistency
    Truncate data to intended maxmimum length/size
    Strip possibly dangerous chars, esp wrt MySQL injection. (mod_security
    on your webserver can help with this further)
    Discard any variable with a name not used in your form, and possibly
    take further action (like blocking client ip)

    Further: keep track of amount of submits by an address or address range
    in a given timeframe. If this exceeds a reasonable value, block the
    address (temporarily?). Or have a lookup in your db how long it was
    since the last attempt for ip w.x.y.z and introduce a delay for the user.

    To prevent bot-action, include a verification field with hard to scan
    characters.

    keep db passwords, names etc. in an include file outside your docroot.
    having non-standard names is a good thing from security point of view.

    Translate form fieldnames to different ones you use in your db.

    Don't use $_GLOBALS.

    Set safe mode on if it's not already the default mode on your server.

    The server should run as a separate user of course. Never root, nor a
    regular user. Be careful with symlinks jumping out of the tree.
    Set rights to a minimum requirement. I use rw- r-- --- root:apache on
    anything that does not need to be modified by the webserver. Consider
    setting the immutable bit on critical files as well.

    Chrooting the server and/or mysql is worth considering on any
    production/high visibility server. (Securityfocus has great walkthroughs
    on this). Of course only applicable if you have access to your own
    server as root.

    I'm not a big fan of too much interactivity and additional
    user-checking. It gets complicated soon and may even give a false sense
    of security if there's holes in it you may have overlooked.

    Anything helpful here ? Hope so.
    GL!

    Sh.
    --
    Backbone Scoliosis

    Comment

    • Gordon Burditt

      #3
      Re: Looking for general advice on security

      >I'm designing a survey form page that will be fairly complex and am[color=blue]
      >becoming confident enough with PHP now to tackle most things.
      >(Thanks to everyone here who has helped)
      >
      >Before I go too far with this I was wondering if anyone could perhaps
      >offer advice or point me to any documents/web pages that could help with
      >ensuring the security of the form/page and site. It is likely that the
      >form will come under attack I expect.
      >
      >Even comments about the best chmod settings are welcome.[/color]

      PHP pages (with an Apache PHP-module setup) have to be world-readable,
      for Apache/PHP to use them. In many hosting setups, you FTP stuff
      in under a userID different from the one Apache runs as. You
      probably want your pages owned by that different userID and mode
      644. It is preferable that your pages *NOT* be writable by the
      user Apache/PHP runs as, just in case a CGI or PHP page is compromised,
      it can't deface your page. Put your data in a database, not writable
      files in the document tree.

      If you need to protect yourself from a different customer on a
      shared server, you have a lot of problems. This is much different
      from protecting yourself against users with browsers. There are
      difficulties with things like hiding your database password, which
      Apache/PHP has to have but that's what the other customer's PHP
      pages usually runs as. You may want your own dedicated (co-located?)
      server.
      [color=blue]
      >I'd rather not have to wade through another history of the internet book
      >with the words "and be security conscious by using SSL" on the last page
      >which is what most adviice I've found so far boils down to.[/color]

      SSL provides a way for a thief with a browser to communicate with
      a thief with a web site, making it difficult for *other* thieves
      to perform a ripoff of either first by listening in. *IF* the guy
      with the browser looks at the cert, he has some assurance of which
      thief he's talking to at the web site. Very few sites use certs
      for users, and it's way too much trouble for a public site. How
      many people would notice the cert says "Satan, Prince of Darkness"?

      DO use SSL for anything containing credit card numbers and other
      sensitive information. If your site deals in real money (especially
      if it can spend money using a remembered credit card number), use
      SSL for the login page the user ENTERs his login/password info.
      That it *SUBMITS* to a secure page isn't enough (among other problems,
      the login page is not SSL, so the browser might cache the filled-in
      data. It also trains users to enter sensitive info into non-secure
      pages without checking).

      Don't provide sensitive information to someone who happens to find
      a logged-in user's computer. Even if you remember the user's credit
      card number, DON'T provide a way to display it in full (last 4 digits
      only is common). DON'T show the user what his current password is,
      although you can let him change it (which will alert the legitimate
      user when he can't get in).

      Be suspicious of input coming from the user's browser. That includes
      form input, cookies, HTTP_REFERER, variables contained in URLs,
      and browser type info. All of that can be manually generated by
      typing into telnet.

      Session cookies are a bit more secure than other things stored in
      cookies because the user can't fake a session with arbitrary contents,
      they have to fake an existing one, and that's difficult. Expire
      inactive sessions. It is less important that you expire inactive
      sessions at 5 minutes vs. an hour, but that you expire inactive
      sessions at 1 week vs. never. The more unexpired sessions you have,
      the easier session hijacking is. Also, in the default setup, the
      more unexpired sessions you have, the larger the directory holding
      them gets, and at some point (e.g. 100,000 unexpired sessions) it
      becomes a performance killer.

      Do not necessarily depend on PHP's probabalistic session expiration
      (If you set an expiration time of 1 day, there's no guarantee a
      particular session won't be around a month later). Putting a
      timestamp in the session and using it to figure out if it's expired
      will work consistently. The probabalistic expiration is good for
      getting rid of unused files, though.

      The expiration should depend on the sensitivity of information being
      protected and the estimated magnitude of the "unattended terminal"
      problem. Don't make it so short your users can't use the site.
      It's not that unreasonable to allow your users 8 hours to submit an
      order (they may be comparison-shopping in another window, or they
      may have to drive home and back to get their credit card).

      Don't trust data validation done by HTML or Javascript. Do it
      *AGAIN* at the server. (Javascript validation does make it more
      convenient and friendly for users to get instant feedback about
      errors, but it doesn't add to security.) People don't have to submit
      data using YOUR form. (but don't spend a lot of time trying to
      prevent this: you'll find yourself doing the equivalent of installing
      a nuclear-bomb-blast proof safe door on a cardboard safe with a
      screen back door with a broken lock). Javascript can be Turned
      Off(tm), or a copy of your page can be set up on another server and
      edited.

      Input validation is good, but don't get overly strict about it and
      reject valid input. Feb 29 *is* a valid date for a birthday.
      People's names sometimes have single quotes in them. Not everyone
      has a *US* postal code. The USPS occasionally creates new postal
      codes, so if you use a zip code table, keep it updated and it still
      might be out of date. Not everyone has a *US* telephone number.
      Some people have telephone numbers with extensions (which are not
      10 digits). Birth dates are not necessarily representable as a
      PHP timestamp (which on some systems only goes back to 1970).
      [color=blue]
      >I've located standard advice such as using PHP strip-tags on input fields
      >and other PHP specific stuff but was wondering how best to get
      >interactive with the security.[/color]

      Do not strip HTML tags out of things like names, credit card numbers,
      email addresses, and such. If you find HTML tags in such things,
      consider them INVALID INPUT and reject them. It's OK to strip out
      HTML tags out of free-text fields like forum postings.

      Beware of SQL injection attacks. If putting a single quote in a
      text field causes SQL errors, you're in trouble. Use functions
      like mysql_escape_st ring() or parameterized SQL (? placeholders
      used for parameters).
      [color=blue]
      >Are there any PHP libraries perhaps that help with this?
      >
      >I'm thinking of things like verifying users ID while they are online
      >without having them email and preventing bots from getting in and things
      >like that.[/color]

      Do not, under any circumstances, allow user input to be put into
      mail headers (or anything but the "message text" argument of the
      mail() function) without first checking it for carriage-return/linefeed
      characters. If you detect such characters (e.g. an email address
      consisting of "me@domain.com\ r\nBcc: victim1@aol.com ,victim2@aol.co m")
      DO NOT SEND ANY MAIL AT ALL! (But you might log the attempt.)
      Don't strip the characters, consider them as invalid input and
      reject them.

      Don't put the user-supplied email address in the From: line of the
      mail message. That can be used to inject headers if they contain
      carriage-return or linefeed. Also, if it can be made to bounce,
      it can spam that email address with a bounce message.

      It is OK to allow carriage-return/linefeed in the body of a message.
      You might want to limit the length of input to something reasonable
      for the situation, or someone will insert whole virus attachments.

      A user-supplied email address can be validated by:
      (1) syntax, such as containing an @ and not containing carriage-return/
      linefeed characters,

      (2) Domain lookup, in which you check that the part to the right
      of the @ has either an MX record or an A record in DNS,

      (3) Try to send a message to the user and see if the mail server
      accepts it. This may be no better than (2) (and requires (2) to
      find the mail server). It also may return inconclusive results if,
      for example, the mail server is down, and it may take an unacceptably
      long time to return such a result. You should NOT assume that (a)
      the first mail server you try will be up, or (b) domains don't
      occasionally have all mail servers fail or become unreachable.
      (Large sections of the net sometimes become unreachable.)

      (4) Send mail to the user and have him click on a link.

      Only (4) verifies that the email address given belongs to the user
      and not a victim. Only (4) is acceptable for putting a user on a
      mailing list (spammers often use mailing list subscriptions as a
      weapon against people who complain about them).

      Be careful about sending email to user-supplied addresses. Your
      site can be used to mail-bomb someone if you do. Keep track of
      confirmation emails you send and don't send more than, say, two
      plus one a week to any one address (You can take the limit off after
      it's confirmed).

      Gordon L. Burditt

      Comment

      • Schraalhans Keukenmeester

        #4
        Re: Looking for general advice on security

        Gordon Burditt wrote:[color=blue][color=green]
        >>I'm designing a survey form page that will be fairly complex and am
        >>becoming confident enough with PHP now to tackle most things.
        >>(Thanks to everyone here who has helped)
        >>
        >>Before I go too far with this I was wondering if anyone could perhaps
        >>offer advice or point me to any documents/web pages that could help with
        >>ensuring the security of the form/page and site. It is likely that the
        >>form will come under attack I expect.
        >>
        >>Even comments about the best chmod settings are welcome.[/color]
        >
        >
        > PHP pages (with an Apache PHP-module setup) have to be world-readable,
        > for Apache/PHP to use them.[/color]

        Not true, at least not on my FC4 box. I have my html & php files all set to:

        -rw-r----- 1 root apache 33 Apr 20 05:24 example.php
        -rw-r----- 1 root apache 817 Mar 06 11:32 index.html

        and they are served up nicely.
        All directories in the docroot tree are set to

        drwx-r-x--- 2 root apache 4096 Mar 06 11:41 css
        drwx-r-x--- 2 root apache 4096 Mar 06 11:41 PHP
        drwx-r-x--- 2 root apache 4096 Mar 06 11:43 images

        Sh.

        Comment

        • Colin McKinnon

          #5
          Re: Looking for general advice on security

          Schraalhans Keukenmeester <firstname_DOT_ lastname_AT_xs4 all_DOT_nl> wrote:
          [color=blue]
          > Gordon Burditt wrote:[color=green][color=darkred]
          >>>I'm designing a survey form page that will be fairly complex and am[/color][/color][/color]
          <snip>[color=blue][color=green]
          >> PHP pages (with an Apache PHP-module setup) have to be world-readable,
          >> for Apache/PHP to use them.[/color]
          >
          > Not true, at least not on my FC4 box. I have my html & php files all set
          > to:
          >
          > -rw-r----- 1 root apache 33 Apr 20 05:24 example.php
          > -rw-r----- 1 root apache 817 Mar 06 11:32 index.html
          >
          > and they are served up nicely.[/color]

          Yes, but I'm cringing even now with the thought that this is a response to a
          thread about security.

          (Chris Shiflett is often found hanging around when people are talking about
          PHP security and has written some good articles on the subject - try Google
          for specifics).

          C.

          Comment

          Working...