Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
23703bf
feat: Implement native anti-tampering guard
JVBotelho Feb 2, 2026
d2bab33
feat: Add performance benchmarks with BenchmarkDotNet
JVBotelho Feb 2, 2026
ecd05dc
docs: Add comprehensive threat model and attack scenarios
JVBotelho Feb 2, 2026
a4d7ec3
docs: Update README with project overview, security, and performance …
JVBotelho Feb 2, 2026
1ef302d
docs: Add attack flow diagram to README
JVBotelho Feb 2, 2026
24929cf
chore: Update repository URL and roadmap in README
JVBotelho Feb 2, 2026
ff57a5f
feat(security): Introduce SqlInjectionDetectionEngine Core & Dependen…
JVBotelho Feb 2, 2026
550297a
refactor(redteam): Overhaul gRPC exploit script into attack suite
JVBotelho Feb 2, 2026
04ea11e
feat(security): Implement advanced native anti-tamper mechanisms
JVBotelho Feb 2, 2026
7728106
docs: Update README and add Reverse Engineering documentation
JVBotelho Feb 2, 2026
7758611
docs: Add Architectural Decision Records and Product Roadmap
JVBotelho Feb 4, 2026
5b206d3
feat(sql): Refine core SQL normalization and heuristic detection
JVBotelho Feb 4, 2026
52b3a9c
feat(sql): Update SqlInjectionDetectionEngine API and add unit tests
JVBotelho Feb 4, 2026
68f94d5
perf(grpc): Optimize gRPC interceptor for zero-allocation protobuf fi…
JVBotelho Feb 4, 2026
08e11ec
feat: Introduce NuGet package locking for reproducible builds
JVBotelho Feb 4, 2026
6516777
style: Apply consistent formatting and whitespace adjustments
JVBotelho Feb 4, 2026
a7dc437
feat: Add Directory.Build.props for consistent project settings
JVBotelho Feb 4, 2026
fa61775
refactor: Configure Rasp.Benchmarks project
JVBotelho Feb 4, 2026
77bb527
refactor: Make NativeGuard injectable and improve logging
JVBotelho Feb 4, 2026
311e7ed
perf: Adopt LoggerMessage for SqlInjectionDetectionEngine
JVBotelho Feb 4, 2026
2bac0b8
chore: Update Microsoft.Extensions.* dependencies to 10.0.1
JVBotelho Feb 4, 2026
5d5dbe7
refactor: Rename Core DependencyInjection to RaspCoreExtensions
JVBotelho Feb 4, 2026
1a4ae21
style: Add ConfigureAwait(false) and ArgumentNullException checks
JVBotelho Feb 4, 2026
2314b82
fix: Suppress CA2000 warning in RaspMetrics
JVBotelho Feb 4, 2026
0691794
build: Relax warnings as errors in CI and add InternalsVisibleTo
JVBotelho Feb 4, 2026
74dea65
feat(tests): Add Dependency Injection sanity tests for RASP Bootstrapper
JVBotelho Feb 4, 2026
7db75c6
build: Exclude 'modules' from dotnet format in CI
JVBotelho Feb 4, 2026
71bd1b5
refactor: Apply whitespace and formatting fixes
JVBotelho Feb 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
run: dotnet restore ${{ env.SOLUTION_NAME }}

- name: Build (Release)
run: dotnet build ${{ env.SOLUTION_NAME }} --configuration Release --no-restore /p:TreatWarningsAsErrors=true
run: dotnet build ${{ env.SOLUTION_NAME }} --configuration Release --no-restore

- name: Run Tests
run: dotnet test ${{ env.SOLUTION_NAME }} --configuration Release --no-build --verbosity normal --logger "trx;LogFileName=test-results-${{ matrix.os }}.trx"
Expand Down Expand Up @@ -90,7 +90,7 @@ jobs:

# 2. Code Formatting (Enforce Style)
- name: Verify Formatting
run: dotnet format ${{ env.SOLUTION_NAME }} --verify-no-changes --verbosity diagnostic
run: dotnet format ${{ env.SOLUTION_NAME }} --verify-no-changes --verbosity diagnostic --exclude ./modules

# 3. CodeQL Analysis
- name: Initialize CodeQL
Expand Down
97 changes: 91 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,61 @@
![Architecture](https://img.shields.io/badge/Architecture-Composite-blue?style=for-the-badge)
![Build](https://img.shields.io/github/actions/workflow/status/JVBotelho/RASP.Net/build.yml?style=for-the-badge)
![Coverage](https://img.shields.io/codecov/c/github/JVBotelho/RASP.Net?style=for-the-badge)
[![Threat Model](https://img.shields.io/badge/📄_Threat_Model-Read-orange?style=for-the-badge)](docs/ATTACK_SCENARIOS.md)
[![Reverse Engineering](https://img.shields.io/badge/🕵️_Anti--Debug-Research-blueviolet?style=for-the-badge)](docs/REVERSE_ENGINEERING.md)
> **Runtime Application Self-Protection (RASP) for High-Scale .NET Services**
> *Defense that lives inside your application process, operating at the speed of code.*

> **Runtime Application Self-Protection (RASP) SDK for .NET 10.**
> *Active defense residing inside the application process.*
---

## 🎮 Why This Matters for Gaming Security

**The Problem**: Multiplayer game services process **millions of transactions per second**. Traditional WAFs introduce network latency and cannot see inside the encrypted gRPC payload or understanding game logic context.

**The Solution**: RASP.Net acts as a **last line of defense** inside the game server process. It instruments the runtime to detect attacks that bypass perimeter defenses, detecting logic flaws like item duplication exploits or economy manipulation.

**Key Engineering Goals:**
1. **Zero GC Pressure**: Security checks must NOT trigger Garbage Collection pauses that cause frame drops/lag.
2. **Sub-Microsecond Latency**: Checks happen in nanoseconds, not milliseconds.
3. **Defense in Depth**: Complements kernel-level Anti-Cheat (BattlEye/EAC) by protecting the backend API layer.

---

## ⚡ Performance Benchmarks

**Methodology:** Benchmarks isolate the intrinsic cost of the `SqlInjectionDetectionEngine` using `BenchmarkDotNet`.
**Hardware:** AMD Ryzen 7 7800X3D (4.2GHz) | **Runtime:** .NET 10.0.2

| Payload Size | Scenario | Mean Latency | Allocation | Verdict |
| :--- | :--- | :--- | :--- | :--- |
| **100 Bytes** | ✅ Safe Scan (Hot Path) | **4.3 ns** | **0 Bytes** | **Zero-Alloc** 🚀 |
| | 🛡️ Attack Detected | **202.0 ns** | 232 Bytes | Blocked |
| **1 KB** | ✅ Safe Scan (Hot Path) | **16.4 ns** | **0 Bytes** | **Zero-Alloc** 🚀 |
| | 🛡️ Attack Detected | **1,036 ns** | 232 Bytes | Blocked |
| **10 KB** | ✅ Safe Scan (Hot Path) | **141.0 ns** | **0 Bytes** | **Zero-Alloc** 🚀 |
| | ⚠️ Deep Inspection | **5,871 ns** | 0 Bytes | Suspicious |

> **Key Takeaway:**
> * **Hot Path Optimization:** For 99% of legitimate traffic (Safe Scan), the engine uses vectorized SIMD checks (`SearchValues<T>`), incurring negligible overhead (**~4ns**).
> * **Zero Allocation:** The inspection pipeline uses `stackalloc` and `Span<T>` buffers, ensuring **0 GC Pressure** during routine checks.
> * **Deep Inspection:** Only when suspicious characters (e.g., `'`, `--`) are detected does the engine perform full normalization, costing a few microseconds but protecting the app.

---

## 🛡️ Security Analysis & Threat Modeling

This repository contains professional-grade security documentation demonstrating **Purple Team** capabilities.

### 📄 [Threat Model & Attack Scenarios](docs/ATTACK_SCENARIOS.md)
A comprehensive STRIDE analysis of the Game Economy architecture.
- **Vectors**: gRPC SQL Injection, Protobuf Tampering, GC Pressure DoS.
- **Validation**: Python exploit walkthroughs and mitigation strategies.

### 🕵️ [Reverse Engineering & Anti-Tamper](docs/REVERSE_ENGINEERING.md)
A deep dive into the Native C++ Protection Layer.
- **Internals**: Analysis of `IsDebuggerPresent`, PEB manipulation, and timing checks.
- **Bypasses**: Documentation of known evasion techniques (ScyllaHide, Detours) to demonstrate adversarial thinking.
- **Roadmap**: Advanced heuristics (RDTSC/SEH) for Phase 2.

---

Expand All @@ -29,6 +81,39 @@ It is designed to develop and validate the Security SDK (`Rasp.*`) by instrument

---

## 🛡️ How It Works (Attack Flow)

```mermaid
sequenceDiagram
participant Attacker
participant gRPC as gRPC Gateway
participant RASP as 🛡️ RASP.Net
participant GameAPI as Game Service
participant DB as Database

Note over Attacker,RASP: 🔴 Attack Scenario: Item Duplication
Attacker->>gRPC: POST /inventory/add {item: "Sword' OR 1=1"}
gRPC->>RASP: Intercept Request

activate RASP
RASP->>RASP: ⚡ Zero-Alloc Inspection
RASP-->>Attacker: ❌ 403 Forbidden (Threat Detected)
deactivate RASP

Note over Attacker,DB: 🟢 Legitimate Scenario
Attacker->>gRPC: POST /inventory/add {item: "Legendary Sword"}
gRPC->>RASP: Intercept Request

activate RASP
RASP->>GameAPI: ✅ Clean - Forward Request
deactivate RASP

GameAPI->>DB: INSERT INTO inventory...
DB-->>GameAPI: Success
GameAPI-->>Attacker: 200 OK
```
---

## 🚀 Setup & Build

⚠️ **CRITICAL:** This repository relies on submodules. A standard clone will result in missing projects.
Expand All @@ -37,7 +122,7 @@ It is designed to develop and validate the Security SDK (`Rasp.*`) by instrument

Use the `--recursive` flag to fetch the Target Application code:
```bash
git clone --recursive https://github.com/YOUR_USERNAME/RASP.Net.git
git clone --recursive https://github.com/JVBotelho/RASP.Net.git
```

If you have already cloned without the flag:
Expand Down Expand Up @@ -94,9 +179,9 @@ The Composite Solution allows you to debug the SDK as if it were part of the app

## 🎯 Roadmap

- [ ] **Phase 1**: Setup & Vulnerability injection in Target App
- [ ] **Phase 2**: gRPC Interceptor with payload inspection
- [ ] **Phase 3**: EF Core Interceptor with SQL analysis
- [x] **Phase 1**: Setup & Vulnerability injection in Target App
- [x] **Phase 2**: gRPC Interceptor with payload inspection
- [ ] **Phase 3**: EF Core Interceptor with SQL analysis 🚧 **IN PROGRESS**
- [ ] **Phase 4**: Benchmarks & Documentation

---
Expand Down
48 changes: 48 additions & 0 deletions Rasp.Core.Tests/DependencyInjection/DiSanityTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using FluentAssertions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Rasp.Bootstrapper;

namespace Rasp.Core.Tests.DependencyInjection;

/// <summary>
/// Verifies the integrity of the Dependency Injection (DI) container configuration.
/// Ensures that all services and their dependencies are correctly registered and compatible.
/// </summary>
public class DiSanityTests
{
/// <summary>
/// Ensures that <see cref="RaspDependencyInjection.AddRasp"/> registers all required services
/// without missing dependencies or causing scope violations.
/// </summary>
[Fact]
public void AddRasp_Should_Register_All_Dependencies_Correctly()
{
// 1. Arrange
var services = new ServiceCollection();

var config = new ConfigurationBuilder().Build();

services.AddSingleton<IConfiguration>(config);
services.AddLogging();

services.AddGrpc();

// 2. Act
services.AddRasp(opt =>
{
opt.BlockOnDetection = true;
opt.EnableMetrics = false;
});

var options = new ServiceProviderOptions
{
ValidateOnBuild = true,
ValidateScopes = true
};

Action build = () => services.BuildServiceProvider(options);

build.Should().NotThrow("the RASP dependency graph must be complete and valid");
}
}
23 changes: 23 additions & 0 deletions Rasp.Core.Tests/Engine/Sql/SqlNormalizerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Rasp.Core.Engine.Sql;

namespace Rasp.Core.Tests.Engine.Sql;

public class SqlNormalizerTests
{
[Fact]
public void Normalize_WithSmallBuffer_ShouldTruncateAndNotThrow()
{
// Arrange
const string input = "SELECT * FROM Users WHERE id = 1"; // Length 32
Span<char> smallBuffer = stackalloc char[10]; // Only 10 chars capacity

// Act
// This should strictly fill only 10 chars and return 10, no IndexOutOfRangeException
int written = SqlNormalizer.Normalize(input, smallBuffer);
string result = smallBuffer[..written].ToString();

// Assert
Assert.Equal(10, written);
Assert.Equal("select * f", result); // Truncated result
}
}
43 changes: 43 additions & 0 deletions Rasp.Core.Tests/Engine/SqlInjectionDetectionEngineTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Microsoft.Extensions.Logging.Abstractions;
using Rasp.Core.Engine;
using Rasp.Core.Models;

namespace Rasp.Core.Tests;

public class SqlInjectionDetectionEngineTests
{
private readonly SqlInjectionDetectionEngine _sut; // System Under Test

public SqlInjectionDetectionEngineTests()
{
_sut = new SqlInjectionDetectionEngine(NullLogger<SqlInjectionDetectionEngine>.Instance);
}

[Theory]
[InlineData("O'Reilly")]
[InlineData("D'Angelo")]
[InlineData("L'oreal")]
[InlineData("McDonald's")]
[InlineData("Grand'Mère")]
public void Inspect_ShouldNotFlag_LegitimateNamesWithApostrophes(string safeInput)
{
// Act
var result = _sut.Inspect(safeInput);

// Assert
Assert.False(result.IsThreat, $"Falso positivo detectado! O nome legítimo '{safeInput}' foi bloqueado.");
}

[Theory]
[InlineData("admin' OR '1'='1")]
[InlineData("user' UNION SELECT")]
[InlineData("name'; DROP TABLE users --")]
public void Inspect_ShouldFlag_AttacksWithQuotes(string attackInput)
{
// Act
var result = _sut.Inspect(attackInput);

// Assert
Assert.True(result.IsThreat, $"Falso negativo! O ataque '{attackInput}' passou despercebido.");
}
}
3 changes: 3 additions & 0 deletions Rasp.Core.Tests/Rasp.Core.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4"/>
<PackageReference Include="FluentAssertions" Version="8.8.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
<PackageReference Include="xunit" Version="2.9.3"/>
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4"/>
Expand All @@ -19,6 +21,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\src\Rasp.Bootstrapper\Rasp.Bootstrapper.csproj" />
<ProjectReference Include="..\src\Rasp.Core\Rasp.Core.csproj" />
</ItemGroup>

Expand Down
Loading
Loading