75 lines
1.8 KiB
Plaintext
75 lines
1.8 KiB
Plaintext
![]() |
include::../description.adoc[]
|
||
|
|
||
|
== Noncompliant Code Example
|
||
|
|
||
|
----
|
||
|
using Microsoft.AspNetCore.Mvc;
|
||
|
using Microsoft.EntityFrameworkCore;
|
||
|
using WebApplication1.Controllers;
|
||
|
|
||
|
namespace WebApplicationDotNetCore.Controllers
|
||
|
{
|
||
|
public class RSPEC3649SQLiNoncompliant : Controller
|
||
|
{
|
||
|
private readonly UserAccountContext _context;
|
||
|
|
||
|
public RSPEC3649SQLiNoncompliant(UserAccountContext context)
|
||
|
{
|
||
|
_context = context;
|
||
|
}
|
||
|
|
||
|
public IActionResult Authenticate(string user)
|
||
|
{
|
||
|
string query = "SELECT * FROM Users WHERE Username = '" + user + "'";
|
||
|
|
||
|
// an attacker can bypass authentication by setting user to this special value
|
||
|
// user = "' or 1=1 or ''='";
|
||
|
|
||
|
var userExists = false;
|
||
|
if (_context.Database.ExecuteSqlCommand(query) > 0) // Noncompliant
|
||
|
{
|
||
|
userExists = true;
|
||
|
}
|
||
|
|
||
|
return Content(userExists ? "success" : "fail");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
----
|
||
|
|
||
|
== Compliant Solution
|
||
|
|
||
|
----
|
||
|
using Microsoft.AspNetCore.Mvc;
|
||
|
using Microsoft.EntityFrameworkCore;
|
||
|
using WebApplication1.Controllers;
|
||
|
|
||
|
namespace WebApplicationDotNetCore.Controllers
|
||
|
{
|
||
|
public class RSPEC3649SQLiCompliant : Controller
|
||
|
{
|
||
|
private readonly UserAccountContext _context;
|
||
|
|
||
|
public RSPEC3649SQLiCompliant(UserAccountContext context)
|
||
|
{
|
||
|
_context = context;
|
||
|
}
|
||
|
|
||
|
public IActionResult Authenticate(string user)
|
||
|
{
|
||
|
var query = "SELECT * FROM Users WHERE Username = {0}"; // Safe
|
||
|
|
||
|
var userExists = false;
|
||
|
if (_context.Database.ExecuteSqlCommand(query, user) > 0)
|
||
|
{
|
||
|
userExists = true;
|
||
|
}
|
||
|
|
||
|
return Content(userExists ? "success" : "fail");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
----
|
||
|
|
||
|
include::../see.adoc[]
|