123
-=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- (c) WidthPadding Industries 1987 0|663|0 -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=-
Socoder -> Web Development -> PHP security

Mon, 21 Mar 2011, 06:01
Afr0
PHP files can be downloaded, right? Or, no?
Is it safe to store the DB password and username in plaintext in PHP files? If not, what's the common way to do it?

What are some other security concerns that are common?

-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Mon, 21 Mar 2011, 06:15
JL235
No, they cannot be downloaded. The server knows to run the scripts rather then offer them as a download.

Yes, for websites it's ok to store username and password in plaintext in a PHP file.
Mon, 21 Mar 2011, 06:24
Afr0
Thanks!
Mon, 21 Mar 2011, 07:03
JL235
Although if someone is able to inject PHP into your site, then this is a danger.

SMF (small machine forums) offer editable PHP themes within their administration dashboard and this is very often an angle of attack for them (find out the password of an administrator and you can edit the PHP theme to allow you to do anything).
Mon, 21 Mar 2011, 10:30
HoboBen
Tumbler recently leaked their database logins (hardcoded into their PHP script) when a typo made the "<?php" part not parse, exposing the script as plain text.

A better solution is to have an .ini file stored in a place that is not publicly accessible (outside of your public html directory).

But it's not the biggest issue in the world.



-=-=-
blog | work | code | more code
Mon, 21 Mar 2011, 11:39
Stealth
Afr0 What are some other security concerns that are common?


The most common is poor handling of user inputted data. PHP developers tend to be terrible at verifying and securing it. If it's going in to the database, you should always escape it first (unless the datatype is int or you've verified perviously that it's an int or safely filtered string). However, theres no harm just escaping everything. You also want to strip out HTML and other things as necessary. Keep in mind where you're outputting this data and the languages involved. XSS is a big problem these days.

I personally run all inputted data through a regex expression that restricts which characters can pass through. I will only allow numbers for a phone number, email characters for email, and so on. For things like a text area, I strip all high bit characters.

-=-=-
Quit posting and try Google.
Mon, 21 Mar 2011, 11:58
JL235
As a general rule, make input SQL safe at the latest possible time (just before the DB) and make information coming out of the DB safe as early as possible (right as it comes out of the DB).

If you structure your code well then you can even do this automatically (this is what I do).

I'd highly recommend running your site on top of a framework which includes code for interacting with your database. It will make coding faster and easier in the long term, and should also make your input SQL safe by default.
Mon, 21 Mar 2011, 12:04
Stealth
On top of the suggestion of using a framework, I would like to point out that not following MVC was a big mistake of mine early on. It will make your life FAR easier to just do it from day one. Luckily, most frameworks follow MVC.

-=-=-
Quit posting and try Google.
Mon, 21 Mar 2011, 12:32
JL235
At the very least just don't roll the HTML and database code together. It becomes a nightmare if you ever want to change one or the other at a later date.

I recently worked on a site where the code was like this (actually worse as logical decisions about what to do next on the site were taken in the DB code too) and it made some tasks literally 5 to 10 times harder then normal.

For example if I wanted to change a small snippet of HTML then ideally I'd just find it, delete and write the new HTML in. Instead it becomes a chore of trawling through database code, picking it all apart, do a little seperating of DB from HTML, remove old HTML code, add new HTML code, ensure you haven't broken the database interaction!
Mon, 21 Mar 2011, 17:23
oscar
The biggest mistake most developers make is NOT assuming that all data is malicious unless it is the exact type of input they are expecting.

Example: your sites url looks something like this https://site.com/page.phpp?id=1245

The ID should always be a number. If it’s not a number assume it’s malicious.

As everyone else has said improperly escaping/sanitising user input is a BIG issue.

As far as a obscuring a DB username/password. I ALWAYS store my db credentials in a file that isn’t browseable (a level or two above the web root folder) and make sure it is never directly included in the files the user is accessing. That way if by some miracle the user can see the source code, they won’t easily be able to find the username & password.

|edit| https://cwe.mitre.org/top25/ - a good list of general programming mistakes & web developer mistakes |edit|
Mon, 21 Mar 2011, 18:21
CodersRule
One time O'Reilley had a sale for any one eBook for only $5, and I bought this:
https://oreilly.com/catalog/9780596006563
It was a pretty good read, because I had absolutely no knowledge of PHP security. Now I have some decent basic knowledge. I wouldn't say it's worth the current price, but it's still a good book.

I do agree with a quote from one of the reviews:
And then, with each progressive chapter, my attitude slowly changed from "yeah, yeah", to "hmmmm", to "oops".
Tue, 22 Mar 2011, 04:10
Afr0
Thanks guys!
As far as user input goes, there's no need for me to sanitize it, at least not yet. You have to log on in order to submit anything at all to the DB, and there really isn't any need for me to have a system whereby people can create their own users.
I might allow admins to create users though, just in case.
One thing I had to do was make sure that the three special characters in the Norwegian alphabet, 'æ, ø and å' were formatted properly.
I'm learning more about PHP everyday, and quite frankly much faster than I thought I would. I really like being back to non-OOP coding. It means I get to hack around alot more.

-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Tue, 22 Mar 2011, 04:18
JL235
Afr0 You have to log on in order to submit anything at all to the DB, and there really isn't any need for me to have a system whereby people can create their own users.

You should still sanitize the input. Even if it's just to ensure that admins can't accidentally mess up the DB.
Tue, 22 Mar 2011, 11:44
shroom_monk
Assume that everyone trying to access your website will be trying to break it, and distrust all inputs accordingly, until you have made them sure to be safe.

-=-=-
A mushroom a day keeps the doctor away...

Keep It Simple, Shroom!
Tue, 22 Mar 2011, 14:37
Stealth
Just do this with any variables that you use in queries. No need to get in over your head with sanitizing, especially if you're just starting out:



But do keep it in mind while you learn that it's highly important.

-=-=-
Quit posting and try Google.
Tue, 22 Mar 2011, 16:52
oscar
"As far as user input goes, there's no need for me to sanitize it, at least not yet. You have to log on in order to submit anything at all to the DB, and there really isn't any need for me to have a system whereby people can create their own users."

what happens if an admin tries to perform an SQL injection and deletes your user database? Sanitising every input is a good habit to get into, otherwise you end up like me and forget to go back and do it later
Tue, 22 Mar 2011, 17:30
JL235
It's also good practice to lock down the admins as well as users. If you don't need to do something, or shouldn't be able to do something, then prevent it. This is regardless of if this is an admin or a user.

Also what happens if a non-admin manages to login as an admin? That happened recently on JavaGaming.org and they had to rollback the whole site to a backup several months old (they had more recent backups but couldn't trust them because they were made after the first attack on the site).
Tue, 22 Mar 2011, 19:07
CodersRule
To sanitize user input in my code, I just do what Stealth said and hope to god it works. If they get by that, screw it, I'm too lazy to do anything about it. ^^
Wed, 23 Mar 2011, 03:03
Afr0
Thanks guys, I'm now using mysql_real_escape_string for all my queries.

Diablos: I've already locked down admins. When uploading magazines, you can only upload *.pdf and *.jpg files. I still need to implement a filesize limit though...

-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Tue, 21 Jun 2011, 14:06
spinal
Is the following a good method, or is it a little overkill?



I'm doing a simple(!) user register form, passing the details through POST in the same page.

-=-=-
Check out my excellent homepage!
Tue, 21 Jun 2011, 14:41
Stealth
Is the following a good method, or is it a little overkill?


Using trim() and stripslashes() is probably unnecessary. I would question the thoroughness of your code. If you're looking for robust filtering, take a look at HTML Purifier.

-=-=-
Quit posting and try Google.
Tue, 21 Jun 2011, 15:08
JL235
Tbh I see everything I used to do when I first started using PHP, and I no longer do any of that because it's quite a naive (and incorrect) way to do it. So here are some tips based on my experience.

Rejecting data based on format, and cleaning data to close security holes are not the same. Only reject data if it is in the incorrect format. Otherwise you allow it, clean it, and use it.

For example if you allowed usernames to contain any character, then '<script>' should be allowed. You then clean that when it's displayed so it doesn't open a script tag in HTML.

You can also clean by checking if the input is in a safe format, and if so convert to it. For example if you expect an integer, then check if it looks like one and then convert to it. Otherwise reject. No SQL injection is possible, yet you don't need to check for it.

Next how you clean depends entirely on what you are doing. You seem to be trying to fix all types of attacks in one function; don't. For example only use mysql_real_escape_string for data going into the DB. Clean for inlining scripts into HTML when you post content to a HTML page.

Don't apply everything to all types of data; you'll end up corrupting bits that don't need to be changed. It's also inneficient, and in a general case pipelining security functions can actually create security holes.

Finally is 'when do I clean'; it looks like your automatically altering all data comming in. This is a naive way to add security. Instead of cleaning as early as possible, in my opinion you should clean as late as possible. Again you should only clean in the way appropriate.

For me, I clean in one of 3 ways: html escape content when displayed (such as forum posts), drive all my SQL queries through my own code which automatically cleans values for SQL injection (unless otherwise stated), and I have special functions for grabbing values from POST/GET as an integer/boolean/float/some other type (and null is returned on failure).

Finally, I believe good security comes from a good architecture. To interface with the DB I have to use classes which by default escape all inputs; I have to do more work to disable this. To get input from POST/GET I have to use validation code, which automatically converts values to int/boolean/etc for me.

I hope that helps.