In theory, modern web frameworks provide secure ways of accessing databases, making SQL injections a non-issue. The reality looks much different. Among other injection vulnerabilities, SQL injections are still atop the OWASP Top 10, and organizations still frequently fall victim.
Therefore there is no way around software security testing solutions that can reliably detect SQL injections. In this blog, I will discuss the role of application security testing in keeping these incessant attacks at bay, as well as some best practices for your test setup. But first, let's do a quick recap of why SQL injections are still an issue in this day and age.
Why It Is so Hard to Test for SQL Injections
In 2022, SQL injections are still a thing, as they are one of the most exploited security vulnerabilities. In 2021 alone, 718 vulnerabilities with the type "SQL injections" got accepted as a CVE. This is despite the huge influx of commercial and open-source solutions in the market today, all claiming to alleviate SQL injections. Fact is, few of these tools actually live up to the billing (Code Intelligence is proudly one of them).
That said, here are reasons why it is so hard to test for SQL injections:
- Reliable and automated testing methods that facilitate a precise detection of injections are quite scarce
- Modern coding practices minimize the issues arising from database access. However, many applications feature old legacy code that was written during a time of less security awareness
- Access libraries that ought to provide a safe way for accessing databases, i.e. by encouraging the usage of query parameterization, are sometimes misused
- To date, a huge number of web applications still utilize SQL databases in the backend. In other words, attackers are spoilt for choice when it comes to choosing target surfaces for deploying injections
- Not enough developers are engaging in negative testing, which is effective at detecting injection vulnerabilities
The Challenges of Testing for SQL Injections
Detecting SQL injections is as easy as adding a single quote ('), double quote ("), or a SQL keyword like 'AND' in the input field parameter, right? Wrong. Testing for this kind of vulnerability attack is not necessarily a smooth experience for developers, and that's because of a few inherent challenges:
It's Not a Priority
Many organizations do not consider testing for web application security vulnerabilities to be an important endeavor. As such, developers have no option but to spend most of their time building new features and fixing bugs that impact user functionality.
It Only Takes One Vulnerability
The time that developers spend on security testing is limited. Therefore, dev teams have to prioritize and triage the bugs that they find and live with the fact that software can never be 100% bug-free. Attackers generally have a leg-up on devs as they only need to find one single exploitable vulnerability, while devs theoretically need to find all of them.
A Lack of Resources
Development teams run lean and mean these days. They simply don't have the manpower, time, or tools to dedicate to testing and remediating every single vulnerability. Besides, when resources are tight, it can be tempting to circumvent the laid-down rules, which can easily jeopardize the level of application security altogether.
It Requires Joint Commitment
In order to test and consequently eliminate SQL injection vulnerabilities, development and security teams must work in unison. This collaboration can be prone to friction. To enable smooth collaboration, modern dev and security teams opt for CI/CD-integrated tooling with reporting and triaging features that both teams can treat as their point of truth. Across many industries, such testing approaches are considered best practice to detect SQL injections and other OWASP Top 10 vulnerabilities.
Rising threat: drive-by SQL injections
Why Feedback-Based Fuzzing Will Help You Find SQLi
In case you're new to feedback-based fuzzing, here's a quick recap:
Modern fuzzing as we know it today emanated from "brute-force fuzzing", a type of automated software testing that began in the 1980s. It essentially generates random, invalid, and unexpected inputs with the aim of failing the program under test. Consequently, the program being fuzzed is monitored for exceptions such as crashes or memory leaks. This form of fuzzing is considered "black-box" fuzzing, as it uses random inputs and basically test the software under test blindly.
Feedback-based fuzzers, also called "white-box" fuzzers, collect feedback about the code coverage of previous inputs and use it to generate new, more efficient inputs. This way, fuzzers are able to regularly refine and improve test inputs and to monitor which parts of the program they reach.
Here are some specific advantages of this form of SQL injection testing: Not only does feedback-based fuzzing work with a set of predefined inputs, but also evolves these inputs effectively through mutation:
- Reproducible inputs
- Up to 99% code coverage
- No false positives
- It protects against unexpected edge cases
- It can be almost completely automated
- Useful reports that aid in the interpretation of test findings
If you're wondering what bugs you can find with feedback-based fuzzing other than injections, here are a few examples:
- Memory leaks
- Data races
- Software crashes
- Sensitive data exposure
- Buffer overflow
- Uncaught exceptions
- Undefined behavior
- Insecure deserialization
- And many more
Code Coverage Reporting
Code coverage is one of the most important metrics in web security. That said, implementing code coverage into a testing flow requires specific tools. Automated web testing security tools such as RESTler, OWASP ZAP, and Burp are awesome if they're used by experts that know how to customize them and where to look for security vulnerabilities. But for the average developer, these tools require too much manual configuration.
As we mentioned earlier, fuzzing is firmly hinged on the concept of code instrumentation. By instrumenting the target code, fuzzers are able to collect concise feedback about code coverage, which is often presented in a percentage format. This way, mutate inputs to maximize code coverage, to trigger bugs hidden deep within the code.
Improved Error Detection
Modern feedback-based fuzzers utilize instrumentation to closely check an application's interaction with the database. Specifically, they dynamically intercept all method invocations that interact with the database. If a query is erroneous or otherwise warped, modern fuzzing tools will uncover this.
The perfect fuzzing setup would intercept all database-related method invocations imaginable. As a result, these platforms are able to collect information about executed queries and to check queries that are not instantly triggered by a user request.
Modern fuzzing solutions support CI/CD-integrated application security testing. This means that dev teams can automatically test their code for SQL injections and other vulnerabilities at each pull request (or at each code change, depending on configuration). Such test automation minimizes the manual effort required to identify security issues in software and makes fuzzing - one of the most powerful software testing approaches out there.
Fuzz Your Own Code
If you are looking for a solution to implement dev-friendly and powerful testing software into your development process, fuzz testing is likely a good fit for you. The Code Intelligence Platform enables you to run automated fuzz tests without ever leaving your favorite dev environment. It comes with an easy-to-use GitHub integration and debugging feature that allows you to reproduce all findings without weary false positives. See for yourself!