JAASRealm logs passwords in the clear: 2005-01-20 17:26:51 JAASRealm[Catalina]: Returning username bob 2005-01-20 17:26:51 JAASRealm[Catalina]: Returning password asdf This is a huge security hole. It should require unusual and explicit configuration to get JAASRealm to emit plaintext passwords if it is even allowed at all.
Is it a security hole? Yes, but only if you specifically turned on debug tracing. This isn't done by default. To your point, it "should require unusual and explicit configuration to get JAASRealm to emit plaintext passwords". It DOES require unusual configuration---tracing. Second, the function of the trace is to report what the JAASCallbackHandler passes back to the LoginModule, and only in a debug/trace scenario. This is very handy for troubleshooting JAAS login modules, which frequently access enterprise resources. If the realm has password digesting turned on, it will log the digest value. It sounds like you don't use digesting in your LoginModule; maybe you should! I'd say the hole isn't "huge," but if this is really a problem, simply snipping this line out of JAASCalbackHandler#handle() would fix the issue: if (realm.getContainer().getLogger().isTraceEnabled()) realm.getContainer().getLogger().trace(sm.getString("jaasCallback.password", password));
Tomcat bills itself as a very secure system. (see "Tomcat's security record is impeccable" at http://jakarta.apache.org/tomcat/faq/security.html ) Exposure of passwords in plain text is something not even MS Windows would allow. Setting the log to a DEBUG level is not uncommon or unusual. It happens all the time. I don't know exactly how the JAAS properties are set or what the "sm" in the code in question refers to, but I can generally propose a separate JAASRealm property "tracePasswords" which defaults to false and a change to the code in question to something like: if (realm.getContainer().getLogger().isTraceEnabled()) realm.getContainer().getLogger().trace( tracePasswords ? sm.getString("jaasCallback.password",password) : "<suppressed, set jaasCallaback.tracePassword=true to show>")); For the record, JAAS Password digests, while better than plain text, are vulnerable to dictionary attacks and thus not particulary secure. Exposing them in the logs would still be a security risk.
I think it would be better simply to snip the offending logging lines entirely. If somebody needs to debug a LoginModule password issue, it could be done inside the LoginModule as a hack (since it's probably a custom code module anyway) instead of in the callback handler. A quick skim of the JDBC and JNDI realm implementations shows that those classes don't log passwords, so JAASRealm probably shouldn't either. Therefore, there is a second line---in the class constructor for JAASCallbackHandler---that should also be snipped: if (log.isDebugEnabled()) { log.debug(sm.getString("jaasCallback.digestpassword", password, this.password)); } As for the claim that "Tomcat's security record is impeccable" --- well, I don't know who wrote that text. It is a foolish thing to boast publicly, IMO. Tomcat's record is pretty good, just not impeccable.
Setting the log to DEBUG is quite unusual. You seriously need to be nicer in your bug reports.
I looked at the code, and I agree with Andrew's suggestion.
I like Andrew's suggestion even better than mine. Thank you for fixing this promptly.
(In reply to comment #1 and comment #4) Tracing is turned on in the example provided in the documentation, which I (and I suspect many others) simply copied as a baseline. That's the point of an example, isn't it? http://jakarta.apache.org/tomcat/tomcat-5.0-doc/realm-howto.html#JAASRealm (also http://jakarta.apache.org/tomcat/tomcat-5.5-doc/realm-howto.html#JAASRealm ) Example Here is an example of how your server.xml snippet should look. <Realm className="org.apache.catalina.realm.JAASRealm" appName="MyFooRealm" userClassNames="org.foobar.realm.FooUser" roleClassNames="org.foobar.realm.FooRole" debug="99"/> If you want tracing to be an unusual configuration, please change the documentation.