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[]
