Blog
Masters at work...
The Web Developer's Responsibility to Society
codeninja December 5th, 2008
Recently our firm was asked to bid on a project for a potential client. The client wanted a highly custom E-Commerce engine with heavy social networking components such that the project demanded a custom solution.
We presented our solution to the client, but unfortunately we were not able to meet their budget and were told by the client that while our proposal offered everything they were looking for in their project, they were going to move forward with a different firm. It was a peaceful parting as we fully understood their position. We wished them luck and success with their project and moved on.
Unfortunately, the client has returned to us. The selected firm was not able to complete the project due to the project’s complexity. It was simply over their heads.
The client invited MWD to preform a review of the code base in order to determine if we are willing to take over the project. The following is the story of our findings. It is a story of a developers responsibility to the client. It is also a story of tragedy.
The developers of the application had made several critical errors in their development of the application. These design flaws have opened up the site for SQL Injection, XSS Attacks, and spoofing. Not to mention the rampant use of brittle, frail code which will prove impossible to extend or maintain.
It’s immediately clear by looking at the code base that the developers not only have a basic grasp at best of the Rails framework, but they have even less knowledge of the Ruby language. This alone is responsible for 60% of the problems on the site. The developers have produced very bloated, procedural code. In many cases they have reinvented the wheel.
Lack of understanding Breeds Fragility
In one case, the developers took 260 lines to create a case statement which returns a hash of country codes and country names based on the first letter selected from a menu.
case first_letter.to_s
when 'A'
ahash = {'AlBANIA' => 'AL','ALGERIA' => 'DZ', 'AMERICAN SAMOA'=>'AS','ANDORRA' => 'AD',
'ANGOLA' => 'AI','ANTIGUA AND BARBUDA' => 'AG', 'ARGENTINA' => 'AR','ARMENIA' => 'AM',
'ARUBA' => 'AW','AUSTRALIA' => 'AU','AUSTRIA' => 'AT','AZERBAIJAN' =>'AZ'}
country_code = ahash[country.upcase]
....
end
return country_code
This 260 lines of bloat is not only SLOW, but fragile, and was quickly refactored by our team into the following.
all_co_codes = {'United States'=>"us", "Canada"=>"ca", ....}
all_co_codes.select{|k,v| puts k.first.downcase == first_letter.downcase}
This type of bloat is littered throughout. The application is slow, unresponsive, and brittle throughout because of it.
As developers, we have a responsibility to our clients to not engage in a contract or commitment without fully understanding the tools we are being asked to use. Be it a new language, a plugin, an API or a third party system.
Sure, you can say to yourself, “I’ll look into that API more when we get to that part.”, but how do you know that the tool is the right tool for the job without an understanding of how the tool works. From 100 yards away, a hammer and a saw are indistinguishable, and you many not realize until you cross the field that what you really needed was a pair of pliers.
Take the time in a new project to gain a detailed understanding of the software and tools you are being expected to use, and you will find that the project is far more fluid in it’s development. You will be able to see problems before they come up with a little forward thinking.
Lack of Understanding Breeds Insecurity
Had the developers taken the time to learn the language, the above example could have been simplified. Had the developers taken the time to learn the framework, the site would be more secure. Here is another example taken from the same file.
This piece of code sends a receipt of the order (containing full credit card information, to the user’s email address based off an order number which is passed through the URL.
It’s executed when a user visits /store/order/1/receipt
def self.email_receipt(order_id, user)
begin
order = CustOrder.find_by_sql("select o.* from cust_orders as o where o.id = #{order_id}").first
email_order_receipt(order, user)
rescue
end
end
If the user visits /store/order/1/receipt then the user would be emailed his receipt. But if an attacker visits /store/order/1||true/receipt then the application will email a receipt of EVERY order in the database to the attacker.
The developers have made 3 critical flaws here.- They have ignored, or remained ignorant of, the built in mechanisms for accessing database objects
- They have subverted built in protections for SQL and XSS attacks that Rails provides by not sanitizing the data being used in hard coded SQL statements.
- They trust tainted data, they also trust tainted results from their own SQL results.
If they simply understood their tool, they would know there is an easy way to avoid this problem.
order = user.orders.find(order_id.to_i)
With a single line of code in this project the developers of the application have created the potential for disaster. They have compromised the integrity of their clients data. They have violated the trust of the company’s customers. They have put those customers in financial jeopardy. And they have potentially opened the company up to legal action.
This issue would be a minor problem to solve… if it was an isolated issue. But we have found 279 instances in the project of this style of code. Leading us to believe that the problem is systemic throughout the application.
Our Responsibility as Developers
As developers, we must understand that we are not developing simple websites any longer. We are developing platforms for societal interaction. We are developing the conduit of business. We are creating reputations for a brand. We are building the future of commerce and communication with every line of code we write. And in many cases dealing with commerce, we potentially hold peoples financial stability and future in our text editors.
And with every line, we must ask ourselves how that single line of code might put these foundations at risk. Are we following the best practices of the community? Are we acting responsibly with our creative skills and the technology we use to execute those skills? Are we fulfilling our obligations to sociaty by taking every precaution?
We also have a responsibility to teach. To train and raise developers who are starting in this field in methods and practices which can prevent these kind of problems. And to work together to ensure that a solid security model is practiced with the first line of code.
Filed in Blog, Design Process
Recent Posts
From our Customers
I want you to know there are tears of joy coming down my face. Great Job!
[They] work hard, give you good feedback, deliver results, and have an eclectic feature set.
Dallas and his team has the upmost professionalism and eye for detail.
He is the guy who has tattooed the phrase "Nothing is Impossible" on his forehead!
Dallas and his team as Master Web Design are the best I have worked with - period.
3567 Responses to “The Web Developer's Responsibility to Society”
Leave a Reply