Security and throwing an Exception - php

I wrote a function that gets the balance from PayPal.
To connect properly I'm passing the user, password and certificate as parameters.
Every thing looks ok until something throws an Exception inside and php prints all the parameters (user details in this case) on the stacktrace.
I'm logging everything to a file so users wouldn't be able to see it anyway but I'd really like to know how to hide sensitive information from the stacktrace. To be true, I don't even like the idea of having it printing out passwords to log files...
Thanks for your time and help :)
Cheers,
Diogo

If it's php that is throwing an exception, can't you catch it within a try/catch block ?

Catch the exception, then handle it rationally without exposing the information. For example, you could log the fact that there was a PayPal exception and display a message along those lines to the user, but without showing the exception string itself.

Related

What values I can use for the $code property of a custom PHP exception [duplicate]

Okay, its a very lame question for many but I hope I will have overwhelming response :)
When I throw an Exception in PHP I can add a code to the message.
I catch an exception and handle it according to its type (Like InvalidArgumentException or OutOfBoundException). I log the message or display it or do whatever is suitable.
I can add also append a previous exception to trace a path to the origin of the error.
BUT one thing I have never used or never thought of: how useful is code?
For example:
throw new Exception("db Error", $code, $previousException);
What do I do with $code?
The message is for display to the user, while the code is for use by your program. So for example, in your "database error" example, you might make up a set of codes like
Can't connect
Error during query
Empty result
Error closing connection
and then use the appropriate code. Then when other parts of your code saw they exception, they would know what happened and could possibly deal with it intelligently.
How $code is interpreted is dependent on the exception type. For example, if you have an Exception subclass that represents a MySQL database error, then the $code could be the native MySQL error code. In the case of a low-level IO error, this could be a value from <errno.h>.
Basically, $code should contain whatever you need to programmatically handle an exception. Most exceptions are meant to be handled somewhere. If all of your exceptions are simply displayed as errors, then $code is only useful if you need to include an error code from a library like the MySQL client library.
I've seen implementations (CakePHP) where the $code is used as HTTP status code.
I've implemented that concept with a subset of exceptions. So all exceptions extending from HttpException which are thrown respond with HTTP errors
In object oriented languages, the type of the exception conveys what type of error it is. However, if for example you have two things that can generate the same exception type, the error code could be used to give more detail.
The error code is a widely used feature in non-object oriented language to convey what type of error it is.
I personally use the code to get a compressed error message, that user can send to the support. For example, let's say the user tries to authenticate, and he fails, my code throws an AuthenticateException with the message: Failed to authenticate, and a specific code referring to the real issue behind the failure. The user will only see the authentication message, and the code, thus not knowing what the real reason of the failed authentication was. He is then advised, that if needed, contact the support team with the code.
Based on the exception code, our support colleagues can easily pin-point what was the real reason for the failed authentication (invalid password, inexistent user-name, account was suspended, etc.) and may help the user accordingly.
Lots of good answers so far, but I'm surprised none have hit upon the core of what an error code really is.
You need an error code for the same reason you need an id column in a database table. It's a unique identifier for the exact error that happened.
The name of the Exception type is not the same. For example:
There could be multiple variations or causes of an exception with the same type. The error code might give you more information if you look it up than just the type of error.
When you manually throw an error in code, there's a lot of positives to being able to pass a custom error code with it. You might want to identify the exact error or place in the code it happened without creating a new type for every exception in your code example.
When you need to check an error object for what error happened, doing a simple if ($error->code === 201) is a lot easier than checking the type or comparing error message strings. If you don't want to use 201 in your code because it doesn't convey the error, it's also really easy to assign it to a constant.
If you want to log information about an error in a database, having a unique identifier is a lot easier to work with in a database. And then when you pull it out of the database to work with it in code (no longer in an Exception object), it's again easier to identify the error by an error code and work with it that way. If you store something like a class name in the database, what if someone puts it in the database with camelCase as opposed to PascalCase, or they remember the exact name wrong, or they have a typo, etc. Even if you use an enum, what if you need to interface with a different database that might have used a different format?
If you give an error code to a user in your application, and he goes to a page with a list of errors, it's a lot easier for him to find the exact error with an error code than to look through text descriptions of the error. It's also easier for them to find it in a search engine.
Basically having a global error code makes it easy to store, reference, pass, compare, change formats without losing information, share code and data with others, create custom errors, etc. Most things that apply to storing data in a database with a unique id also applies to storing an error with an error code.

How to differentiate between error exceptions and fatal exceptions in CodeIgniter?

I want to use two different kind of exceptions in my project:
Fatal exceptions. If something goes unexpectedly wrong, like a mysql query fails, I want to throw this kind of exception, without necessarily having to catch it. This exception means that I need to take some action, like logging a message, then showing an error, using CodeIgniter's show_error() function. The script should exit without continuing.
Error exception. If a user does something not allowed, such as enters letters into a numbers field or accesses a page he doesn't have permissions for, this exception should be thrown and caught.
I want to use both kinds of exceptions throughout the project. Number 2 is clear enough, but how do I go about doing exception 1? It would be great to not have to have two catch blocks for every try block, as the 1st type is global and should always be the same: log message, show error, exit. And lastly, in codeigniter, where would be the correct place to extend the Exception class?
Thanks.
Fatal Exceptions
The link posted by Sunil above is great for globally handling Fatal Exceptions. You want to be very careful about throwing these exceptions, and be sure that to the end user, the site doesn't look scary and broken - humoring the user is always a good idea.
Error Exceptions
I think you would be better off not treating errors like text in a numeric field as exceptions, because they do not disrupt the normal flow of the program's instructions.
If a user enters an alpha into a numeric field and submits the form, your application should expect that a user may provide junk data, and you repeat the input process, which is the normal flow.
Here is how I handle scenario 2 in code igniter:
Extend CI_Log with /application/libraries/MY_Log
Add MY_Log::$logs to store messages in array if log level permits
The template hook gets the logs MY_Log::get_logs() then passes them on to the view that displays the appropriate message boxes for the log levels
I also implement a custom log level called error_log. This is for anything that I want to send to the log file without showing the user.

How to catch and log every PHP and JS error in production website?

I have a website that's written in PHP and uses intense level of JS coding. One of my clients has a very strange error. The site is empty and nothing is displayed. I can not reproduce the error in spite i use the same browser, the same OS and have much the same addons and firewall and antivirus.
So i would like to catch every one PHP and JS error or warning and put it in the error log (best - to database). Is there any ready, simple solution to acomplish this? I address this question to experienced web-developers.
Or is there any way to dump every data about user session while the error occurs that is easy to acomplish by no-tech user? I see it this way: when the user has this error, he clicks something (for example in extension or something) and this sends all session, error informations to me so I can figure out what is going on. Do you know any solution of this kind?
mplungjan's idea is good.
I would also ask the client to view the source of the page and send that to me to make sure it looks OK.
Your web server (e.g. apache) should keep a log file of every single PHP request and tell you whether errors occurred.
I don't know if there is a way to report javascript errors back to your server. If you were able to catch the error and send an AJAX request in your error handler to get logged on your server, that would work. But I think that some javascript errors (like syntax errors?) can not be caught with catch. I would ask the client to open the javascript console (or whatever it is called in his browser) and tell me all the errors he sees. You should eliminate all the errors eventually, and a good strategy to do that would be to focus on the first error that occurred.
I would run the page through a w3c validator to see if it is valid HTML/CSS.
Also, you should try the universal technique of simplifying the code down to the simplest possible thing that should work but doesn't work. That will either let you find the problem or produce something that is so small and simple that you can post it to Stack Overflow.
You need to differ between two types of errors: Client-side and Server-side.
A blank page can be both, but I would think most likely this is server-side.
For server-side errors you can log every error and even add own information like the session by registering your own error handler. You then can log errors into the database and append the session and request information as well as providing a backtrace. This will enable you to obtain more information.
For client side, David Grayson's answer has a suggestion.

What do we need the PHP-exception code for? Any use case scenario?

Okay, its a very lame question for many but I hope I will have overwhelming response :)
When I throw an Exception in PHP I can add a code to the message.
I catch an exception and handle it according to its type (Like InvalidArgumentException or OutOfBoundException). I log the message or display it or do whatever is suitable.
I can add also append a previous exception to trace a path to the origin of the error.
BUT one thing I have never used or never thought of: how useful is code?
For example:
throw new Exception("db Error", $code, $previousException);
What do I do with $code?
The message is for display to the user, while the code is for use by your program. So for example, in your "database error" example, you might make up a set of codes like
Can't connect
Error during query
Empty result
Error closing connection
and then use the appropriate code. Then when other parts of your code saw they exception, they would know what happened and could possibly deal with it intelligently.
How $code is interpreted is dependent on the exception type. For example, if you have an Exception subclass that represents a MySQL database error, then the $code could be the native MySQL error code. In the case of a low-level IO error, this could be a value from <errno.h>.
Basically, $code should contain whatever you need to programmatically handle an exception. Most exceptions are meant to be handled somewhere. If all of your exceptions are simply displayed as errors, then $code is only useful if you need to include an error code from a library like the MySQL client library.
I've seen implementations (CakePHP) where the $code is used as HTTP status code.
I've implemented that concept with a subset of exceptions. So all exceptions extending from HttpException which are thrown respond with HTTP errors
In object oriented languages, the type of the exception conveys what type of error it is. However, if for example you have two things that can generate the same exception type, the error code could be used to give more detail.
The error code is a widely used feature in non-object oriented language to convey what type of error it is.
I personally use the code to get a compressed error message, that user can send to the support. For example, let's say the user tries to authenticate, and he fails, my code throws an AuthenticateException with the message: Failed to authenticate, and a specific code referring to the real issue behind the failure. The user will only see the authentication message, and the code, thus not knowing what the real reason of the failed authentication was. He is then advised, that if needed, contact the support team with the code.
Based on the exception code, our support colleagues can easily pin-point what was the real reason for the failed authentication (invalid password, inexistent user-name, account was suspended, etc.) and may help the user accordingly.
Lots of good answers so far, but I'm surprised none have hit upon the core of what an error code really is.
You need an error code for the same reason you need an id column in a database table. It's a unique identifier for the exact error that happened.
The name of the Exception type is not the same. For example:
There could be multiple variations or causes of an exception with the same type. The error code might give you more information if you look it up than just the type of error.
When you manually throw an error in code, there's a lot of positives to being able to pass a custom error code with it. You might want to identify the exact error or place in the code it happened without creating a new type for every exception in your code example.
When you need to check an error object for what error happened, doing a simple if ($error->code === 201) is a lot easier than checking the type or comparing error message strings. If you don't want to use 201 in your code because it doesn't convey the error, it's also really easy to assign it to a constant.
If you want to log information about an error in a database, having a unique identifier is a lot easier to work with in a database. And then when you pull it out of the database to work with it in code (no longer in an Exception object), it's again easier to identify the error by an error code and work with it that way. If you store something like a class name in the database, what if someone puts it in the database with camelCase as opposed to PascalCase, or they remember the exact name wrong, or they have a typo, etc. Even if you use an enum, what if you need to interface with a different database that might have used a different format?
If you give an error code to a user in your application, and he goes to a page with a list of errors, it's a lot easier for him to find the exact error with an error code than to look through text descriptions of the error. It's also easier for them to find it in a search engine.
Basically having a global error code makes it easy to store, reference, pass, compare, change formats without losing information, share code and data with others, create custom errors, etc. Most things that apply to storing data in a database with a unique id also applies to storing an error with an error code.

PHP - recording errors

What is the best way to record errors experienced by the user?
My initial thought was to make a function that recorded the error with a unique number and maybe a dump of the variables into a record on the database.
Is there a better approach? Should I use a text file log instead?
How about overriding the default PHP errorhandler?
This site should give some basic information: http://www.php.net/manual/en/function.set-error-handler.php and the first comment on http://www.php.net/manual/en/function.set-exception-handler.php
You might also want to store database errors, perhaps some kind of custom function that allows you to use code like:
<?php
$objQueryResult = mysql_query("query here") or some_kind_of_function_here();
?>
You might want to store the recorded errors in a file, which is outside your public html root folder, to make sure people can't access it by accident.
I would also assume, you'd want to store a complete stacktrace in such a file, because then you can actually debug the problem.
When overriding the default errorhandlers, please note you don't forget to send a nice message to the user (and exit the script, when needed).
I would recommend storing:
$_POST
$_GET
A complete dump of
debug_print_backtrace()
Possibly the SQL that triggered this?
I would suggest you to use debug_print_backtrace() to make sure you get a summary of data. The debug_backtrace() function gives about the same information, but it can sometimes just give you too much information.
The code you could use to catch backtraces:
<?php
ob_start();
debug_print_backtrace();
$trace = ob_get_contents();
ob_end_clean();
?>
To store this, you could use a plain text output, if you don't get too much errors, otherwise perhaps use something like sqlite? - Just don't use the same SQL connection to store the errors, as that might trigger more problems, if you're having webserver to SQL connection errors.
Well, at least writing to text files on the local system should be less error prone, thus allowing you to catch DB errors too :)
I would prefer to write a decent dump of the current state to a simple log file. In addition to your "own" state (i.e. your application's variables and objects), you might consider doing a phpinfo() to get inspiration as to which environment and request variables to include.
PEAR::Log is handy for this kind of logging. e.g.
$logger->alert("your message");
$logger->warning("your message");
$logger->notice("your message");
etc.
You can log to a file or to a database, I wrote a PDO enabled sqlite extension , pretty simple.
These are handy to put into exception handling code too.
PEAR::Log
Records: id, logtime, identity, severity 1-7( ie "Alert"), and your message.
I think #Icheb's answer covers it all.
I have tried something new this year in a project that I thought I'd share.
For a PHP based content aggregation / distribution service, an application that runs quietly in the background on some server and you tend to forget, we needed an error reporting system that makes sure we notice errors.
Every error that occurs has an Error ID that is specified in the code:
$success = mysql_query(this_and_that);
if (!$success) log_error ("Failed Query: ".mysql_error(), "MYSQL_123");
Errors get logged in a file, but more importantly sent out by mail to the administrator, together with a full backtrace and variable dump.
To avoid flooding with mails - the service has tens of thousands of users on a good day - error mails get sent out only once every x hours for each error code. When an error of the same code occurs twice within that timespan, no additional mail will be sent. It means that every kind of error gets recorded, but you don't get killed by error messages when it's something that happens to hundreds or thousands of users.
This is fairly easy to implement; the art is getting the error IDs right. You can, for example, give every failed mySQL query in your system the same generic "MYSQL" Error ID. In most cases, that will be too generic and block too much. If you give each mySQL query a unique error ID, you might get flowed with mails and the filtering effect is gone. But wWhen grouped intelligently, this can be a very good setup.
From the usability point of view, the user should not Ever experience errors.
Depending on the error you should make different strategies:
non catchable errors or difficult to catch from PHP, read the logs for each application
Apache
MySQL and DB errors, transactions
prepare php with "site being updated" or error controllers for emergencies.
PHP errors
these should be detected through Exceptions
silenced but not forgotten, don't try to fix them on the fly
log them and treat them
interface errors
an advice: allow user to submit suggestions or bugs
I know this does't cover all, is only an addendum to the others have suggested.

Categories