Secure Web Development
Secure Web Development
Nathan Fox
Beginning web application developers have a tendency to focus so strongly on getting an application
to work correctly that they forget one critical component of development—security. To effectively
protect a web application, developers have to think like hackers and have to know what kinds of
attacks to expect, which is difficult for beginning developers who lack experience with hackers.
Hackers can exploit security vulnerabilities to access or delete user data, to break the application’s
functionality, to prevent legitimate users from accessing the application, or even to gain control of
the servers the application is running on.
Security is a big issue in the professional world, and even professionals make mistakes. Consider
these security breaches that made headlines:
In December 2013, hackers accessed credit card data for 40 million Target shoppers, leading
to over 90 lawsuits and a noticeable decline in Target’s sales (Riley, Elgin, Lawrence, &
Matlack, 2014).
In an attack on Home Depot’s systems nearly a year later, 56 million credit card numbers and
email addresses were compromised (Banjo, 2014).
A well-orchestrated attack on Code Spaces, an application where users could collaboratively
write source code, forced the company out of business when the attackers wiped its databases
(Code Spaces, 2014).
Developers must understand how to secure their web applications if they want to protect their users,
data, and servers. This chapter discusses common attacks that hackers use and what developers can
do to defend against them.
Packet Sniffing
The internet works by sending electromagnetic signals through wires, fiber optic cables, and the air.
These signals represent the data sent between machines and are separated into small groups of data
known as packets. Packet sniffing occurs when the attacker uses a wire tap or a radio receiver to
record packets that are in transit. All packets sent over the internet are vulnerable to packet sniffing.
The only way to protect sensitive data is to encode the data in such a way that only the intended
recipient can decode it. In other words, data must be encrypted while in transit in order to be secure.
The HTTPS protocol. Fortunately, application developers are not expected to write code to encrypt
data. There is an existing internet protocol that performs encryption and decryption operations:
HTTPS. HTTPS uses a secure method (known as a handshake) to establish encryption and decryption
keys between the server and the client. By enabling the HTTPS protocol on an application’s web
servers, the developer can ensure that all web traffic between the server and the client will be
encrypted. If any packets are recorded by packet sniffers, the encrypted data will be indecipherable.
The process of enabling HTTPS is different for every server, so developers will need to refer to their
server’s documentation for specific instructions. Though enabling HTTPS may seem like a hassle for a
beginning developer, it is necessary to secure any sensitive information that flows between users and
the application servers.
Email. If a web application communicates with users by sending emails, the developer must be
careful to not include any sensitive information in those emails. Most email protocols (e.g., POP3,
IMAP, SMTP, HTTP) do not encrypt data that is in transit. As a general rule, expect email to not be
secure (Duncan, 2013). If a web application needs to communicate sensitive information to a user,
the application should send a generic email prompting the user to log into the application and then
display the sensitive information to the user once the user logs in.
The process of logging into an application is also known as authentication. A user provides
authentication tokens—typically a username and password—to the application, and the application
confirms that the tokens are authentic. Once a user’s identity is confirmed, the application uses
authorization rules to decide what data the user is allowed to access and what actions the user is
allowed to perform. For example, a standard user may be authorized to write comments, view
personal comments, and view comments written by friends. An administrative user, on the other
hand, may be authorized to view, modify, or delete any comments.
Server-side code is code that is executed on the application’s servers. Common server-side
programming languages include Java, ASP.NET, PHP, Python, Ruby, and Node.js. Server-side code
acts as an intermediary between the client and the data, so data will not be secure if the server-side
code fails to protect it. Whenever a user makes a request to one of the application’s servers, the
server should verify that the user is authorized to perform the request. If the user is not authorized,
the server should respond with an error message and terminate the request. Then, even if a user is
able to circumvent any client-side defenses, the server will enforce the authorization rules to help
keep the data secure.
Password Cracking
If attackers cannot find a way to bypass authorization rules, they may try to guess or steal the
authentication tokens of other users. Although users are primarily responsible for securing their own
passwords, there are ways for application developers to help protect user passwords:
Never send a password in an email or over a connection that is not using the HTTPS protocol.
Only exchange passwords over encrypted connections to protect passwords from packet
sniffing.
Never store raw passwords. Instead, use a cryptographic hash function (such as a SHA-2
algorithm) on a password to get a digest, then store the digest. When a user provides a
username and password, run the same hash function on the given password and compare that
digest to the stored digest to authenticate. If an attacker manages to steal the application’s
password digests, it will still be very difficult for the attacker to recover the original
passwords.
Enforce a cap on how many times a user is allowed to attempt to log in with a wrong password.
Attackers may try to use computer programs to submit thousands of authentication attempts in
just a few seconds. If a single user fails to provide a correct password after several attempts,
the application should not allow the user to try to authenticate again for a period of time. This
prevents an attacker from trying millions of guesses until the correct password is found.
By helping users secure their passwords, application developers can reduce the likelihood of
successful attacks and keep sensitive user data from getting into the wrong hands.
Code Injection
If a web application stores user input in a database or shares one user’s input with other users, then
SQL injection. SQL is a querying language that developers use to interact with relational databases.
Hackers may try to use SQL injection to make unauthorized changes to a web application’s database.
Fig. 1 illustrates an example in which the developer uses PHP as the server-side programming
language and SQL as the database language. The developer builds an insert statement (a line of SQL
code used to add new data to a database) and places the user’s comment into the insert statement. If
the user submits a typical comment (e.g., “I had a great time at the lake today!”), then the comment
will be successfully saved in the database. However, a hacker may try to attack the database by
trying to submit SQL code as a user comment. For example, if the user submits “test`, `hacker123`,
now()); DROP TABLE user_comments;--” as a comment, then all user comments will be deleted from
the database, and the developer will be left with nothing but a group of angry users.
Figure 1
An Example of How a Hacker Might Use SQL Injection to Make Unauthorized Changes to Data
For a web application that needs to save user input into a relational database, the developer must
protect against SQL injection to keep the data safe. Developers can use code libraries (such as PHP’s
PDO library) that can prepare SQL statements in a safe way by removing parts of user input that may
be unsafe to execute (cf. Fig. 2). For databases that do not use SQL (e.g., MongoDB, Cassandra,
Redis), there are still vulnerabilities to code injection attacks. To effectively defend web applications
that use NoSQL databases, developers must research vulnerabilities and learn about recommended
precautions to take.
Figure 2
An Example of How a Developer Can Use Prepared Statements to Prevent SQL Injection
Stripping HTML tags from user input is a relatively simple method to implement. A web application
sanitizes user input by removing all HTML tags (defined by text between the < symbol and the >
symbol) from the input, then stores the sanitized input in the database. When the web application
retrieves that data from the database and displays it to another user, the lack of HTML tags will allow
the other user’s client to display the input text without executing any code.
The main limitation of stripping away all HTML tags is that the developer may want to allow the user
to input certain HTML tags—such as hyperlinks, lists, tables, or formatting tags—to make the
application more flexible and user-friendly. Whitelisting HTML tags is done by enumerating a list of
acceptable tags and removing all other tags from user input. This method may be difficult to
implement for beginning developers, but many programming languages have libraries (such as the
OWASP HTML sanitizer) that implement whitelisting functions that are relatively simple for
developers to use. Due to the complexity of whitelisting functions, beginning developers may want to
look for available sources before attempting to write these functions on their own.
Distributed Denial-of-Service
To execute a distributed denial-of-service (DDoS) attack, a hacker programs multiple devices (or bots)
to flood a web application’s servers with requests. The application servers utilize all of their
resources to respond to the hacker’s flood of requests, making it difficult for legitimate users to get
any data from the application server. Servers may eventually be driven into a state of deadlock and
crash. Because the hacker uses multiple bots with unique MAC addresses and IP addresses, it is
difficult for the application servers to distinguish between the hacker’s requests and legitimate
requests. If a web application falls prey to a distributed denial-of-service attack, the developer can
purchase third-party DDoS mitigation software that thoroughly analyzes incoming traffic in an
attempt to distinguish bot requests from legitimate user requests.
Buffer Overflow
A buffer overflow attack (also known as a stack smashing or stack overflow attack) is an attack that is
very difficult for hackers to execute, as it generally requires a lot of guessing and a lot of luck. The
goal of a buffer overflow attack is to hack into the operating system of one of the web application’s
servers. The attack is executed by injecting binary—also known as bytecode or machine code—into
the web application’s run-time stack. The run-time stack is part of the server’s RAM (memory) that is
Conclusion
Protecting a web application is not simple, but it can be critical to the application’s success. Hackers
use a wide variety of attacks to access sensitive data, and it is important for developers to understand
how those attacks work and how to effectively defend against them. By taking time during the initial
development phase to learn about and implement security features, web application developers will
save their time, their money, their customers, and their data in the long run.
References
Banjo, S. (2014). Home Depot hackers exposed 53 million email addresses. The Wall Street Journal.
Retrieved from
http://www.wsj.com/articles/home-depot-hackers-used-password-stolen-from-vendor-1415309282
Code Spaces. (2014). Code Spaces: Is down! Code Spaces. Retrieved June 18, 2014, from
http://www.codespaces.com/
Duncan, G. (2013). Here’s why your email is insecure and likely to stay that way. Digital Trends.
Retrieved from
http://www.digitaltrends.com/computing/can-email-ever-be-secure/#:rHaYKy9xLnMJFA
Frykholm, N. (2000). Countermeasures against buffer overflow attacks. RSA Laboratories. Retrieved
from
http://www.isiloniq.com/emc-plus/rsa-labs/historical/countermeasures-against-buffer-overflow-att
acks.htm
Riley, M., Elgin, B., Lawrence, D., & Matlack, C. (2014). Missed alarms and 40 million stolen credit
card numbers: How Target blew it. Bloomberg. Retrieved from
http://www.bloomberg.com/news/articles/2014-03-13/target-missed-warnings-in-epic-hack-of-cred
it-card-data