Skip to content
Back to skills

Sql Injection Defense

ASecurity

Detects SQL injection risks in .NET + EF Core: flags FromSqlRaw with non-static string arguments, distinguishes safe FromSqlInterpolated from concatenated queries, reviews stored procedure EXEC patterns for dynamic SQL, and checks Dapper query strings for parameter hygiene. Maps all findings to CWE-89 / OWASP A03:2021 and emits them in the /fsp-audit findings schema. Defers query-optimization decisions to the dotnet-data plugin.

  • 2 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 6, 2026
developmentgoc#sqlapidatabasesecurity

Works with

  • api

Security analysis

A100/100

Scanned September 6, 2026

npx -y skills add AgenticPawan/FullStack-Pilot --skill sql-injection-defense --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Sql Injection Defense?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Sql Injection Defense
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/agenticpawan-sql-injection-defense/badge)](https://www.skillsdirectory.com/skills/agenticpawan-sql-injection-defense)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: sql-injection-defense
description: "Detects SQL injection risks in .NET + EF Core: flags FromSqlRaw with non-static string arguments, distinguishes safe FromSqlInterpolated from concatenated queries, reviews stored procedure EXEC patterns for dynamic SQL, and checks Dapper query strings for parameter hygiene. Maps all findings to CWE-89 / OWASP A03:2021 and emits them in the /fsp-audit findings schema. Defers query-optimization decisions to the dotnet-data plugin."
when_to_use: SQL injection, FromSqlRaw, FromSqlInterpolated, raw SQL, stored procedure, EXEC, sp_executesql, parameterized query, SQL concatenation, Dapper, CWE-89, OWASP A03, security audit
---

## Rule reference

| ID | Standard | Severity |
|----|----------|----------|
| sql-parameterized-queries | OWASP A03:2021 / CWE-89 | block |
| sql-no-fromsqlraw-dynamic | InternalPolicy | block |
| sql-stored-proc-hygiene | InternalPolicy | warn |

---

## Check A — FromSqlRaw with user-controlled input

`FromSqlRaw` is safe only with **fully static** string literals. Any concatenation or interpolation makes it a SQL injection sink.

### BAD — string concatenation (P0)

```csharp
// CWE-89: user input flows directly into raw SQL
var sql = "SELECT * FROM Orders WHERE Status = '" + status + "'";
return await _db.Orders.FromSqlRaw(sql).ToListAsync();

// Also bad — FormattableString constructed manually
var sql = string.Format("SELECT * FROM Users WHERE Name='{0}'", name);
_db.Users.FromSqlRaw(sql);
```

### BAD — string interpolation (P0)

```csharp
var sql = $"SELECT * FROM Users WHERE Name = '{name}'";
_db.Users.FromSqlRaw(sql);   // EF cannot parameterise this
```

### GOOD — EF Core LINQ (always preferred)

```csharp
var users = await _db.Users
    .Where(u => u.Name == name)
    .ToListAsync();
```

### GOOD — FromSqlInterpolated (when raw SQL is necessary)

```csharp
// EF Core converts the interpolation to DbParameters automatically
return await _db.Orders
    .FromSqlInterpolated($"SELECT * FROM Orders WHERE Status = {status}")
    .ToListAsync();
```

**Detection rule:** scan for `FromSqlRaw(` where the argument is not a `const` string or string literal without variable references. Any `+`, `$"..."`, `string.Format`, or `string.Concat` in the argument is a finding.

---

## Check B — ExecuteSqlRaw and ExecuteSqlInterpolated

Same split as above.

```csharp
// BAD: P0 — executes arbitrary SQL
await _db.Database.ExecuteSqlRaw($"DELETE FROM Logs WHERE UserId = {userId}");

// GOOD: EF Core converts to parameter
await _db.Database.ExecuteSqlInterpolated(
    $"DELETE FROM Logs WHERE UserId = {userId}");
```

---

## Check C — Stored procedure EXEC patterns

Dynamic stored procedure invocation is vulnerable when parameter values are concatenated into the EXEC string.

```csharp
// BAD: sp_executesql called with concatenated SQL
var cmd = $"EXEC sp_GetUser '{username}'";
await _db.Database.ExecuteSqlRaw(cmd);   // P0

// GOOD: stored proc called as fixed string with parameters
await _db.Database.ExecuteSqlInterpolated(
    $"EXEC sp_GetUser {username}");       // EF parameterises username
```

If `sp_executesql` is invoked from C# with a dynamic `@sql` argument built by concatenation, that is a separate P0 finding citing both the C# call site and the T-SQL pattern.

---

## Check D — Dapper (when used alongside EF Core)

```csharp
// BAD: string interpolation in Dapper query
var sql = $"SELECT * FROM Users WHERE Email = '{email}'";
var user = conn.QueryFirstOrDefault<User>(sql);

// GOOD: Dapper anonymous-object parameters
var user = conn.QueryFirstOrDefault<User>(
    "SELECT * FROM Users WHERE Email = @Email",
    new { Email = email });
```

---

## Finding output format

Emit one finding per injection site in the /fsp-audit schema:

```json
{
  "source": "semantic",
  "severity": "P0",
  "cwe": "CWE-89",
  "owasp": "A03:2021",
  "file": "src/Api/Repos/OrderRepository.cs",
  "line": 18,
  "title": "SQL injection via string concatenation into FromSqlRaw",
  "evidence": "var sql = \"SELECT * FROM Orders WHERE Status = '\" + status + \"'\";",
  "proposedFix": "Replace with FromSqlInterpolated($\"...{status}...\") or EF Core LINQ",
  "batchable": true,
  "confidence": "high"
}
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.