Injection flaws are one of the oldest yet most dangerous classes of software vulnerabilities. They happen when unverified input is passed into interpreters like SQL, shell commands, or XML queries without proper safeguards. As a result, attackers can directly commit crimes like data theft or system compromise.
Besides SQL injection, there are other injection risks that modern applications may experience. Read to learn about the major types of injection flaws, how they enter code, and what teams can do to prevent and mitigate them across the CI/CD pipeline.
What are injection flaws in software security?
Injection flaws are vulnerabilities in apps that let attackers send untrusted data or malicious code. This manipulates the interpreter into remote code execution. In other words, they may run commands or retrieve data that was never meant to be accessed.
Injection flaws are dangerous because they’re easy to exploit and often give direct access to sensitive systems. In fact, they consistently rank in the OWASP Top 10 web application risks.
Common examples include SQL injection, command injection, Lightweight Directory Access Protocol (LDAP), XPath, and NoSQL injection, each of which targets a different kind of query or data layer. Across all these attacks, user input, such as search boxes and API parameters, is the most common attack surface.
SQL injection vs. other injection flaws
SQL injection is the most well-known injection flaw, but it’s not the only one. Each injection flaw type targets a different layer of the application stack.
- SQL injection targets database queries. Attackers do this by modifying or inserting malicious SQL code into inputs like login forms. A common example is entering
' OR '1'='1, which can trick the system into bypassing authentication. - Command injection or OS command injection targets the operating system shell. This happens when a vulnerable app passes unsanitized or unverified user input directly to functions like exec() or
system()calls. An attacker might inject something likeping 10.0.0.1 && rm -rf /to run destructive operating system commands on the host. - LDAP injection manipulates directory queries that apps use to retrieve or authenticate users. It lets attackers retrieve unauthorized user details. For instance, injecting
(uid=*)can expose every record in a directory service. - XPath injection exploits XML navigation by manipulating XPath queries. An attacker could submit a string like
username=') or '1'='1to bypass application logic and gain access. - NoSQL injection manipulates schema-less database queries that accept dynamic inputs. In MongoDB, for example, adding
{ "$ne": null }into a filter condition can bypass intended checks and return unauthorized data.
Here’s how all of these injection flaws compare.
| Injection type | Target | Impact | Relative risk |
| SQL injection | Relational databases | Exfiltration of financial/health data | Critical — common, easy to automate, attackers routinely scan for it |
| Command injection | OS shell | Full server compromise | Critical — one of the most devastating, often trivial to exploit |
| NoSQL injection | Schema-less databases | Escalated privileges, data corruption | Critical — mirrors SQLi impact, defenses less standardized |
| LDAP injection | Directory services | Unauthorized access to user accounts | High — requires more context, but serious in enterprise apps |
| XPath injection | XML data stores | Data leakage or authentication bypass | Medium–High — less common today, moderate effort to exploit |
How injection flaws are introduced into code
Injection encoding flaws can creep in through everyday coding shortcuts, unsafe design decisions, and the pressures of rapid release cycles. Here’s how these flaws usually happen.
Poor input validation and unsafe code practices
Injection flaws usually happen when developers directly embed user input into queries without verification. A common anti-pattern looks like this:
"SELECT * FROM users WHERE username = '" + input + "';"
Here, the app takes whatever a user types into a field (the input variable) and plugs it straight into the SQL statement. If the user enters a normal value like alice, the query runs as expected. But if an attacker enters ' OR '1'='1, the database interprets it as:
SELECT * FROM users WHERE username = '' OR '1'='1';
Since '1'='1' is always true, the query now returns all users instead of just one. That’s how a simple login form can be tricked into giving away sensitive data.
This pattern still shows up in production code when teams skip parameterized queries or rely only on client-side validation. Without strong safeguards, a single input field can become a gateway for attackers.
Common developer mistakes
Several common developer mistakes keep injection flaws alive in modern codebases:
- Using string concatenation instead of parameterized queries. Attackers know these patterns and can exploit them with off-the-shelf payloads.
- Relying on client-side validation only. Anything running in the browser can be bypassed; attackers will always test inputs directly against the backend.
- Forgetting to sanitize special characters. Delimiters like
;,&&, or$nein NoSQL queries give attackers a foothold.
These mistakes can lead to injection flaws, causing significant damage. In 2022, the Optus breach in Australia happened when an exposed API failed to check input, leading to 9 million leaked customer records.
Agile teams & CI/CD pressure
If a team uses Agile and DevOps practices, which emphasize quick iteration, they can easily fall for injection flaws if they don’t use guardrails. Here’s how:
- Skipping peer review to meet sprint deadlines.
- Moving security tickets down the backlog so they can focus on new features.
- Testing environments don’t mirror production closely enough. As a result, exploits aren’t caught until it’s too late.
How to prevent injection flaws in CI/CD environments
Fortunately, there are ways to prevent injection flaws in CI/CD environments. Follow these steps to get started:
Input sanitization and validation
Don’t let users enter any character or string. Instead, set strict whitelists for formats like email addresses, IDs, or dates only. For example, if a field should only contain numbers, reject everything else. This prevents attackers from sneaking special characters that can change the logic of queries.
Prepared statements and parameterized queries
At the coding layer, developers should rely on APIs that separate data from logic. Prepared statements in Java (PreparedStatement) or parameterized queries in .NET (SqlCommand.Parameters) ensure that user input is treated purely as data, not executable code. As such, even if an attacker tries to inject malicious strings, the database interprets them safely rather than executing them.
Static application security testing (SAST)
Automated SAST tools scan source code during the build stage and flag insecure coding patterns, such as string concatenation in SQL queries or unsanitized shell commands. Since SAST runs early in the software development lifecycle (SDLC), it reduces the number of flawed builds that make it downstream. As a result, developers have more time to focus on high-level tasks rather than constantly having to rewrite and rebuild.
Dynamic application security testing (DAST)
DAST or black-box testing is a cybersecurity testing method for identifying misconfigurations and vulnerabilities in web apps, mobile apps, and APIs. Unlike SAST, it tests apps in their runtime environment without accessing their source code. Rather, it stimulates real-world attacks to mimic malicious actors’ behavior. For example, a DAST tool might inject ‘ OR ‘1’=’1 into a login form to test if authentication can be bypassed. This validates fixes before release, and DAST compiles results into reports that outline vulnerabilities, their severity, and possible attack scenarios.
Runtime Application Self-protection (RASP)
RASP tools find and block attacks by using information from the running software. When RASP detects a malicious query or command, it can block execution right away and log details for investigation. An example of a RASP tool is PreEmptive’s Dotfuscator. Made to protect MAUI and .NET-based apps, it provides multiple C# code obfuscation methods that make your app safer from threat actors and their decompiling tools.
Example: Mitigating command-injection risk in an industrial control panel
Here’s an example showing how a development team can prevent injection flaws in a CI/CD environment.
Imagine a web-based control panel used by industrial plant technicians to run on-demand diagnostics against factory equipment. The UI accepted a hostname and then built a shell command like:
ping + userHostname
That shortcut looked convenient, since technicians could type a device name and get immediate results. Unfortunately, the app handed the user text straight to the shell. When an attacker typed device42; rm -rf /tmp/logs, the application dutifully executed the whole string, not just the ping. Suddenly, crucial logs were deleted, and a maintenance VM was partially sabotaged.
The incident forced the development team to rethink the code. First, they removed direct shell calls and used native network libraries and APIs that return structured results without invoking a shell. They also added strict whitelists for allowed hostnames and enforced regex validation on any user-supplied identifiers. Additionally, they added SAST rules to CI builds to flag dangerous exec() or system() usage, and ran DAST tests to simulate malicious payloads against the diagnostic endpoint. Finally, the team deployed a runtime protection layer (RASP) to detect suspicious system-call patterns and block them in real time.
Because the team shifted execution away from the shell, minimized privileges for maintenance processes, and layered in runtime defenses, they managed to protect the system from a similar attack. This time, the system rejected the input at validation and blocked and logged an attempted execution before any damage occurred.
CI/CD security workflow: Key stages to test for injection flaws
To successfully protect code from SQL injection and other injection flaws, you need to ensure each stage of the SDLC is protected.
Below is a high-level walkthrough of where to test, what to run, and why it matters.
- Plan: Start by modeling threats. Map data flows, identify high-risk inputs such as forms and APIs, and tag stories that touch sensitive data. Add security acceptance criteria to user stories so testing isn’t optional.
- Develop: Enforce secure coding patterns at commit time. Use linters and pre-commit hooks that flag unsafe constructs (string concatenation in queries,
exec()usage). Further, require peer review for changes touching inputs or parsing logic. Also, add unit tests that assert sanitization behavior. - Build: The build stage is where code is compiled and packaged for release. The team should run SAST here to spot unsafe patterns like raw SQL concatenation or shell calls. If the scanner finds a serious flaw, the build should fail so the issue is fixed right away.
- Test: During staging, run DAST and fuzzing to see how the app behaves under attack. Use automated payloads like SQLi or NoSQL injections against environments that mirror production. Regression tests can also ensure old injection flaws stay fixed.
- Deploy: Before releasing, make sure limitations are in place. Only deploy artifacts that pass SAST/DAST checks, are signed, and are built immutably. Run apps with least-privilege accounts and segment networks so a single flaw can’t take down everything.
- Monitor: Once in production, keep watch with runtime protection and observability tools. RASP, WAF telemetry, and APM traces help flag and block suspicious queries. Feed those alerts back into the backlog so each new cycle starts with better defenses.

How PreEmptive helps mitigate injection flaws
If you’re looking for a powerful tool to defend against SQL injection and other injection flaws, PreEmptive is here to help. A powerful suite of application security solutions, PreEmptive provides runtime protection and code obfuscation. These features can protect your data and systems when vulnerabilities sneak past coding standards and automated testing. Here’s how:
- Runtime protection means monitoring the application while it’s actually running, not just before deployment. Instead of standing outside the app like a firewall, runtime protection works inside the code, watching queries and commands as they execute. As such, it’s especially effective against injection flaws. It can stop malicious input at the very moment it tries to run. PreEmptive’s Runtime Application Self-Protection (RASP) technology is a great example of runtime protection. It detects unusual query patterns, intercepts suspicious input, and blocks the execution of malicious payloads before sensitive systems are exposed. For instance, if someone tries a classic SQL injection attack with a string like ‘ OR ‘1’=’1, PreEmptive can catch and neutralize it on the spot.
- Obfuscation makes applications harder to reverse-engineer by disguising variable names, altering control flows, and hiding sensitive strings. To a hacker with a decompiler, the code appears to be a confusing tangle. That extra layer of complexity makes it far more difficult to identify injection points or craft reliable exploits.
Together, runtime protection and obfuscation make exploitation significantly harder. However, their real strength lies in being part of a broader security strategy. Most teams already rely on secure coding, peer reviews, and penetration testing to reduce the odds of injection flaws reaching production. However, PreEmptive builds on top of those efforts by adding runtime protection to malicious behavior as it happens. It also adds code
Bottom line
SQL injection may be the most well-known and common example of an injection security vulnerability. However, command, LDAP, XPath, and NoSQL injection vulnerabilities can be just as devastating to systems. As such, your IT team needs to take proper precautions against all of them.
That’s why you should consider adopting PreEmptive. Trusted by over 5,000 companies globally, our app security solutions prevent injection flaws and other cybersecurity risks. Start your free trial today.
FAQ
What are the most common injection flaws?
SQL code injection and command injection are the most common type of attack. However, NoSQL injection is becoming more popular as more organizations adopt MongoDB and other schema-less databases.
Are injection flaws still a major concern?
Yes. Injection attacks still consistently appear in real-world breaches. Automated bots scan the internet for them daily.
Can secure coding alone prevent all injection flaws?
No. Secure coding reduces the risk of injection flaws, but teams must perform runtime defenses and continuous testing for layered security.
How does runtime protection differ from SAST/DAST?
SAST analyzes the app’s source code to spot flaws before it runs. Meanwhile, DAST tests the app while it’s running. It stimulates real-world attacks to find vulnerabilities that SAST may not detect.
Finally, RASP or runtime protection protects the app during runtime. It spots and blocks threats in real-time from inside the app.







