Mark is a graph advocate and field engineer for Neo Technology, the company behind the Neo4j graph database. As a field engineer, Mark helps customers embrace graph data and Neo4j building sophisticated solutions to challenging data problems. When he's not with customers Mark is a developer on Neo4j and writes his experiences of being a graphista on a popular blog at http://markhneedham.com/blog. He tweets at @markhneedham. Mark is a DZone MVB and is not an employee of DZone and has posted 544 posts at DZone. You can read more from them at their website. View Full User Profile

Defensive Programming and the UI

03.24.2010
| 3530 views |
  • submit to reddit

A few weeks ago I was looking at quite an interesting bug in our system which initially didn't seem possible.

On one of our screens we have some questions that the user fills in which read a bit like this:

  • Do you have a foo?
    • Is your foo an approved foo?
    • Is your foo special?

i.e. you would only see the 2nd and 3rd questions on the screen if you answered yes to the first question.

However, if you went to the next page on the form having answered 'Yes' to the first question and then came back to this page and changed your answer to the first question to 'No' then when the data got submitted to the server the answers to the other two questions would still be posted.

We were therefore ending up with a request with the following values submitted:

hasFoo		"No"
approvedFoo 	"Yes"
specialFoo	"Yes"

Later on in the application we had some logic which decided what to do with the user request and this one was erroneously being approved because we hadn't catered for the condition where the first question was answered 'No' and the other questions had 'Yes' values.

In theory we should have written some client side code to reset the optional questions if the first one was answered 'No' but even then it's still possible to post whatever data you want to the server if you try hard enough.

Given that we need to behave in a somewhat defensive way somewhere on the server.

My initial thinking was that perhaps we should change the logic to handle this scenario but talking through the problem with Mike he pointed out that it would make more sense to fix the data earlier in the chain.

I ended up writing some code in the controller to change the latter two fields to 'No' if the answer to the first question was 'No'. We're not really using custom binders on the project otherwise I think it would be the type of logic that would go in there.

Overall I'm no really a fan of defensive programming in general because it often seems to lead to over complicated code but in the case of user input it does make sense and the general guideline seems to be to fix any logically invalid values as close to the entry point of our application as possible.

From http://www.markhneedham.com
Published at DZone with permission of Mark Needham, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Alessandro Santini replied on Thu, 2010/03/25 - 3:06am

In theory we should have written some client side code to reset the optional questions if the first one was answered 'No' but even then it's still possible to post whatever data you want to the server if you try hard enough.

IMHO there is no way you can get around that. If the user changes the answer, you have to reset the fields. More simply, you could disable the input fields again so that they won't be transmitted in the POST (if it is a web application). But in any case, the bottom line is that you have to implement some kind of UI state management.

Overall I'm no really a fan of defensive programming in general because it often seems to lead to over complicated code but in the case of user input it does make sense and the general guideline seems to be to fix any logically invalid values as close to the entry point of our application as possible.

If I really would, I could give you plenty of reason for which defensive programming is not only good, but is indeed necessary. I will limit myself to the first and foremost: security.People may forge a malicious POST or GET or even hack the page (e.g. changing the values of hidden/javascript variables holding the UI state, using tools like FireBug) and submit sets of data that should not be treated normally.

I would add that adding defensive programming at the service level (assuming you have a service level in your UI) would make your application more robust and your services re-usable from non-UI clients.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.