Holy Hash! Yahoo! keeps passwords in clear!

Washington Post reports on the Yahoo password database leak, the auditors say that Yahoo stores passwords in clear text. I am shocked.

I mean, how more silly can you get? We have been talking about not storing passwords in clear for, oh, I don’t know, ages now. Definitely long enough to expect that nobody in the right mind would do such nonsense any longer.

We do expect an occasional idiocy like the recent discovery that LinkedIn stores passwords hashed with a weak algorithm and not following the security recommendations. Fine, but just storing the passwords in clear is beyond such simple fallacy, this is almost like intentionally evil.

We know that sites get broken into. If a site has not been broken into, it is just a matter of time. And the more prominent sites are, of course, prime targets and should expect the break-ins like everyday business.

When the break-in occurs, the first thing attackers would go after are credit card numbers and other monetary assets. Next on the list are the password databases. And that’s why the passwords are never stored in plain, they are never encrypted, they are hashed. One-way hash, properly done, is a good way to keep passwords safe even when they get stolen.

CakePHP: plugins models

I spent two days trying to trace why the plugin I am writing did not work. Eventually I realized that the files defining the models were not loaded at all. After several hours trying to figure this out I came across this explanation provided by zuha-3:

My bet is that you don’t have a plugin defined somewhere. I had the same problem in a couple of places after the upgrade because I had forgotten to name which plugin the model could be found in.


belongsTo = array(
className = [PLUGIN].[MODEL]

instead of...

belongsTo = array(
className = [MODEL]

And this goes for all relationships, and you might have just missed one.

And so finally it worked. This should be like written in really large letters on the page that talks about plugins in CakePHP documentation. Two days for this simple stupid thing…

Software design – separation of concern

Still, the separation of concern is as actual as it always was. Consider this website design thing. You still have to separate the concerns between the user management and the website content management. These are totally different concerns. And they have different priorities too.

When you manage the content in your application you basically do not care about users at all. You care only to know whether the requester has the right to see (or modify, whatever) this particular content. So you need some kind of identifier as an input to the authorization management, which is another concern. You really do not need any details of the user that is usually kept by the user management.

While you are in the user management, creation, registration, modification, verification etc. require full knowledge of the user details. So you need to have different data on users here.

What happens is that you really need to have two different concepts of users: one for your user management subsystem and one for your website content management subsystem. And those have little in common. Plus, the website content management requires such user information (besides being useful) that can be quickly retrieved and add minimal overhead. On top of that, user information in both must be kept in sync.

Finally, one comes to realize that the database views are invented precisely for this particular problem. So we can have the same user data underneath but present two different views of that same data to the two subsystems of our web application.

CakePHP: bind hasMany as hasOne

This is totally brilliant. I came across this marvel somewhere and adapted to my application. See, if you have a hasMany relation, you end up with (1) an extra query and (2) with a lot of data. I have a case where I just need the last (time of creation) row. So I basically want to bind that model in a hasOne relation where the one row is determined by an expression selecting a single row. Continue reading