1

So I'm building a GUI admin area for my site. I will be the only one to login and it will just show a clean (printable) layout of info from my db.

Here's what I'm doing for security. Let me know if you think this is good and how I can improve.

  1. headers on all pages check for admin == true or die/redirect
  2. since i have a dedicated ip at home and i will only login from home. I made all pages including the login form page check for my IP $_SERVER['REMOTE_ADDR']; != header redirect
  3. My login script is in dir set 700 in folder permissions.
  4. my login and pw contain 10 total combo of letters, numbers and special chars. PW is stored as SHA2 HASH
  5. my login script checks for regex prior to sql and my credentials are stored in a separate admin table
  6. The entire site is on SSL.

So is this secure? Can I do more? Is this overkill? Please share your opinions and suggestions (especially regarding my IP check. Can that be circumvented?)

Used to escape bad data - in conjunction with regex on every field

function escape_data ($data) {
    if (function_exists(‘mysql_real_escape_string’)) {
        global $dbc;

        $data = mysql_real_escape_string (trim($data), $dbc);
        $data = strip_tags($data);
} else {
        $data = mysql_escape_string (trim($data));
        $data = strip_tags($data);
        }
        return $data;

    }
MrPizzaFace
  • 7,807
  • 15
  • 79
  • 123

3 Answers3

2

NOTHING is overkill for an admin page. You want as much security as you possibly can.

As for your methods, most of them are fairly good, but some suggestions:

  • Setting chmod to 700 won't prevent others from at least accessing the admin page (I'm assuming that's what you were using it for), because it's the web server that's accessing the files, regardless of who's making the HTTP request.
  • Rather than checking $_SERVER['REMOTE_ADDR'], it's probably more secure (and easier) to just create a unique user SSL certificate and only allow the computer with that user certificate (i.e. yours) to access the site. This can be done in your Apache setup (if you managed to set up SSL, you can go back in and set up user certification on your SSL), solves the chmod problem, and prevents people from spoofing your IP to go into your admin page.
  • If you don't need to SSH into your home computer, disable the SSH daemon. This will (hopefully) prevent others from targeting your computer to go after your server.

These are the first things I can think of. I'll add more as they come to me.

EDIT: Right, logging! Log everything that happens on your admin page. EVERYTHING. For the SSL, for the requests, for the database access, for everything. Then get a log-watching program (e.g.: logwatch) to watch it for suspicious activity.

Palladium
  • 3,723
  • 4
  • 15
  • 19
  • I agree on nothing being overkill.. lol especially for a paranoid like me.. Thanks for the tips. I will be looking into that SSL setup to see if it is available to me. This is on a shared server .. not sure if I can access SSH (not sure what that is.. need to read up / thx for the tip) – MrPizzaFace Jul 23 '12 at 21:44
  • @FabioAnselmo See edit. (Summary? Logging. Logging logging logging. Logging.) Also, SSH is for remotely accessing your computer - so if you don't have SSH, make sure that other remote access protocols aren't running (or that they're restricted to running when you want them to). – Palladium Jul 23 '12 at 21:50
  • Awesome .. Where should I be saving these logs? My theory is that anyone smart enough to get in is smart enough to `edit/erase` logs... – MrPizzaFace Jul 23 '12 at 21:53
  • @FabioAnselmo You're on a shared server, right? The logs will be created on the server. If someone's good enough to get into the *server*, well... let's just say that your personal admin page getting exploited will be the least of everyone's worries. (Also, if it deals with confidential information, you can probably sue your host's ass off - just don't quote me on that one.) – Palladium Jul 23 '12 at 21:56
  • lol - The SSL offers a warranty. I def need the info to be secure. I'm thinking of switching to Site5 - Do you have any experience with them? – MrPizzaFace Jul 23 '12 at 21:59
  • @FabioAnselmo None whatsoever. Sorry 'bout that. – Palladium Jul 23 '12 at 22:00
  • Its cool. Thanks for the all help and great info. If you're in NY or ever come to NY => hit me up i owe you a beer :) – MrPizzaFace Jul 23 '12 at 22:01
0
  • Have you also set the secure, domain and http only flag on your cookies?

my login script checks for regex prior to sql and my credentials are stored in a separate admin table

And please, don't use mysql_* functions for new code. They are no longer maintained and the community has begun the deprecation process. See the red box? Instead you should learn about prepared statements and use either PDO or MySQLi. If you can't decide, this article will help to choose. If you care to learn, here is a good PDO tutorial.

P.S. as far as I know the $_SERVER['REMOTE_ADDR'] variable would be pretty safe to use, because the only way I see that being exploitable is by an attacker proxying through your machine or spoofing the ip. And (correct me when wrong) both are pretty hard to do.

P.S. 2:

Is see you are using global in your code, also please stop using that :-) For more information about this watch this talk about dependency injection and SOLID programming in general. Nothing to do with security, but simply best practices for programming.

Community
  • 1
  • 1
PeeHaa
  • 71,436
  • 58
  • 190
  • 262
  • For brute forcing I block a reCaptcha is used if failed attempts exceed 3 -- assuming someone is able to emulate my IP – MrPizzaFace Jul 23 '12 at 21:41
  • I wrote a function to escape bad data and regex is padded to it – MrPizzaFace Jul 23 '12 at 21:41
  • @FabioAnselmo So you aren't using prepared statements? – PeeHaa Jul 23 '12 at 21:43
  • Hey sorry for the delay.. I am using mysql_connect.. not a PDO or mysqli.. By prepared statements I'm guessing you mean OOP PHP? – MrPizzaFace Jul 23 '12 at 21:49
  • @FabioAnselmo Please stop using `mysql_*` functions. And start reading the links in my answer. Escpecially the one about prepared statements, but the others will also do you good I think. – PeeHaa Jul 23 '12 at 21:51
  • Great thanks for all the links.. Btw if NULL is in NY lol -- let me know and I'll buy you a beer sometime.. – MrPizzaFace Jul 23 '12 at 21:54
  • I'm Dutch, but when I'm ever going to NY I'll ping you so you can by me a beer ;) – PeeHaa Jul 23 '12 at 21:56
  • For the purpose of this application which is 85% complete - Switching everything over to `PDO` or `MYSQLi` using prepared statements is a big job. From reading through your post link - I don't see how this is any different from using specific `REGEX` - Please correct me if I'm wrong but how can a hacker exploit a field like this: `if(preg_match('/^[A-Za-z]{2,30}$/', stripslashes(trim($_POST['f_name'])))) { $fname = escape_data($_POST['f_name']); } else { $fname = FALSE; }` I will definitely use PREPARED statements in future versions but am I risking security here? – MrPizzaFace Jul 23 '12 at 22:15
  • If you use that you are limiting what you can use in a query, so you are also limiting the characters you can use for your password. – PeeHaa Jul 23 '12 at 22:23
  • well that is for a first_name field on a form. But I use similar expressions on all fields and specific to the field. So isn't that just like using a prepared statement? – MrPizzaFace Jul 23 '12 at 22:25
  • No. With prepared statements the statement and the values are sent to the server separately and a possible attacker doesn't have any change to inject his/her malicious SQL. I've also started on a PDO tutorial (which I didn't have time to finish) if you are interested: http://pieterhordijk.com/tutorials/sql-and-php-done-the-correct-way-tm – PeeHaa Jul 23 '12 at 22:28
0

Make sure you uses prepared statements for SQL, use brute-forcing protection (in cases someone gets a proxy on your PC) and do not use SHA2. SHA2 is a terrible, useless method for hashing passwords. Look into the crypt function or use pkbdf, or at the very least; a primitive sha512. (see the "hash" function)

Lusitanian
  • 11,012
  • 1
  • 41
  • 38