Fix code injection in C# and ASP.NET Core
=========================================

Do not run request input as code. Roslyn's CSharpScript executes the formula
with the server's privileges, and a denylist of dangerous APIs cannot make it
safe: it misses Environment.GetEnvironmentVariable and is never complete.
Parse the small grammar the feature needs (numbers, the allowlisted fields and
the operators) and evaluate that, so there is no type or member to reach.

Page: https://softwaresecurity.com/fix/code-injection/csharp-aspnetcore/

What is in this archive
-----------------------
code-injection/csharp-aspnetcore/   the project: three implementations of the same code and one test suite
  src/Rules/impl/VulnerableFormulaEvaluator.cs   (vulnerable)
  src/Rules/impl/FixedFormulaEvaluator.cs   (fixed)
  src/Rules/impl/WrongFormulaEvaluator.cs   (a plausible fix that still fails)
run-all.mjs   runs the tests in all three modes and checks the results (Node.js only)
LICENSE-CODE.txt

Run it
------
  Tested with ASP.NET Core 10 minimal API on .NET 10.0.12. run-all.mjs needs
  Node.js 22 or later. Supported versions:
  https://softwaresecurity.com/fix/versions/

  From the code-injection/csharp-aspnetcore folder, install the dependencies
  once (this needs network access):

    dotnet restore tests/Rules.Tests --locked-mode

  Then run the tests. IMPL chooses the implementation the tests load:

    # every test passes
    FIXCARD_SECRET=730199138246 IMPL=fixed dotnet test --project tests/Rules.Tests --no-restore --results-directory reports --report-xunit-junit --report-xunit-junit-filename junit.xml
    # an exploit test fails
    FIXCARD_SECRET=730199138246 IMPL=vulnerable dotnet test --project tests/Rules.Tests --no-restore --results-directory reports --report-xunit-junit --report-xunit-junit-filename junit.xml
    # a test fails
    FIXCARD_SECRET=730199138246 IMPL=wrong dotnet test --project tests/Rules.Tests --no-restore --results-directory reports --report-xunit-junit --report-xunit-junit-filename junit.xml

  The JUnit report is written to reports/junit.xml. To run all three modes and
  check the results in one step, run the harness from this top folder (it needs
  only Node.js; --install runs the install step first):

    node run-all.mjs --install code-injection/csharp-aspnetcore
    node run-all.mjs code-injection/csharp-aspnetcore

Verified
--------
  11 October 2026 on macOS 27.0 (Darwin 27.0.0, arm64), with dotnetSdk 10.0.112,
  aspNetCoreRuntime 10.0.12, roslynScripting 5.6.0, xunitV3 4.0.2. Versions and
  results hold for that date: run the tests with your own versions before
  relying on the fix.

Licence
-------
  The code is MIT licensed (LICENSE-CODE.txt). The page text is CC BY 4.0.
