I'm writing an extension that pulls some data to an external site.
I'd wish to know what's the more reliable way to do that.
At the moment I'm using cURL, but since some hosting doesn't have that library installed, I'm using this method as fallback (fopen with stream_context_create).
However, sometimes it fails anyway, and I can't reproduce the error.
Do you know any other method? Is there room for improvement?
EDIT:
sadly no, I have no log since i have no problems on my tests. some customers are reporting that data is not sent, and I was wondering if there are a set of fallback actions, starting from the most common one (ie cURL) to a "last resort" one.
If you look hard enough, there probably are more options than the two you mentioned, but at some point the customer needs to have a decent host and not put the blame on you.
cURL
Most hosts provide cURL. Some will disable it, but it's easy to check for that.
fopen(url)
This can be disabled by the allow_url_fopen runtime option, which is also easy to check for.
You could get really creative and use external Perl scripts, for example, to do the work PHP cannot (per config), but what if the host has the external execution functions disabled?
I think it is sufficient to offer these two options, and then provide proper error handling so the customer knows it isn't going to work. It isn't a fair expectation for your script to run on every host. Just don't leave the customer seeing something didn't work and you didn't get them enough information to know it's their host's fault.
Related
I'm trying to understand the actual risks of allow_url_include, or find some practical alternative for this scenario:
Server A has a php-based web page, which fetches data from a number of remote servers (Servers B to J) about their current status. Server A then parses the data returned and displays a summary. The code to get the data and send it back is a PHP script which resides on Servers B to J, and as more servers are added, is becoming a pain to keep up to date - whenever a new feature is required on the summary page, that file must be updated on every server to match what the summary code expects to be sent back.
One obvious solution is to include the code to get data, so that the code on Servers B to J looks like:
include("http://ServerA/stats/getData.php.source");
echo base64_encode(serialize(getData()));
But pretty much every SO question regarding allow_url_include just says "Don't do it". I've struggled to find specific risks associated with this, and how to mitigate them.
The goal here is to have all the code on Server A, so that maintenance / feature additions become much easier to handle. An nfs mount might be practical, but seems a little excessive for a single file. Writing a script on Server A to use ssh to push new code to each server is also a possibility, but would slow down the development cycle.
There are no other developers on Servers B to J, so is allow_url_include really such a risk? What else could it do?
If the application layer and system layer are BOTH secured to an extent that you believe no one can get in - then there is nothing wrong with allowing something like allow_url_include
This can be extremely complicated, as you will need a layer on the outside of your application monitoring incoming requests. However it is not impossible!
Other things to help :
PhpSecInfo
theDevShed
Unless you are 100% sure you can secure your server to a more than reasonable level then I would suggest using an alternative such as cURL instead.
I have a hobby wesbite written in PHP and I like to know if there is a problem with it (database errors, an update broke something, etc.) I have a simple notification system which sends me an email if there is a problem and that would be enough for me. Unfortunately, the mail sending feature of the hosting provider is not very reliable. Usually it works, but there are periods when it simply swallows the mails and doesn't send anything.
Is there some other reliable method for notification of the maintainer in case of an error? It's a hobby site, so I'm looking for something simple. Not an industrial strength solution, but something more reliable than email. How do you monitor your hobby sites?
I tagged the question with PHP, because the site is written in it, but I'm also interested in generic suggestions, not just in concrete PHP solutions.
EDIT: the question is about the mechanism of active notification. I want to be notified when something happens. If PHP email is not reliable then what are the other possibilites of notification?
EDIT2: two examples to illustrate what kind of solutions I'm thinking of:
Store the errors and provide a page listing the latest errors (maybe password protected) which would be polled from my computer which could pop up some window if there is an error. It can work, but it works only if I'm at my home computer.
Use google calendar api to insert an event into it when an error occurs, and google calendar will send me an email reliably. It may work, though it's cumbersome.
some other idea?
Are you looking only for email based alerting systems? If not, you should try Notifo. You can use their API to push notifications and it'll be instantly sent to your phone.
PHP has an error_log function for returning errors in various ways, either via email to an admin, to the servers log file or to an external file. I assume that you could merely substitute this functionality for your mailto when you find an error:
http://php.net/manual/en/function.error-log.php
I've run into the issues you've mentioned with my hobby project as well. When I started I was using GoDaddy who's mail relay was pretty unreliable for delivering mail in a timely fashion.
Two things I'd suggest:
For sending email messages with higher reliablity, check out Postmark. Its a paid solution, but the rates are pretty reasonable and it comes with PHP classes you can hook your code up to fairly easily.
For custom error handling, check out PHP's set_error_handler(). Its a good way to have custom code execute on error conditions on your site. From the documentation:
set_error_handler — Sets a user-defined error handler function.
This function can be used for defining your own way of handling errors during runtime, for example in applications in which you need to do cleanup of data/files when a critical error happens, or when you need to trigger an error under certain conditions (using trigger_error()).
Maybe give Airbrake (formerly Hoptoad) a try. This is a commercial service, but they have a basic free plan (tiny little link at the bottom of the pricing page), and the tool looks pretty cool. It's focused on Ruby on Rails but according to their site has plugins for various other frameworks and languages, inlcuding PHP.
http://airbrakeapp.com/pages/home
We have a system set-up that polls specific pages on our important websites every now and then and checks for certain strings. Would something like that be viable to you?
I am currently creating a website in php that has a database backend (can be either MySQL or SQL Server) and I realized recently that if my database crashes at any time, my website will not run properly and probably cause some headaches.
So what is the proper thing to display on the website if my database (or any crucial outside component) goes down? My particular website relies heavily on its database and will be almost useless without it.
One option I have been told is to email the website admin and display a Error 500 page that says something is wrong with the server and basically make the website unusable till the issue is fixed. Is there anything else I could do to work around this problem? Are there any ways to design a website so that the database (any crucial component) crashing isn't an issue?
I am looking for general rules of thumb as well as specific examples of how people have worked around this in the past. Also, these examples don't just have to be for my website example.
If you only have one database server, and the website cannot work without it's database, there is no magic : you'll have to display some sort of nice error page, informing the users there is a technical problem and that the website will come back shortly.
Generally speaking :
Chances of such a problem are pretty low
If your website is a normal one, people will tend to accept a problem once in a while, especially if you communicate about it.
If you can afford it (and have the technical knowledge to set this up), you could use two database servers, with replication (MySQL supports this) between them : one master, which you use, and a slave, that's considered as a backup.
Then, if the master falls, your application will use the slave.
Of course, this will greatly reduce the risks of a database-related problem (having two servers crash at the same time is quite unlikely), but you'll still have problems with all other components -- like your webserver : if you only have one, you might want to consider using two, with the second one as a fallback.
After that, if you still have money (and think you need an even better uptime for your website), you'll want to think about the case when your datacenter has a problem -- setting up server in two separate locations...
The proper thing to display is a simple "oops" error message that gives away no information that would be helpful to hackers. Something along the lines of "We're experiencing technical difficulties" or "website unavailable". This is for security purposes.
It would be good to have an error logging and notification system in place to notify an administrator in case of a crash. That would be fairly simple to write, but I'm sure there are already libraries that handle this. (There's a tutorial with code samples at http://net.tutsplus.com/tutorials/php/404403-website-error-pages-with-php-auto-mailer/ and a simpler example at http://www.w3schools.com/php/php_error.asp)
There are ways to design the architecture of your web site to handle a database component crashing. It's not architecting your website, it's architectin the whole environment. For example, database clustering for high availability (http://en.wikipedia.org/wiki/High-availability_cluster). It's not cheap.
Overall, you just need to ensure that you're doing your error handling properly. A database crash is a classic example ofr why we need error handling. There are plenty of resources and guidance for this.
http://www.google.com/search?q=Error+Handling+Guidelines&rls=com.microsoft:en-us&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1
Edit
I found this and thought it was a very nice resource for answering how to handle the errors:
http://www.nyphp.org/PHundamentals/7_PHP-Error-Handling
It is considered best practice to return a HTTP 500 status code in the event that your database being down, or any other crippled service, prevents your website from functioning properly. Depending on your websites functionality, this could be on a page by page basis or site wide. For example, your "About Us" page may not need database capabilities while your search page would. You could thus keep the "About Us" page up and running but return a 500 status code when someone goes to your search page.
Do not give any technical information about why the site is not working to the end user. This could be a security risk.
If you are using apache, this document will tell you how to setup custom error pages:
http://httpd.apache.org/docs/2.0/custom-error.html
I recommend you use plain HTML for your 500 status code pages. You can also have your PHP pages send a 500 status code via the header() function, documented here:
http://php.net/manual/en/function.header.php
While installing an application onto a client's server, I would like to make sure that the client (or a future developer for them, etc) does not copy my application and place it on other domains/servers/local servers.
How can I verify that my application is running on the server I installed it on? I do not want any substantial lag in the script every time it runs, so I assume a 'handshake' method is not appropriate.
I was thinking the script could request a PHP page on my own server every time it runs. This could send my server their server info and domain name, which my script can check against a database of accepted clients. If the request is invalid, my server handles the work of emailing me the details so I can follow it up. This should not slow down the client's script as it isn't expecting a response, and will still operate on their 'invalid' server until I can investigate this and follow it up with them personally.
If this is the best method (or if there is better), what PHP call should I be making to request my server's script? file_get_contents, curl and similar seem to always retrieve the response, which I don't need.
UPDATE
Thank you all for your responses. I completely understand that PHP is open source and should be freely available to edit. I should have stated more clearly initially, but my intentions were for this verification method to assist me in finding anyone breaching my license agreement. The application is covered under a license, but I would also like to include this check so that I can monitor an initial misuse of my application.
Hence, somebody may still breach my license and it would most likely go unnoticed, but if I implement this script I have the advantage of any 'lazy robbers' who don't break apart my application and remove the verifier before ripping it.
Does this justify the use of such a script? If so, is cURL my best option?
Any checking code for verification is easily replaced with a return true;. Look at the faq at https://stackoverflow.com/tags/php/info :
Q. Can I protect my PHP code from theft? If so, how?
A. There is no effective technical solution to protect, encode or encrypt PHP source code. There are many products that offer some levels of protection, but all can be broken with time and effort. Your best option is not a technical solution, but a legal solution in the form of a license agreement.
You get a legal agreement and sue everyone.
SaaS is your friend. Host the application on your own secure servers, and charge a license fee for your customers to access it.
imo its worth checking out some joomla extensions that do this. There a few different implementations, some check the domain and validate it before executing, most are encrypted, along with a domain validation. I remember sakic's url sef extension used to do this. There are quite a few more commercial extensions that use the same thing. Apart from that I cant think of another way.Probably another good idea is to have a good license in place and a good lawyer....
Short answer: This can't be done.
Long answer: Whatever protection you put in your code, it can be removed with little difficulty by anyone with some experience in PHP. Even if the code is encoded with something like ionCube or Zend Guard, this too can be decoded with relative ease.
Your only option is to protect your intellectual property by actively pursuing copyright infringers. Even this is not foolproof, as our folks from RIAA and MPAA know very well. In this day and age, I'd say this is not a solvable problem.
You could integrate phone-home behavior into your software but you should probably consult a lawyer to discuss privacy issues about that and to work out privacy guidelines and terms of use for your clients' usage license.
One thing to be careful about is the data you send (and the way you send it, i.e. securely encrypted or not) to identify the client who is illegally using your product because it could potentially be used to compromise your client's infrastructure or for spying on your client.
Regarding your phone-home function, be warned that the client could just locate and remove it, so using a PHP obfuscator or compiler might provide some additional protection against this (though any sufficiently determined PHP developer could probably disable this). Note that your protection will only act as a deterrent aimed to make the cost of circumvention
approach or exceed the cost for legal use.
EDIT:
As poke wrote in the question comment, you could move parts of your code outside the software installed at your client's site to your servers but this may backfire when your servers are unreachable for some reason (e.g. for maintenance).
In the end, I think that customer satisfaction should be valued higher than protecting your software from the customer, i.e. try to avoid protections that are likely to make your customers angry.
You could encode it and hard code a license file that would allow it to only work on the domain it was intended for (e.g. use ioncube or zend to encode a file that checks if the HTTP HOST is the intended domain without doing a handshake). You could then make that file required in all other files (if everything was encoded).
I asked a recent question regarding the use of readfile() for remotely executing PHP, but maybe I'd be better off setting out the problem to see if I'm thinking the wrong way about things, so here goes:
I have a PHP website that requires users to login, includes lots of forms, database connections and makes use of $_SESSION variables to keep track of various things
I have a potential client who would like to use the functionality of my website, but on their own server, controlled by them. They would probably want to restyle the website using content and CSS files local to their server, but that's a problem for later
I don't want to show them my PHP code, since that's the value of what I'd be providing.
I had thought to do this with calls to include() from the client's server to mine, which at least keeps variable scope intact, but many sites (and the PHP docs) seem to recommend readfile(), file_get_contents() or similar. Ideally I'd like to have a simple wrapper file on the client's server for each "real" one on my server.
Any suggestions as to how I might accomplish what I need?
Thanks,
ColmF
As suggested, comment posted as an answer & modified a touch
PHP is an interpretive language and as such 'reads' the files and parses them. Yes it can store cached byte code in certain cases but it's not like the higher level languages that compile and work in bytecode. Which means that the php 'compiler' requires your actual source code to work. Check out zend.com/en/products/guard which might do what you want though I believe it means your client has to use the Zend Server.
Failing that sign a contract with the company that includes clauses of not reusing your code / etc etc. That's your best protection in this case. You should also be careful though, if you're using anything under an 'open source' license your entire app may be considered open source and thus this is all moot.
This is not a non-standard practice for many companies. I have produced software I'm particularly proud of and a company wants to use it. As they believe in their own information security for either 'personal' reasons or because they have to comply to a standard such as PCI there are times my application must run in their environments. I have offered my products as 'web services' where they query my servers with data and recieve responses. In that case my source is completely protected as this is no different than any other closed API. In every case I have licensed the copy to the client with provisions that they are not allowed to modify nor distribute it. This is a legal binding contract and completely expected from the clients side of things. Of course there were provisions that I would provide support etc etc but that's neither here nor there.
Short answers:
Legal agreement, likely your best bet from everyone's point of view
Zend guard like product, never used it so I can't vouch for it
Private API but this won't really work for you as the client needs to host it
Good luck!
If they want it wholly contained on their server then your best bet is a legal solution not a technical one.
You license the software to them and you make sure the contract states the intellectual property belongs to you and it cannot be copied/distributed etc without prior permission (obviously you'll need some better legalese than that, but you get the idea).
Rather than remote execution, I suggest you use a PHP source protection system, such as Zend Guard, ionCube or sourceguardian.
http://www.zend.com/en/products/guard/
http://www.ioncube.com/
http://www.sourceguardian.com/
Basically, you're looking for a way to proxy your application out to a remote server (i.e.: your clients). To use something like readfile() on the client's site is fine, but you're still going to need multiple scripts on their end. Basically, readfile scrapes what's available at a particular file path or URL and pipes it to the end user. So if I were to do readfile('google.com'), it would output the source code for Google's homepage.
Assuming you don't just want to have a dummy form on your clients' sites, you're going to need to have some code hanging out on their end. The code is going to have to intercept the form submissions (so you'll need a URL parameter on the page you're scraping with readfile to tell your code that the form submission URL is your client's site and not your own). This page (the form submission handler page) will need to make calls back to your own site. Think something like this:
readfile("https://your.site/whatever?{$_SERVER['QUERY_STRING']}");
Your site is then going to process the response and then pass everything back to your clients' sites.
Hopefully I've gotten you on the right path. Let me know if I was unclear; I realize this is a lot of info.
I think you're going to have a hard time with this unless you want some kind of funny wrapper that does curl type requests to your server. Especially when it comes to handling things like sessions and cookies.
Are you sure a PHP obfuscator wouldn't be sufficient for what you are doing?
Instead of hosting it yourself, why not do what most php applications do and simply distribute the program to your client with an auto-update feature? Hosting it yourself is complicated, from management of websites to who is paying for the hosting.
If you don't want it to be distributed, then find a pre-written license that allows you to do this. If you can't find one then it's time to talk to a lawyer.
You can't stop them from seeing your code. You can make it very hard for them to understand your code, which is a good second best. See our SD PHP Obfuscator for a tool that will scramble the identifiers and the whitespacing in the code, making it much more difficult to understand.