SQL Injection

Prevalence

Occasional

⚙️⚙️

Exploitability

Easy

🔧🔧

Impact

Devastating

💀💀💀

SQL injection is a type of injection attack. Injection attacks occur when maliciously crafted inputs are submitted by an attacker, causing an application to perform an unintended action. Because of the ubiquity of SQL databases, SQL injection is one of the most common types of attack on the internet.

If you only have time to protect yourself against one vulnerability, you should be checking for SQL injection vulnerabilities in your codebase!

Risks

What's the worst thing that could happen when you suffer a SQL injection attack?

Our example hack showed how to bypass the login page — a critical security flaw for a banking site. More complex attacks will allow an attacker to run arbitrary statements on the database. In the past, hackers have used injection attacks to:

  • Extract sensitive information, like Social Security numbers or credit card details.
  • Enumerate user authentication details, which can be reused on other sites.
  • Delete data or drop tables, corrupting the database and breaking the site.
  • Inject malicious code executed when users visit the site.

SQL injection attacks are astonishingly common. Major companies like Yahoo and Sony have been compromised. Hackers also target specific applications or write scripts to harvest user data. Not even security firms are immune.

Protection

So SQL Injection is a serious risk. How can you protect yourself?

Parameterized Statements

Parameterized statements ensure inputs are treated safely. For example, in JDBC:

Connection conn = DriverManager.getConnection(URL, USER, PASS);
String sql = "SELECT * FROM users WHERE email = ?";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, email);
ResultSet results = stmt.executeQuery();

Contrast this with unsafe concatenation:

String sql = "SELECT * FROM users WHERE email = '" + email + "'";
ResultSet results = stmt.executeQuery(sql);

Object Relational Mapping (ORM)

ORMs like Active Record generate safe queries:

def current_user(email)
  User.find_by_email(email)
end

But direct SQL in ORMs can still be vulnerable:

def current_user(email)
  User.where("email = '" + email + "'")
end

Escaping Inputs

Escape inputs if parameterization isn’t possible. Double quotes, e.g., ' becomes ''. But escaping doesn’t protect against numeric injection:

def current_user(id)
  User.where("id = " + id)
end

Sanitizing Inputs

  • Use regex for emails and structured input.
  • Reject unexpected symbols in numeric/alphanumeric fields.
  • Strip whitespace where inappropriate.

Remember: client-side validation is not enough. Most hacks use scripts, not browsers.