Some time ago I created this LAMP based web. At the time I wrote my own user authentication and access control system. It checks whether the user logged in with a correct password, and whether or not he/she has the correct permission level to access given page. State information is handled via PHP sessions while usernames, salted, hashed passwords and user level are stored in a MySQL back end. All the user inputs are sanitized and etc. Users must access the site wtith SSL.
The problem is that I'm starting to second guess myself and am becoming paranoid about security. So I'm looking for ways to improve it.
Can you give me suggestions for:
some comprehensive lists of security tests I could implement and run against it
best practices for implementing this sort of system
Is there a robust open source framework or library set that you could recommend using instead a home grown one? The conventional wisdom is that it is usually better to adopt a mature, tested system than write your own from scratch. What would you recommend?
1) Since you already wrote your own from scratch I would not throught it away and waste your time and effort to integrate a new external open source framework.
Code written by others might not be necessary better than your one, moreover you might not completly understand how to integrate it properly therefor you might add even more secuirty holes to your application.
2) This is a good and short 3 pages guide (unfortunately it's in italian, but you can use Google translator toolbar to translate the all pages)
Anyway from what you say you don't seem to be a newby to PHP programming, i would reccomend:
sanitizing input (but you said you did)
using at least addslshes (or mysql_real_escape_string) when playing with the DB
php.ini config: REGISTER_GLOBALS should be Off
careful about how you set the ERROR_REPORTING, it might prints out private data when encounters an error
The Zend framework has authentication built into it although Zend tends to be a bit bloated. It is possible to use only bits and pieces of Zend but I've never tried using just the Authentication bit.
There are also a couple of authentication libraries in PEAR - PEAR::Auth which is in a stable release and PEAR::LiveUser which is in beta and was last released (as beta) in 2008.
I hope that gives you a good start.
Related
I am thinking about selling Magento modules on my website and need your advise what would be the best way to do it.
Here is what I thought:
Install Magento store on my website
When client purchase the module from my store - he is required to enter his domain name
If order is successfully processed and payment is received - Magento or standalone script encode purchased module using ionCube or Zend Guard "On-The-Fly" and generates license to work on provided domain name only.
Is there a script that can do all of this? Or should I write my own code? What do you think about encoding scripts in order to protect your work?
Any thoughts and suggestions are welcome.
Thanks
This is really a matter of opinion and debat-able, however below is my feeling towards such:
Disadvantages of encrypting your code:
Obviously: It is (almost) impossible to modify or extend for custom
needs, without having to contact the original developer which adds
more cost to your end user as well as causing more time for “custom”
development.
3rd party server software like Zend Optimizer is needed
in order to execute the encrypted code. Which can be a headache by
itself.
Confusion during transfer for binary and text data, ultimately
corrupting your binary encrypted data.
It is impossible to have others
contribute to your code to improve it, and/or help with bug finding
and fixes.
As a store owner or maintainer I’m less confident you are
not utilizing any of my data collected from my stores.
Maintenance
becomes chaotic. Having to re-encrypt every release, can be quite
pain staking. This is especially true if you have a bug fix that
needs to be offered to all of your customers using it – however, the
ones with “Custom” versions will require re-encryption for all.
Unless your using some kind of release management that handles this
automatically for you. Most don’t I’m sure.
Full article: http://www.molotovbliss.com/magento-module-developers-stop-encrypting-and-domain-jailing
With that said, I've changed my mind on phone home calls. Since I've posted this article.
I'm okay with modules making phone calls home to a developers site to check for licensing, if you have a simple observer that did such and was done properly (By properly I mean don't break my site because your phone home server is down, and don't make my end users wait for the validation), I wouldn't see any problem with obfuscating this portion of code as long as it didn't interfere with the modules overall functionality, i.e., it is strictly there for checking a license, no module functionality encrypted. I believe Boris (unigry) does such and works well, even though I've had to jump through many hoops at times to get ionCube loader working on different environments, so this still something to consider not doing, and just having hope in peoples integrity and honesty to not pirate.
With that said, domain wide acceptance should be standard, I shouldn't need to send in support requests to get my subdomain added to your white list of domains. Personally if you can obfuscate and encode without the need of an apache/php module is a huge plus. General end users won't know where to remove such code at times.
To answer your question, a home brew script and process would be ideal, as using a cookie cutter solution would be easier to reverse engineer.
I'm thinking of protecting my script to the mass majority of users (non-web dev savvy) and I came across an online service to encode php script. I'm not sure about it though.
Is it safe to encrypt php script? What if the encoded code has something fishy in it?
If you intend to distribute the PHP file then I would suggest that you do not do this. It's only going to irritate those that want to tinker with it.
If for some reason you don't want them tinkering with it, then don't distribute the PHP file.
If you need to distribute the file AND you don't want them tinkering with it, then I would highly suggest you not do this in PHP and instead write the functionality using C as an extension to PHP.
You'll notice that at no point do I suggest you actually go ahead and "encode" the php file. That's not going to buy you anything.
If you are looking to obfuscate your server-side PHP, the best bet would be to use a commercial product such as Zend Guard (http://www.zend.com/en/products/guard/). Any home-brew encryption is not secure in the slightest - your code can be easily reverse-engineered with fairly trivial effort. The page you link to does not have any credibility, it is just someone's side project. They have no accountability or stake in protecting your information.
Even these commercial products (Zend Guard, ionCube, phpShield, SourceGuardian) can be decrypted if someone really, really wanted to. No tool or technique in any language can make absolutely secure obfuscation, there is no "unhackable" system. Everything boils down to effort over time.
If it isn't important enough to bother doing it right, then you're probably wasting your time on the issue. Further, if it is absolutely vital that some information or code remain private, you should simply not put it out into the public purview.
[edited for clarity]
Ultimately, you need to trust the encrypting party. If you don't trust them (apparently you don't), then don't give them access to your server (through executing their decryption code/your obfuscated code, possibly with who-knows-what else inside). Simple as that, albeit possibly inconvenient.
php is usually running on the server where the users have no access to the code(neither source nor any other representation) anyways. No reason to obfuscate it there.
Obfuscating php is only useful in the rare cases where you give the php code to clients. For example if you want clients to be able to run their own server but not give them full access to the code.
So, it looks like all it does is obfuscate the code so it's not human-readable. The only way this would really be useful is to prevent lazy people who have access to the code from reading it. However, it uses simple functions to encode/decode, so it would be trivially easy for someone to decode it if they have access.
Which brings me to my point... PHP security works by not allowing anyone to have access to the source file. If someone who shouldn't have access gets it, then this "encoding" thing isn't going to do you any good.
The OP mentioned an interest in protecting database connection details, and it should be kept in mind that no matter what protection system is used for the code itself, the PHP engine and component libraries being opensource sets some absolute limits on what can be achieved. If MySQL connection details, for example, are hidden in a script then these details could be trivially revealed without going near the PHP scripts themselves simply by running the scripts with a PHP build that had slight modifications to the MySQL library or the associated PHP module wrapper. Even hiding the details in a C module as suggested by Chris L. would afford no extra protection in this case. Good protection can certainly be given to source code with compiled code systems such as ionCube and Zend, but wherever data hits routines in the PHP core then it can be exposed.
Obviously for any online service where you may be sending sensitive details, you should use due diligence and make best efforts to ensure that it has a good pedigree. Apart from anything else, not having a working https URL for the site the OP questioned should immediately warn that it's a no-no, and not just for the lack of connection encryption but showing that they are not offering a service that they consider to be serious.
For the past three months I've been working for an Indian NGO, doing some volunteer work in the field but also trying to improve their website, which needs a ton of work. Recently I've been trying to fix the "subscribe to newsletter" button, which is broken. I used filter_var to filter the email input, but when I tried to test this out I got an error. Then I learned that the web host is still using php version 4.3.2 and register_globals is turned on.
I've mentioned that they should upgrade their web host before. That would add a lot of complexity for the IT staff of 3, who would have to update everyone's email information (I assume? this is a 250-person organization), and have me find a new web host and teach them about it. The staff isn't that sophisticated about web usage - the head guy still uses IE6, and the website's laid out in tables (they use Dreamweaver WYSIWYG to lay out pages).
So I've got two options - use regular expressions to filter the email, which I'm not that skilled at doing (and would be more vulnerable to exploitation after I leave), turn off register globals and then try to teach the staff what I'm doing, or try to get them to upgrade their versions of PHP and MySQL and/or change web host. I'd appreciate some advice.
Thanks for your help,
Kevin
First, I'd make the application run properly and as safely as possible in that environment, with regexes if necessary.
Then, I'd talk to the IT people. They need to upgrade their web package at some point and that point is already long past. PHP 4.3.2 is out and not supported any more at all (see here). That means that if a vulnerability is detected, it's not guaranteed to get a fix (altough it's still pretty likely due to the number of hosts not having switched yet).
Better do the switch now than later.
It's not really clear from your description how the people in the organization use E-Mail (do they have their own mail clients? Do they use web mail) but if they use their own mail clients, the "only" issue will be moving the mailboxes to a new host.
While that may take a few painful days to move all the mailboxes and redirects, and get everything running - including setting up everybody's workplace with the new data - it is not impossible to do, and will hardly add any long-term strain.
What I would do :
- fix your main issue asap : parse the email using a regexp, you can find some quite easily with google
- Discuss with the team about upgrading/migrating your host. Fixing the email problem first is allowing you to take your time in this matter.
I won't turn off register globals, because you might face many more problems on the other pages of the website. But this can remain in your 'todo list' as it would be a good update.
If security is a real big deal, then you need to introduce a layer to tackle intrusion. There are a few options in PHP land, but they all seem to require >5.1.4. Therefore I'd look at maybe installing mod_security if the web server layer is running apache. That way your application will be protected not just from POST injections, but GET injections and COOKIE exploitations as well. Secondly it'll future proof the application if next week they add another form to it without your knowledge.
It does sound though as if you've got your hands tied, and I'll be honest with you, if the company holds, or intends to hold any personal information about their users, or sensitive information about the company in an area accessible by the application, security is not a series of hacks or hotfixes, it's a serious commitment to a graceful and correct solution.
Best of luck.
The standard regex to check for RFC822 compliance is VERY ugly:
/^(?:[A-Za-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")#(?:(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[A-Za-z0-9-]*[A-Za-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/
from http://www.regular-expressions.info/email.html (hopefully it cut/pasted ok).
But implementing this will just delay your pain. A webhost still living in the register_globals = on days should be dumped as soon as possible. It's just begging to be subverted.
It is pretty standard practice now for desktop applications to be self-updating. On the Mac, every non-Apple program that uses Sparkle in my book is an instant win. For Windows developers, this has already been discussed at length. I have not yet found information on self-updating web applications, and I hope you can help.
I am building a web application that is meant to be installed like Wordpress or Drupal - unzip it in a directory, hit some install page, and it's ready to go. In order to have broad server compatibility, I've been asked to use PHP and MySQL -- is that **MP? In any event, it has to be broadly cross-platform. For context, this is basically a unified web messaging application for small businesses. It's not another CMS platform, think webmail.
I want to know about self-updating web applications. First of all, (1) is this a bad idea? As of Wordpress 2.7 the automatic update is a single button, which seems easy, and yet I can imagine so many ways this could go terribly, terribly wrong. Also, isn't the idea that the web files are writable by the web process a security hole?
(2) Is it worth the development time? There are probably millions of WP installs in the world, so it's probably worth the time it took the WP team to make it easy, saving millions of man hours worldwide. I can only imagine a few thousand installs of my software -- is building self-upgrade worth the time investment, or can I assume that users sophisticated enough to download and install web software in the first place could go through an upgrade checklist?
If it's not a security disaster or waste of time, then (3) I'm looking for suggestions from anyone who has done it before. Do you keep a version table in your database? How do you manage DB upgrades? What method do you use for rolling back a partial upgrade in the context of a self-updating web application? Did using an ORM layer make it easier or harder? Do you keep a delta of version changes or do you just blow out the whole thing every time?
I appreciate your thoughts on this.
Frankly, it really does depend on your userbase. There are tons of PHP applications that don't automatically upgrade themselves. Their users are either technical enough to handle the upgrade process, or just don't upgrade.
I purpose two steps:
1) Seriously ask yourself what your users are likely to really need. Will self-updating provide enough of a boost to adoption to justify the additional work? If you're confident the answer is yes, just do it.
Since you're asking here, I'd guess that you don't know yet. In that case, I purpose step 2:
2) Release version 1.0 without the feature. Wait for user feedback. Your users may immediately cry for a simpler upgrade process, in which case you should prioritize it. Alternately, you may find that your users are much more concerned with some other feature.
Guessing at what your users want without asking them is a good way to waste a lot of development time on things people don't actually need.
I've been thinking about this lately in regards to database schema changes. At the moment I'm digging into WordPress to see how they've handled database changes between revisions. Here's what I've found so far:
$wp_db_version is loaded from wp-includes/version.php. This variable corresponds to a Subversion revision number, and is updated when wp-admin/includes/schema.php is changed. (Possibly through a hook? I'm not sure.) When wp-admin/admin.php is loaded, the WordPress option named db_version is read from the database. If this number is not equal to $wp_db_version, wp-admin/upgrade.php is loaded.
wp-admin/includes/upgrade.php includes a function called dbDelta(). dbDelta() scans $wp_queries (a string of SQL queries that will create the most recent database schema from scratch) and compares it to the schema in the database, altering the tables as necessary so that the schema is brought up-to-date.
upgrade.php then runs a function called upgrade_all() which runs specific upgrade_NNN() functions if $wp_db_version is less than target values. (ie. upgrade_250(), the WordPress 2.5.0 upgrade, will be run if the database version is less than 7499.) Each of these functions run their own data migration and population procedures, some of which are called during the initial database setup script. Nicely cuts down on duplicate code.
So, that's one way to do it.
Yes it would be a security feature if PHP went and overwrote its files from some place on the internet with no warning. There's no guarantee that the server is connecting correctly to your update server (it might download someone code crafted by someone else if DNS poisoning occured) - giving someone else access to your client's data. Therefore digital signing would be important.
The user could control updates by setting permissions on the web directory so that PHP only has read access to the files - this procedure could simply be documented with your program.
One question remains (I really don't know the answer to): can PHP overwrite files if it's currently using them (e.g. if the update.php file itself needed to be updated)? Worth testing.
I suppose you've already ruled this out, but you could host it as a service. (Think wordpress.com)
I'd suggest that you package your application with pear and set up a channel. Your users can then upgrade the application through a standard interface (pear). It's not entirely automatic (unless the users have some kind of automation running on top of pear), but it's standard, so any sysadmin can maintain it.
I think your best option is an update checking mechanism that will alert the administrator when there are update(s).
As you mention, there are a number of potential security problems. Due to those alone, I would suggest not doing this. Instead, try creating a fairly smart upgrading script.
Just my 2 cents: I'd consider an automatically self updating application within my CMS as a security hole, so if you decide to code this feature, you should consider to implement different levels of this behavior:
Automatically update
Check for updates and notify
Disable
We've got a large classic asp application and we consider migrating to either asp.net or php. I don't want to talk about the pros and cons of either one, but I'd rather like to know whether there are ways to avoid a complete rewrite in one shot when migrating to php. We simply can't stop maintaining the current codebase just to do a rewrite. So things have to go hand in hand.
If we'd move to asp.net, we should be able share session data among both technologies and have parts of the site replaced with new asp.net code, while other just keep on running. Is such an approach possible with php? Does anyone has got experiences with such a migration or could point me to some good readings?
The ability to share session state between ASP Classic and ASP.NET isn't an intrinsic feature of either language, though it's fairly easy to accomplish.
Microsoft provides sample code:
http://www.google.com/search?client=safari&rls=en-us&q=share%20session%20data%20between%20ASP%20and%20ASP.NET%20pages&ie=UTF-8&oe=UTF-8
By using Microsoft's example, you could pretty easily implement something similar in PHP. Basically you'd use the ASP Classic portion of Microsoft's code above. Then in PHP you'd write a fairly simple class to read session state from the database into an array or collection when each page is loaded. It's a little extra work in PHP, but shouldn't be more than a few extra days of coding and testing.
PHP runs pretty well on IIS6 in my limited experience and support for it is supposedly even better in IIS7. The only snag I've hit in is that a most of the PHP code out there assumes you're running on Linux/Unix... but generally this is only an issue for file-handling code (think: user image uploads) that works with local filesystem paths. Because they assume your filesystem uses / instead of \ like on Windows. Obviously fairly trivial to fix.
Good luck!
Yes; it is possible to share session data between ASP and ASP.NET pages on a single web application. We do that with our legacy code at my work.
I know it's possible to run PHP on the IIS. Not sure about sharing sessions between ASP and PHP scripts though.
"I'd rather like to know whether there are ways to avoid a complete rewrite in one shot when migrating to php"
Welcome to our world.
Our FogBugz codebase was written in classic ASP and when we wanted to offer it on Linux, the simplest solution was to write a compiler which read the asp and emitted php. It wasn't that difficult, and didn't take more than a few weeks.
The upside was when we decided to switch our entire application to .NET it only meant tweaking the compiler a bit to output .Net object code.
But to get back to your answer, ASP and PHP are VERY VERY similar and depending on your app there are really naive translators that might get you most of the way there.
Just another option. John Booty has a good suggestion too.
If the session data isn't sensitive information you can work cookies which will also be platform agnostic pending the user has cookies turned on.
That's probably not your best option given the post but another to think about.