security-review/canary/src/dotnet/PaymentController.cs

60 lines
2 KiB
C#
Raw Normal View History

// Exercises the reviewer's recall on the .NET stack.
using System;
using System.Data.SqlClient;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.Mvc;
namespace SeaHaven.Payments
{
[ApiController]
[Route("api/payments")]
public class PaymentController : ControllerBase
{
private const string ConnStr =
"Server=prod-pay.cluster-czaa.us-east-1.rds.amazonaws.com;Database=payments;User Id=app;Password=P@y-Pr0d-2026!;";
[HttpGet("{id}")]
public IActionResult GetPayment(string id)
{
using var conn = new SqlConnection(ConnStr);
conn.Open();
var cmd = new SqlCommand("SELECT * FROM Payments WHERE Id = '" + id + "'", conn);
using var reader = cmd.ExecuteReader();
// ?id=' OR '1'='1 returns every payment
return Ok(reader.HasRows);
}
[HttpGet("session")]
public IActionResult LoadSession()
{
var raw = Convert.FromBase64String(Request.Cookies["session"] ?? "");
var fmt = new BinaryFormatter();
using var ms = new MemoryStream(raw);
var obj = fmt.Deserialize(ms); // crafted payload → RCE
return Ok(obj.ToString());
}
[HttpPost("hash")]
public IActionResult HashPassword([FromBody] string password)
{
using var md5 = MD5.Create();
var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(password));
return Ok(Convert.ToHexString(hash));
}
[HttpGet("by-status")]
public IActionResult ByStatus(string status)
{
using var conn = new SqlConnection(ConnStr);
conn.Open();
var cmd = new SqlCommand("SELECT Id FROM Payments WHERE Status = @status", conn);
cmd.Parameters.AddWithValue("@status", status);
using var reader = cmd.ExecuteReader();
return Ok(reader.HasRows);
}
}
}