Brendan Enrick

Daily Software Development

URL Parameters - Code Audits #1

This is the first post in a series that I am writing that focuses on some interesting finds from different code bases I’ve seen over my years looking at lots of different software projects. Code Audits are one place where lots of interesting bits of code can be found, since you're combing through an entire software system. I will be explaining what I’ve seen, why it’s wrong, and usually the better approach if it’s not obvious.

URL Parameters

URLs let you control the navigation as your user navigates around your site. Users may not know what URLs mean or how they work, but most people browsing the web know that URLs exist. A good number of them know that modifying that URL will take them to different pages. Even my mother knows that much about URLs.

It’s not just a tech savvy computer programmer or hacker who can figure out that changing the URL might get them to a page they’re trying to see. This is sometimes useful on site’s whose navigation is somewhat lacking. It’s also often possible to guess the page you’re looking for by adding “/login” or some other common word to find a page whose link you’re not seeing.

The Bad

On web sites that have user accounts associated with multiple accounts, it’s quite common for the current account that the user is viewing to be specified in the address bar using a query string parameter. Normally, this means that there will be something along the lines of “?AccountId=123456” on the end of the URL. It’s also very common for those to be built in as “subfolders” like this “/Account/123456/”. Either way, it’s easily visible, modifiable information presented directly to the user.

As I am sure most of you can predict, I am going to point out that I’ve seen some code that didn’t do the proper protection to make sure that only an allowed user can access any given AccountId. The site will only display the links to the allowed accounts, but the site itself does not protect against a user changing that AccountId.

If you want to get to another user’s account, you can just type in another AccountId into the URL and the site will take you there…

The circumstances where these mostly come up is when 1 user account is allowed to have access to more than one account. It’s on these sites that the user will need to be able to change accounts, and sometimes users keep multiple accounts open at the same time, so the URL is needed to keep both open at the same time. It’s important, however, that we maintain at least some level of security here.

The Better

When we build sites, it’s extremely important that we validate inputs given by users to make sure that they’re valid. It’s also important to make sure that users have access to the information they’re requesting.

The first thing you do when you receive user input is to validate that input. Obviously if you consider a URL to be user input, you would validate that immediately as well. This means that either directly or through some layer of abstraction, your code should be verifying a user has access to any information being requested.

Citigroup

There was a big fiasco last year related to Citigroup. (http://www.nytimes.com/2011/06/14/technology/14security.html) The rumor is that they had a security breach based on this type of issue. I have no real, credible information about this, but it makes for a good example even if it’s only rumor.

From the New York Times article we get these:

Once inside, they leapfrogged between the accounts of different Citi customers by inserting vari-ous account numbers into a string of text located in the browser’s address bar.

That sure sounds to me like what I just described. If it is what I described, then this security expert stretched the truth quite a bit based on what is in that same article.

One security expert familiar with the investigation wondered how the hackers could have known to breach security by focusing on the vulnerability in the browser. “It would have been hard to prepare for this type of vulnerability,” he said. The security expert insisted on anonymity because the inquiry was at an early stage.

It’s not hard to prepare for that kind of vulnerability. I guess if you have it, it’s hard to track and log the issue. What’s easy is not having the issue to begin with. It’s a simple policy of making sure that all inputs are validated for permissions before being executed. Also, that is not a “vulnerability in the browser”.

More Code Audit Nuggets

Keep watching for more interesting nuggets of stuff that I’ve seen in codebases.

Single Responsibility Principle

Now that we’re in the second half of June, I think it’s time that those of us with one, take a look our 2011 Software Craftsmanship Calendar. In June 2011, the topic was the Single Responsibility Principle, which states that your code should only have one reason to change.

The Single Responsibility Principle is the first in a set of Principles called SOLID,

SingleResponsibilityPrinciple

That looks dangerous…

For the rest of June, please try to follow Single Responsibility Principle and try to not be a Duct Tape Coder. Everyone who has to maintain your code in the future will thank you.

Duct Tape Coder

For anyone following along in the NimblePros Software Craftsmanship Anti-patterns Calendar, June is the month of the Duct Tape Coder. The calendar is a great reminder to try to avoid all of these bad practices. You obviously want to avoid all of the bad practices illustrated in the calendar, but for the month of June, you should be focusing on not being a Duct Tape Coder.

Duct Tape Coding

Similar to Cowboy Coding, Duct Tape Coding is all about getting things done. Not worrying about how you do it or how it will be maintained in the future. The goal of the duct tape coder is to get something working.

You might be saying to yourself, “I thought that all of these agile good practices said to start with the simplest thing that works!”

You’re correct. It says to start there. That means that you need to clean things up and use refactoring to create a maintainable, clean solution. Consider the initial duct tape to be scaffolding to allow you to build the final, maintainable solution. The duct tape, along with some automated tests allows you to build a system to be proud of.

DuctTapeCoder

Spend June making sure that you’re building your software the right way. Don’t settle for a “working” solution. Build a good solution.

The Clean Coder Review

I recently read The Clean Coder: A Code of Conduct for Professional Programmers (Robert C. Martin Series), and it is one of the best books on software development that I’ve ever read. The book is a quick read from Uncle Bob Martin and is comparable in size to his similarly named, Clean Code: A Handbook of Agile Software Craftsmanship.

The book goes through many, many examples from the author’s development experiences. It has sample discussions between parties to explain points and really goes over professionalism in software development.

The Title

The impression I have about why the book is called “The Clean Coder” is mostly a play on professional developers wanting to have clean code. This doesn’t just mean the code, the code is included of course, but it also means that the whole coding experience and the whole project should be clean.

There are a lot of mistakes that developers can make, and the book is covering them and discussing how to keep things clean.

The Material

Without jumping into too much of the meat of the book, I will say that there are many things in the book that I’ve done before and don’t do anymore. There were some things mentioned that I’ve done recently, and I am going to make sure I never do again. There are some things in there that I’ve thankfully never done, and I hope I don’t ever do them.

The book focuses on a lot of bad situations, why these situations are bad, and how we should really be handling things.

Consider this book to be a guidebook of suggestions for how to act as a professional. For example, in the book’s discussion of estimation, instead of focusing on how to be more accurate with estimation, it covers how you should be estimating. This means that it tells you that you should be very clear about things being estimates, not to imply a commitment, and not to make commitments if you cannot meet them.

Controversial Points

The Clean Coder makes some recommendations that I am sure that plenty of people will disagree with, and the way some points are worded cause me to sometimes disagree as well, but I don’t think it really takes away from the value of the book.

One example of this type of suggestion is that you work 40 hours a week and then another 20 each week on improving your career, leaving 56 hours for sleeping and 52 hours for everything else. It’s presented as doing this makes you a professional and not doing it is not professional. What I disagree with is the definite amount of time. I think it’s important for people to work on their careers, but 20 hours is arbitrary here. Someone may get the same value out of 10 hours that requires me 30 hours. There also is no definitive line between professionalism and unprofessionalism. There are some gray areas, and I believe this would be one of them.

Some things in the book were kept clear that it’s how he works, and I took these as suggestions to learn how I work and make sure that I am evaluating a possible issue.

In this case, I am referring to a point on music. Some people listen to music lightly while programming. This is even true when pair programming. I sometimes like having a very light bit of background buzz from music while pairing. In this case, I keep it so quiet that we can still communicate easily. The book seems to be against music, since it distracts and changes the author’s thinking. For me, I think I don’t have this issue because my pairing partner prevents a change in thinking. I also try to listen to music with foreign lyrics or no lyrics at all. It also helps to not distract from the task at hand. The value here for me is that I should be evaluating and thinking about how I am doing things to make sure that something as seemingly inconsequential as music is not detracting from my work.

Meetings

One great suggestion made by Uncle Bob is that it’s OK to decline a meeting invite. I think that’s very important to understand. Unless you’re really needed in the meeting, you should try not to attend. Meetings take up time, and if it’s less important than your other work, you shouldn’t be attending.

I had a meeting I scheduled yesterday. I invited 8 people to that meeting. I made sure it was clear that if you had something to bring up, you should attend the meeting, otherwise your attendance was not required. We had 4 people in the meeting, and I think 1 of the attendees need not have been there anyway.

Trying

You should read the section on trying. It’s important not to try, and this book makes it very clear why. If you’re going to try, you’re making a commitment to try.

Mentoring

The first paragraph on the chapter on mentoring illustrates one of the biggest shortfalls of the software development industry. I owe a lot of my successes as a developer to the mentoring that I’ve received through books, blogs, and any other recorded sources of information I can get my hands on. I was also lucky enough to have a mentor and a role model to learn from as I became a better developer.

Summary

If you go in to this book expecting it to be a recipe for success, you will be mistaken. This book is fantastic, but it’s important to think and consider why it’s valuable. It is one developer’s experience as a developer.

From his own stories, he is a developer who has hit some pretty rough patches and made some terrible mistakes. That’s a good thing! It means that he has learned a lot!

While reading the book, I never felt like it was forcing his way of doing things onto me. It is presented in a great way to inspire changes in the developers who read the book. You don’t have to do the same things that he is doing, but try to consider what the right answer should be.

The examples are simplified for the book, and business are more complex than what is in the examples. The reader will need to adjust and make decisions, but that’s what you should be doing anyway. Think about being professional and doing what you should be doing.

This book has been on my intended reading list for a while, and now I am going to recommend it to other people.

Well done, Uncle Bob. Thank you for sharing your experience with everyone.

Information Overload

After CodeMash, I was informed by many people that I had missed a great talk that Scott Hanselman presented. The talk was his “Information Overload” talk, which is about the onslaught of information that the world sends at us constantly. I’ve since discovered that he has been presenting this around the world. Last week, at StirTrek, I made a point of watching Scott’s “Information Overload” talk.

His talk is designed for developers, but it’s not developer-specific. It is all about managing the streams of information that come into our lives. As is usual, his talk is entertaining, well-presented, and contains enough impromptu comments and laughter to keep it memorable. (More than just the comedy is memorable even.)

He had a lot of suggestions about how to organize what is important, when we should deal with things, and how we should deal with things. Techniques, tools, recommendations, and guidelines are the name of the game.

If you get the chance to see the talk in person, I recommend doing so. It is one of the better talks I’ve seen presented at conferences.

Try Writing Try Methods

When I say "Try Methods", I am of course referring to the common prefix "Try" on a method, which implies that the method is going to attempt to do what you're asking by using an output parameter for the operation and using the return value to indicate whether the attempt succeeded.

The common ones that people see in the .NET Framework are the TryParse methods, which attempt to parse something and if it can't be parse, they assign the default value to the output parameter and return false. If the succeed, the parsed value will be placed in the output parameter and the return value will be true. If the code failed, the convention is to use the type’s default value to assign to the output parameter. This lets you write code like this:

int someNumber;
int.TryParse(userInput, out someNumber);
// use the number entered or the default 0
int result = 1 + someNumber;

 

This is also great when you're going to be checking whether the method succeeded. In fact, you can use the try method directly in the if block, which usually makes things nice and clean. Here is an example of using them like that:

int someNumber;
if (int.TryParse(userInput, out someNumber))
{
    // Do something with someNumber
}
else
{
    // Invalid input: handle this case accordingly
}

 

Yes, you know all of this and have seen it before, however, are you writing these types of methods yourself or is your only experience with them the standard TryParse ones?

What I am trying to emphasize here is that you need to write your own Try methods in your code. You will thank yourself later.

Everyone can see the obvious benefit of not having to check for the default value to see if it the method worked. You also don't have to have ugly Try-Catch logic in your code. You get an if statement instead.

The real benefit of a writing a Try method has nothing to do with what I've already said. The most important benefit, in my opinion, is that you have a return value from it that isn't the value you are using for your logic. By having this return value for its success, you have to decide on how to handle the case where it failed.

There are important cases that might be forgotten, but having a return value means that I need to handle the return value. When I have it, I need to decide what to do with it. There may be a message I need to display to a user. There may be logging I need to do. I might be able to ignore that case. What is important, however, is that I thought about how to handle it. I had the chance to make sure that I handled the case correctly.

Create your own “Try” methods. I recommend looking into creating your own “TryParse”, “TryGet”, TryDelete”, and anything else that has a chance of failure that you may want to handle.

Common Reuse Principle

Classes that are used together are packaged together.

This is the April topic from 2011 NimblePros Software Craftsmanship Calendar, which includes a nice quote.

Common Reuse Principle (CRP):
Classes should be packaged together when reusing one will mean reusing them all. Source: “Agile Principles, Patterns, and Practices in C#”
by Robert C Martin

This is a pretty simple principle, and one that should seem quite logical. Not everyone agrees with the principle, but it least has a good point. If two things are going to be reused together, it makes logical sense that you should package them together.

Imagine if we didn’t follow this for ASP.NET and instead had everything spread around in some random assortment of assemblies. If I were accessing my HttpRequest, which is normally in the System.Web assembly and doing something with the cookies from that, which is an HttpCookieCollection. That HttpCookieCollection is a collection of HttpCookie. All of these are in System.Web, since they’re commonly used together. There is one assembly that we need to use this full set of classes.

Now think of how much fun this development experience would be if we had broken these apart such that the HttpRequest was in the System.Web assembly, HttpCookieCollection was in System.Web.Collections assembly, and HttpCookie was in the System.Web.State assembly. That would mean having to access three different assemblies to get three closely related classes.

Don’t get me wrong, I like having smaller, broken up dependencies, so that I don’t have to depend on a lot of things I don’t need. In fact, I have to have a good number of assemblies when I use the onion architecture. (They’re not all compile time dependencies everywhere they’re used though.)

The painful part, however, is when there are obvious pieces that should be together and aren’t. Common reuse is basically saying that there is pretty much no time that I would use HttpCookieCollection without also needing HttpCookie, so they should be in the same package. (Just those two from my example. I think that HttpRequest could be somewhere else with a good reason for it. Although we all know that all of these classes are in the same assembly right now.)

What’s your take on it? There is a lot of gray area with Common Reuse Principle.

Groundhog Day Experience

One of my all-time favorite movies is Groundhog Day. In the film, the main character, Phil, repeats the same day for thousands of days. I've heard rumor before that the author said that Phil had repeated the day enough times to have been trapped in the loop for 40 years. I don't know if the author really said this, but it seems like enough time to have learned and experienced everything that he claims to have experienced in the film.

I believe this comedy offers a lot more meaning that what it appears on the surface. I think that we should all be striving to live our lives as Phil did in this one. No, ignore all of the silly, crazy, and suicidal days. Focus on the days where he was focusing on improving himself. Phil did a great thing in motivating himself to learn to speak French, play the piano, and genuinely change his character and outlook on life. He attained many artistic abilities and social skills. He also learned a great deal by varying his days. He repeated the same day over, but he never really repeated the day the same as he did before.

One of the greatest weaknesses that we as humans have is our urge to do today the same things we do every day. If we don't get out of our confort zone and try new things we will never learn, grow, or master anything new. I think I should strive to live my normal life more like Phil's. 

I've heard the reverse mentioned about many of the developers in our industry. On many occasions and from many people, I've heard the saying that someone may have 10 years experience, but it's really 1 year of experience repeated 10 times.

That terrifies me. I really don't want to fall into that situation. i want to make sure that I am always learning and growing as a developer. I look at my code from 5 years ago and can't believe I wrote things that way. I look at my code from 6 months ago and am also glad I've improved. Ten years from now, I hope I will still be saying the same things about my past code. I also hope that the software I am writing, the languages I am using, and the patterns I am folliwing are vastly different from the ones I am using now. That will mean that I am improving my skills as a developer and improving myself.

The best way to describe this is to say that Phil took one day and expanded it to more than 10 years of experience. As developers, we should make sure that we don't condense 10 years of experience down to 1 of fewer years.

Try new things and continue improving.

Static Mocking with JustMock

One of the coolest (and scariest) things I’ve seen lately is mocking static classes and methods with JustMock. I was working on some legacy code, and was making some changes, so I wanted to make sure that I got everything tested first. When I went to write the tests, I noticed that I needed to wrap and hide away a static method that was being called.

My eventual intent, however, is to get rid of the static class and method calls if possible. Writing the wrapper around it temporarily, so I can get tests in place before refactoring has always seemed like a pain. I went to check and see if JustMock would be able to mock a static class. That seemed like one of those crazy things that commercial mocking frameworks can usually do. I was right. It could mock the static class. (SCARY!!)

I wrote some code that looked like this: (Sorry I can’t show you my clients’ code in my blog without their permission, so you get sample code.)

public static class MyStaticClass
{
    public static int DoSomeDependentStuffThatIsHardToFix()
    {
        // Pretend this does more than just returning 1
        return 1;
    }
}

 

In my example, I need to test some code calling this static method. Normally, I would put a wrapper around this class, write my tests, refactor, and eventually change this to not be a static dependency anymore.

I decided to try this. Here is a test class that uses mocking to demonstrate how I can decide any result for this method and have control of this dependency. Notice that my method always returns 1. Pretend that a different result were possible.

Now when I go to write my test, I can just Mock out the static and define that I want that method to be called and for it to return 2 instead of 1. I will then assert that it worked as I expected in my test. Once I confirm that the mock works as expected using this type of test, I can put it in place in my actual test. (Yes, I sometimes write temporary tests to confirm what I expect before I write the whole test. Little steps.)

[TestFixture]
public class MyTestClass
{
    [Test]
    public void WhatIsTestedDoesNotMatter()
    {
        Mock.SetupStatic(typeof(MyStaticClass));
 
        Mock.Arrange(() => MyStaticClass.DoSomeDependentStuffThatIsHardToFix()).Returns(2);
 
        Assert.AreEqual(2, MyStaticClass.DoSomeDependentStuffThatIsHardToFix());
    }
}

Then when I go and run my tests, I get this nice result showing me that everything is working as I expect it to. Yippee!

JustMock Static Test Passing

How it achieves this? I am not sure. I intend to find out though. When I do, I will write a post explaining it.

Have a good day!

Open/Closed Principle and Reinventing the Wheel

This month at the Hudson Software Craftsmanship group, we had two interesting discussions that were spawned from the NimblePros Software Craftsmanship Calendar. The calendar’s topic for March 2011 was the Open/Closed Principle and the topic for March 2012 is Reinventing the Wheel. Keep in mind that 2011 is a calendar of good practices we want to encourage and the 2012 calendar is full of anti-patterns to be avoided.

This post is a recap of some of the stuff we discussed at the March, 2012 HudsonSC meeting.

Reinventing the Wheel

Going into the meeting, I had the thought that Reinventing the Wheel is obvious when you’re doing it and Open/Closed is less obvious when you’re not following it. Boy was I wrong. The main discussion we had about Reinventing the Wheel was based on “how do I avoid reinventing the wheel in a large, badly organized code base”. We had a lot of very good ideas and suggestions about how we can try to avoid this through tools, communication, and a variety of other methods and ideas. It’s interesting though, because none of them really are the silver bullet that just solves this challenge. If you don’t know if something is already written in the codebase, it can be a real challenge to find.

Open/Closed Principle

For the open closed principle, we discussed how we use it, when it’s used, and whether we should start of our code building for open/closed. I think most people came to the consensus that it’s likely not a good idea to use Open/Closed right away, but that we should refactor to it when we’re changing the code. The thought here is that if we change it once, we might need to change it again, so the next time we need to extend it instead of changing it.

Make the code better now and we’ll save ourselves time later.

Supermarket Checkout Exercise

As our programming exercise at the end of the day, we decided to do the Supermarket Checkout programming exercise. It is an interesting little challenge that involves some design decisions. This is what makes it interesting.

The exercise has the developers writing a checkout system for a supermarket. Essentially, it’s about calculating the price of the items as their scanned. It factors in discounts, selling by quantity or individually, and selling by weight. This information also needs to be presented to the customer on a receipt at the end of the transaction. This means that you need to figure out how to give the user the needed information in a nice, clean way.

As you work on the code, you have to make some decisions on how the code is going to interact with the customer. Should the discounts appear inline immediately or at the end? Is the discount a separate line item or shown in the price? How do these choices affect how you’re writing the code? Some have you returning information immediately and some have you gathering the information later. How do you adjust your design decisions based on this?

You can find a link to this programming exercise and more on my List of Katas and Programming Exercises. And, because I am not a total jerk, I will give you a direct link to the kata pdf in case you don’t want to check out my other blog post.

Supermarket Pricing Coding Exercise (Sample Output)

The Sample Output is optional to use. You can also come up with any sample output that you wish to use for it. Change things up. Or do the kata and then pretend that the business rules have changed and now you need to display the information differently.