
Last week, I deployed my first web applications, a big moment in any developer’s life. One app, a guestbook for my friend’s wedding, was written in Ruby, dependent on the Sinatra gem and deployed through Heroku. It consisted of a simple form where friends and family could leave messages for the happy couple.
I excitedly posted a link to the application on Twitter, and moments later my app was hacked. Silly me, I forgot to secure my web form:
In my case, I was lucky. My app was hacked by someone I knew, and all they did was drop an HTML <div> into the form which changed the CSS properties of my website. Without form security, I was also vulnerable to more dangerous html injections such as script injections. Silver lining.
Injections
An injection is any code injected into an application. Instead of inputting the intended text, code can be injected into a form which the browser or web application will read and render as part of the program. Injections can come in three general forms: (1) HTML injections, including script injections, (2) SQL injections and (3) mass assignment.
SQL Injections
SQL injections are used to attack data-driven applications which use a database. A SQL command can be entered which will manipulate the application’s database. This cartoon, ironically the same cartoon that took over my web application, depicts one of the many risks associated with SQL injections:
SQL injections can not only drop databases; they can be used to steal the personal information stored in those databases. If you haven’t been living under a rock for the past decade, you’ve probably read about well known SQL injection attacks to Yahoo, Target and many large retailers. Even MySQL has been the victim of a SQL injection attack. Due to the number of attempted SQL injections, web applications should not be left unsecured for even a short period of time.
SQL injections can be complicated. If you’d like to learn more about how SQL injections are carried out, the following resources can help:
Sanitizing Data
The first step to securing your forms is to sanitize data. This can be difficult, but there are certain steps that should always be taken, including escaping user input, regular testing for vulnerabilities and stricter password policies.
Escaping User Input
Escaping user input is the process of sanitizing the data input into your application. In the case of my Sinatra application, instead of reading the text included in the message form, the strong_params and html_safe methods are now called (see below).
post '/messages' do @message = Message.new(strong_params) if @message.save redirect to("/messages/#{@message.id}") else erb :"messages/new" end end def strong_params params[:message].each_with_object({}) do |pair,hash| hash[html_safe(pair[0])] = html_safe(pair[1]) end end def html_safe(text) Rack::Utils.escape_html(text) end
To learn more about sanitizing user input for Sinatra applications, see the Frequently Asked Questions.
- PM Career Story - April 28, 2022
- How to Transition into Product Management - December 26, 2017
- What I’ve Learned in My First Few Months as a Product Manager - October 14, 2015
Thanks for writing such an eatn-so-understayd article on this topic.