Issues

ZF-12074: Passwords printed in plaintext on PDOException

Description

When using the postgres PDO and I supply a password but no user name in the application.ini, I get a PDOException (this is to be expected). However the exception message prints the sql server password in plaintext. For security concerns, stack traces should never print a password in plain text.

Ideally, the stack trace should be scrubbed like in Zend_Auth_Adapter_Ldap (~Line 372), see ZF-11839.

Example 'admin' password below:

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[08006] [7] fe_sendauth: no password supplied' in E:\build\console_sep12\lib\Zend\Db\Adapter\Pdo\Abstract.php:129 Stack trace:

0 E:\build\console_sep12\lib\Zend\Db\Adapter\Pdo\Abstract.php(129): PDO->__construct('pgsql:host=loca...', '', 'admin', Array)

Comments

After discuss this with the community, I don't think this is something we care to implement. I can't speak for the Ldap specific use case, but in this particular case, attempting to scrub an exception stack from a method call that clearly failed has the potential to create a situation that would leave a developer with fewer facts to rectify the situation.

For example, if someone mistyped the password in a configuration file, but kept getting exceptions thrown in their development environment (about not being able to connect), it is clearly helpful to have the exact unadulterated stack trace in order to rectify the problem.

In addition, a developer should never be displaying exception messages to the screen during production (this is synonymous with display_errors = On. In ZF1 applications, displaying exception messages is turned off during production, and turned on during development. This should suffice for never having the password on the screen in a production environment.

Here is the situation I am in. We deploy a product that uses Zend Framework on our customer's system. If a customer has a problem, they may need to turn on debugging. Our customers are primarily High security environments (Banks, Govt, etc). These customers have a very strict policy against printing passwords in plaintext, even in a test environment, for any reason, including "test" users.

ZF really needs to do a better job of maintaining password secrecy.

In the meantime I will find and identity every area a password printed in the clear might happen, and wipe the stack trace. Which leaves me with NO facts to solve an issue.

There are a number of better options than "scrubbing a stack trace".

  • Turn on debugging for a particular IP address,
  • Print the stack traces to a file with a corresponding "error number" on the screen,
  • Mail the stack trace to the person who turned on debugging,

Ultimately, displaying any kind of stack trace to a customers screen in production is not generally considered a best-practice approach to application fault management.

If it is a Zend Framework v1 Application, all you simply need to do is alter the ErrorController with your custom logic for handling these issues, the stock ErrorController is simply there as just that, a starting point or a place for better/custom error/exception handling.

The feature you're asking for, to implement carte-blanche for all ZF1 users is overreaching as it assumes that all ZF1 users want and need this feature. At this point, we don't have the resources to track this kind of new feature in ZF1. Since I am developing ZF2's Zend\Db currently, I will bring it to the community and discuss as a feature for ZF2. I suspect it will not be well received, but I could be wrong.

In your test environment, another possibility (if you are using Zend Server) is to use the Zend Server Monitor instead of displaying exceptions to the screen:

http://framework.zend.com/manual/en/…

Also see the note about integration of a ZF application and Zend_Log_Writer_ZendMonitor.

Mike -- you're attributing the issue to ZF, when in fact it's an exception being thrown by PDO. This is not a ZF issue at heart -- it's an issue with how PHP provides stack traces. As Ralph notes, the information in the stack trace is often useful for debugging; if the framework "scrubs" the stack trace, the end-user potentially misses vital information that can help them identify the cause of an issue. Additionally, once we start on a path of scrubbing, we hit a slippery slope: should we scrub usernames, too? what about database names? or paths? Basically, the concept of "privileged" information will vary widely between projects and organizations, and having the framework make a carte-blanche decision on this will ultimately lead to further issues.

Also, as Ralph noted, there are other ways to address this. As an example, instead of displaying errors to the user in testing, use logging, instead -- write errors and exception messages to a log (hint: Zend_Log has built in facilities for this), and then monitor the log; this can be done for exceptions as well. If you need to scrub artifacts, either for display purposes or when logging, write this logic -- it can be in your error.phtml if rendering stack traces to the screen, or as a custom Zend_Log_Filter and/or Zend_Log_Formatter.

The point is this: only you can adequately identify your application's security needs, and, as such, the onus is on you to write code that will address those needs. The framework can help facilitate this (and we do, via our ErrorController and the logging component), but we cannot make blanket decisions that will affect all users -- at least not without getting consensus on such decisions.

I am in fact using logging, the only errors the users ever see is akin to "An error occurred, go check your log file".

I have to operate under very tight security requirements. So as I'm sure you can understand, any time a password shows up in the clear its a red flag. But you are right, it is an issue with how PHP handles exceptions, and not a ZF problem. I (foolishly) did not realize the PDO is not something maintained by ZF.

I understand how you do not want to be obfuscating information that other users would find useful.

My own solution is to surround all LDAP authentication with a try-catch and bury the exception. This is acceptable to me.