Skip to content

Instantly share code, notes, and snippets.

@runewake2
Created September 18, 2022 18:28
Show Gist options
  • Save runewake2/c15f9aa788200a3996a467eb6fe5546d to your computer and use it in GitHub Desktop.
Save runewake2/c15f9aa788200a3996a467eb6fe5546d to your computer and use it in GitHub Desktop.
This is a ASP.NET controller that can execute C# code that is POSTed to it.
// Created by Sam Wronski
// Find more of my work at: worldofzero.com and youtube.com/WorldOfZeroDevelopment
//
// WARNING: This controller exposes the .NET runtime as a web endpoint.
// This could allow third parties to run arbitrary code on your system
// which would be very harmful to your computer and could compromise
// your personal devices and information.
// If you choose to run this inside of a cloud runtime this would also
// make it possible in some cases for people with access to this endpoint
// to exfiltrate details about the current environment (like Secrets!)
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
namespace WorldOfZero.DotNetEvaluator.Controllers;
[ApiController]
[Route("evaluator/csharp")]
public class EvaluatorController : ControllerBase
{
private readonly ILogger<EvaluatorController> _logger;
public EvaluatorController(ILogger<EvaluatorController> logger)
{
_logger = logger;
}
[HttpPost(Name = "EvaluateCsharp")]
public async Task<object> Post([FromBody]string[] code)
{
var resultsSet = new List<dynamic>();
var builder = new StringBuilder();
ScriptState state = null;
Script script = null;
// Execute line by line and save the results after each line to assist with debugging later
foreach (var line in code)
{
if (script == null || state == null)
{
script = CSharpScript.Create(line);
state = await script.RunAsync();
}
else
{
state = await state.ContinueWithAsync(line);
}
Console.WriteLine(line);
builder.AppendLine(line);
var scriptCode = builder.ToString();
var variables = state.Variables.Select(v => new { name = v.Name, value = v.Value }).ToArray();
resultsSet.Add(new
{
Script = scriptCode,
Result = state.ReturnValue,
Variables = variables,
Exception = state.Exception
});
}
var hash = Convert.ToString(script.GetHashCode(), 16) + Convert.ToString(DateTime.Now.GetHashCode(), 16);
return new
{
Logs = $"https://localhost:7272/logs/{hash}", // todo runewake2: this doesn't go anywhere yet and is just a placeholder - fix that.
Trace = resultsSet,
Result = state?.ReturnValue
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment