78 lines
1.9 KiB
Plaintext
78 lines
1.9 KiB
Plaintext
include::../description.adoc[]
|
|
|
|
== Noncompliant Code Example
|
|
|
|
----
|
|
using System;
|
|
using System.Xml;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace WebApplicationDotNetCore.Controllers
|
|
{
|
|
public class RSPEC2091XPathInjectionNoncompliant : Controller
|
|
{
|
|
public XmlDocument doc { get; set; }
|
|
|
|
public IActionResult Index()
|
|
{
|
|
return View();
|
|
}
|
|
|
|
public IActionResult Authenticate(string user, string pass)
|
|
{
|
|
String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']"; // Unsafe
|
|
|
|
// An attacker can bypass authentication by setting user to this special value
|
|
// user = "' or 1=1 or ''='";
|
|
|
|
return Content(doc.SelectSingleNode(expression) != null ? "success" : "fail"); // Noncompliant
|
|
}
|
|
|
|
}
|
|
}
|
|
----
|
|
|
|
== Compliant Solution
|
|
|
|
----
|
|
using System;
|
|
using System.Text.RegularExpressions;
|
|
using System.Xml;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace WebApplicationDotNetCore.Controllers
|
|
{
|
|
public class RSPEC2091XPathInjectionCompliant : Controller
|
|
{
|
|
public XmlDocument doc { get; set; }
|
|
|
|
public IActionResult Index()
|
|
{
|
|
return View();
|
|
}
|
|
|
|
public IActionResult Authenticate(string user, string pass)
|
|
{
|
|
// Restrict the username and password to letters only
|
|
if (!Regex.IsMatch(user, "^[a-zA-Z]+$") || !Regex.IsMatch(pass, "^[a-zA-Z]+$"))
|
|
{
|
|
return BadRequest();
|
|
}
|
|
|
|
String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']"; // Compliant
|
|
return Content(doc.SelectSingleNode(expression) != null ? "success" : "fail");
|
|
}
|
|
|
|
}
|
|
}
|
|
----
|
|
|
|
include::../see.adoc[]
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
include::../comments-and-links.adoc[]
|
|
endif::env-github,rspecator-view[]
|