Archive for the ‘Philosophy’ Category

On Password Security

Thursday, December 18th, 2008

If you are storing user-entered passwords in your system, it’s imperative to keep those passwords as secure as possible.  With all the systems that require passwords, users often end up reusing one or two passwords for many sites.  As users also often reuse usernames (or use a single email for all sites) that means if you have user information for logging in on one site, you then have information for logging in to many sites as  that user.  Example: even if you’re just a site where users can log in and create silly little drawings, if a user can enter their own password on your site, there’s a good chance you can use that information to get into that user’s online email, or possibly even their banking sites.  So, good security rules would dictate treating that password as sensitive personal data, even if it’s not sensitive in your context.  In face, I think this might even apply if your system assigns the user a password.  If you are forcing the user to accept a new password, you might expect that once they have memorized that password they might start reusing THAT password elsewhere.  (if anything this sort of reuse is probably MORE likely with the non word, mixed case, mixed letter and number high-security passwords, since people can remember very few of those and a lot of sites want that kind of thing)

So, what to do to treat passwords well? One-way hash it-nothing less is acceptable.  You really don’t want anybody to ever be able to look at that password again.. remember, that password is black-hat hacker’s gold.  If the user forgets their password, they can reset it.

Some organizations have a policy of a clear-text password for “good customer service” (if the user calls to say they forgot their password,  the person answering the call can give them their password again)  this is a REALLY bad idea-it could be someone impersonating the user, and even if it’s not, the person answering the phone is one more person unnecessarily exposed to that password.  So, encrypt the password, and rethink the customer service angle.  If a customer calls asking for their password, say something like “To protect your privacy and identity  we do not store your password in a way that is retrievable by me or anyone else, so I cannot tell you your old password.  However, I can reset your password for you, and you should receive the information to reset your password in an email.  Please do not tell me your new password; I do not need to know it.”

Another argument sometimes used to store passwords in clear-text or a reversible encryption is so that administrators look up passwords so they can can log in to the system as that user to debug sepecific user-reported issues.  While verifying issues at this level is a good idea, allowing admins to access user passwords is a bad idea, as they should NOT see these passwords, and it requires passwords to be stored in a viewable format.  Asking users for passwords when issues appear is not ok either-the admin should not need any access to the passwords at all.  However, theses admins have a legitimate need-the right solution is to build into applications an impersonation system.  From an admin area, an administrator would have a backdoor into the system that allows them to access the application authenticated as a particular user-no literal logging in as that user required, so no password needed.

Psychology of a “pretty good” programmer

Tuesday, December 9th, 2008

(This post refers to no single person or job, but is describing a personality type I and others have encountered)

Just to get this out of the way, a really bad programmer is easy to spot-a truly bad programmer can be a perfect storm of inability to understand and unwillingness to try, a lack of caring or opinions, poor innate troubleshooting skills, and general lack of intelligence. Such people do make a living as programmers (which is a separate, interesting issue) , but they’re not who I’m addressing today.

More interesting to me than the truly awful programmers are the pretty good ones. They crank out code that works, they’re good troubleshooters, and they are generally reliable. Some of these people are senior. They do what they do pretty well. They accomplish things, deliver sizable projects. They focus on risk that is near-term… a guaranteed return is the way to go, every time-“this is what I know, and that’s what I’ll do”. As for how current work will be to deal with in a year or two from now if things drastically change? That’s another day.

There are problems with this approach though…sometimes improvements initially appear as risks. For example, writing unit tests (upfront time not spent on “production code”), writing in a concerns-separated fashion(moving things around is stirring things up for no reason), or exploring a new technology or methodology(time that could slow down the project, or even lost entirely if the new tech doesn’t pan out). Finishing the task is key to this mindset, and keeping an application useful, understandable, and maintainable is, frankly a lot of “busywork”. Problem is, the long-term success of the project can hinge on those factors.

Well… I’m trying to understand the mindset. As I said, the people I’m talking about are smart, capable people, so it’s not a simple case of lack of ability to think it through- there’s more to this story. It’s easy to imagine non-coding managers taking this approach, but why competent developers?

NHibernate and Entity Framework Battle it Out in the Real World

Wednesday, December 3rd, 2008

The scene: a company division with no prior in-house experience using any ORM of any kind. A really, really legacy database-the kind with many composite keys, fields with mystery names, uneven use of enforced keys, etc. Currently, access done through ADO teamed with stored procs containing dynamic sql involving string concatenations (horrible for speed, security and my sanity among other things)

The mission? Given the constraint of not being able to change the underlying database aside from adding on some views, build a clean, modern app to eventually replace a legacy app that’s creating significant maintenance pain.

Early on, the team decided to lean toward use of an ORM-several team members had had positive past experience with ORMs, and it seems to be the way the industry was headed. However, that still left a choice-which ORM? The choice was quickly whittled down to NHibernate and Entity Framework. We ran two small parallel spikes, and ended up with a few thoughts about working with each:

First, we picked 3 or 4 tables to map to with both technologies, wrote up some simple classes, and then set about setting up persistence through an ORM-agnostic repository via both mappers.

NHibernate’s mapping files are relatively easy to read, but there’s no GUI to write them for you. It lets you write your classes and then work on your mappings separately afterward. The classes are clean POCO. NHibernate requires some code modification (virtual/overridable) and works better with some child-to-parent mappings that don’t seem like they should need to be there, but generally, modifications needed are minor. Repository is straightforward, and there’s lots of helper code online to do the legwork. Not tested, but it’s got sophisticated caching built-in.

Entity Framework was from Microsoft and had a GUI. The classes were autogenerated in one direction, from the database to the GUI to the classes… non-mapped properties caused errors-the proper place to put such artifacts was in a separate partial class file for the class-looking at the autogenned class, it was VERY clear you were not supposed to touch it, and probably not supposed to look at it.. this left the class spread across your partial and the gui. In addition, there were tight EF dependencies on these domain objects. Not to mention, after working with the GUI, I got the strong feeling that the GUI would not be able to handle complex scenarios, leaving us working with the raw verbose and complicated (and not really designed to be hand-edited) mapping xml. A pre-written class doesn’t seem to be able to be used easily-at least, we were exploring the usefullness of the gui, which left us to recreating the pre-written classes via the gui. It wasn’t clear if it was possible to mark a class as read-only, and code wouldn’t even compile if fields required in the DB were not mapped. Repository pattern was a bit more work-less guidance online… not sure if that’s because EF is so incredibly new, or because EF users are generally not as familiar with this pattern… in any case, it was a bit more tweaking to get things working through a moderately ORM-agnostic repository interface. No seamless caching yet-that’s slated for v2.

Non-technical factors:

NHibernate was an industry leader, was fairly mature, had been around a few years (and a few MORE years if you counted Hibernate) and a team member (me) had experience using it in a high-profile production environment. No paid support available to speak of (not counting unknown companies here) but a truly responsive, helpful community with a product that is in active development… but then, NO backing company (not even Red Hat these days) … potential of giving fly-by-night appearance to non-techies as a result.

Entity Framework is brand-spanking new. If it were a car, it might still have temporary plates! It’s a 1.0 Microsoft product, with all that implies. Next version slated for 2010. If anything happens, Microsoft’s there for help, or (worst case) to receive a lawsuit. And it’s always easy to justify a Microsoft product.

It was a tough debate, but we ended up going with Entity Framework. Despite agreeing that NHibernate was the better technical solution, the team eventually concluded that having a backing company was extremely valuable for the organization, and that the GUI would be helpful for people coming into the project that were unfamiliar with ORMs.

The next morning, we set about doing some preliminary mapping. (ignore the DDD-related problems with this workflow for now, please)

  • Yeah, that GUI is looking even more inadequate…
  • Generated class and mapping files are THOUSANDS of lines long-this really sucks what with the inadequate GUI
  • IT was REALLY easy to screw up the EF stuff so the gui couldn’t load-easiest way to deal was to redo the whole thing-I think we did that about 5 times that morning.
  • It didn’t seem to deal well with the messy legacy db. Due to the db-first nature of EF, the messiness was going to leak through into our classes…
  • We were going to be on the hook to support this thing-were we ready to do that?

By noon, we’d decided to switch to NHibernate. Cleaner code, clearer classes, and a team member with experience suddenly became a whole lot more compelling.

Working through those mappings has been a valuable, revealing process too. (more on that in a later post)

(Corrected: Thanks to Scott Bellware for the heads-up that even if you’re working on a VB project, it’s still POCO and not POVO, since the C stands for CLR, not C#.)

Broken Windows

Thursday, November 27th, 2008

We all know the broken windows idea, but Jan did a nice, clear write-up of it. such a simple idea, so hard to fight in the day-to-day.

Professional Under Pressure

Funny, apropos comic

Tuesday, September 23rd, 2008

Everything Is Going Just fine, thank you

Working Effectively with Legacy Code

Wednesday, April 23rd, 2008

I mentioned this book in an earlier blog, and I’ve started to read it. (I was somewhere around 2/3 through Martin Fowler’s Refactoring, and in the weeds of arcane refactoring patterns when I decided to switch out) I’m maybe 70 pages in, and I have to say Working Effectively With Legacy Code thus far seems quite good. It’s actually a great companion to the refactoring book, and to the design patterns that I keep trying to get back to so that they really sink in (through reading the Heads Up book last time I made a concerted effort at patterns, though I might give the GoF book a go as it is the canonical choice.)

Unlike the patterns, and even more than the refactoring book, this book really gets at how to approach a messy codebase. Rather than just talking about refactoring, it really discusses them in context, usually in the context of separating concerns enough to test. At this point in the book at least, testing seems to be the short-term goal, making the assumption that you probably don’t have tests covering your legacy code. Fair assumption to make. So, it doesn’t focus on making the code easier to read, more maintainable, or elegant. It actually focuses on smashing apart your concerns, by whatever means necessary, so that you can get stuff under test, and *then* make stuff pretty and maintainable. The chapter I just read focused on finding what it referred to as “seams”-places where you can change the behavior of the code to make it testable *without* messing with the code under test in a significant way. for instance, if you’re already passing in a class to use in your operation (Dependency Injection) you’re golden. But Feathers suggests much more “wily” seams, such as overriding included libraries with your own wrapper libraries during compilation to introduce hooks for testing. Whew. that could get ugly… but then, you’re trying to reform legacy code from a test-unfriendly state, it’s probably not going to be pretty. Anyway, that’s a fair bit different from the refactoring book, as that tends to discuss tests as an assumption that you have before doing sometimes significant changes.

The book also has some chapters ahead of me that seem refreshingly realistic.  These are from memory so don’t quote me, but there are chapters titled things like “I can’t get my code into a test framework!” and “I don’t even understand my code enough to change it!” Working on a complex, deteriorated codebase is a programming challenge, but also a morale problem.  It’ really easy to throw up your hands and say “this code base cannot be saved!  It needs to be totally rewritten, and since that won’t get paid for, we’re screwed!” … OK, frankly, this IS sometimes true, and I do think it is important to recognize when that’s what you are really dealing with-and to recognize that’s a high bar.  The vast majority of the time, you’re facing some code that’s okay, but could be much, much better.  The transition will be tough, and involve a lot of rewriting and duplication, but you know it’ll pay off.  Do you do it?  Well, it depends, of course.  But the answer should not be determined, as it so often is, by pondering the work involved and deciding that it feels to exhausting to even contemplate.  This book thus far seems to be pretty good at illustrating a straightforward path to get to somewhere better, and get over the intimidation of all that badness.

Pain encourages change? Not sure I buy it.

Wednesday, April 16th, 2008

A frequently repeated theme on the Alt.Net list is that certain ideas, like IoC, are not understood until you feel significant pain, and you’ll be motivated to try something new.  From Derik Whittaker’s post today, “[…] do this not because he is told or shown, but because he is in so much pain because of NOT using them that the only other option IS to uses these techniques.”  Frankly, I’m not convinced that this revelation will ever happen for many developers.  In my experience, if certain kinds of pain is seen as integral to the development process (whether really it is or not) there will be no searching for alternatives.  Instead, that developer will ask for more time/resources, or just say those problems are part of development, etc, and yes, sorry, but this task IS going to take 10x longer than planned.  The solution to make it much better could be handed to the developer, but if it conflicts with previously-held ideas, it’s seen as a threat and rejected.  It’s kind of an eyes-open vs. eyes-closed attitude, and there are a whole lot of people with their eyes closed.  The majority?  Sadly, I’m pretty sure that’s the case.

Top 5 reasons why “The customer is Always Right” is wrong

Wednesday, March 26th, 2008

Pretty related to an earlier post I made about how programming shops are not dry cleaners… It’s not saying ignore the customer, but that random customer demands aren’t the way to run a business well.

Top 5 reasons why “The customer is Always Right” is wrong 

Managing Mangers

Thursday, February 21st, 2008

A spot-on post by SerialSeb…

Software Development is not Dry Cleaning

Friday, January 11th, 2008

“Of course software development is not dry cleaning!”, you might be saying. However, it’s apparently a not-so-obvious idea. As a services-oriented software company, what’s your role? Is it to deliver “satisfaction guaranteed” ? It it to do whatever it takes to get things done on time, and if there are delays, to do what it takes to get back on schedule? If the delivered is somehow unacceptable is it your job to fix the situation, because what you delivered wasn’t perfect? Is the customer’s singluar role to evaluate if what they brought you turns out right? Really, that sounds a lot like a dry cleaning business. The “Dry cleaning” approach is a classic services-industry scenario.

Dry cleaners, restaurants and florists who follow this model are generally going to be successful, it’s a tried-and-true approach. It’s really understandable that in approaching the services-side of software, that people might think the “dry cleaning” model would once again lead to success. However in software, this model leads to unsuccessful projects.

Picking apart the scenario, the main problem is the client relationship. Software services are very different from traditional services in that the client’s requirements can be incredibly complex and individualized. Developers need to understand the client’s business and the problem that nees to be solved. Communicating this information is not a one-time thing, but a task that generally runs thoughout the process of development. The client can’t just “drop off” what they need and pick it up later with software. In contrast, their busness and specific needs are so central that the client needs to be considered part of the development team to create the product together-the development team develops, the client communicates and is the investor, the designers manipulate graphics, these are all parts of a working whole with the same goal.

It might seem “scary” to let the client inside the team, but the fact is, doing so will help clients to understand that they and their requirements are important and valued by the software company. In addition, clients will understand that since they are important and equal members, they have to live up to their role in the team or the project is hurt. Since it’s no longer and us-vs-them situation, if the client IS late on something, they will have an easier time understanding that their actions have consequences, i.e. the whole team is delayed, and they’re are either causing someone to work overtime, or maybe they’ve created a situation in which the team cannot possibly deliver on time. If you leave the clients on the outside and leave the development process a black box, it’s understandable that they would be intolerant to delay or bugs. Bring them into the decision process… “well, things did end up getting a little more complex than we anticipated, so if we cut time for testing, there are going to be more bugs. or we can add time and deliver with fewer bugs. What’s best for the project?” If the client understands what led to bugs and their own role in that, they will be more willing to see followup as part of the process and not a “freebie” they are owed for the software company “messing up”. More followup was just a tradeoff choice.