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
  • 2 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…