Shellshock in Aspnet
How Shellshock Manifests in Aspnet
Shellshock is a critical vulnerability in Bash that allows remote code execution through specially crafted environment variables. In Aspnet applications, this manifests through several attack vectors that developers often overlook.
The most common Aspnet-specific scenario involves improper handling of HTTP headers that get passed to system processes. When an Aspnet application uses Process.Start() or similar APIs to execute shell commands, malicious headers can exploit the vulnerability:
// VULNERABLE Aspnet code
var process = new Process {
StartInfo = new ProcessStartInfo {
FileName = "/bin/bash",
Arguments = "-c 'echo vulnerable'",
UseShellExecute = false
}
};
process.Start();Attackers craft headers like Referer: () { :;}; /bin/bash -c 'cat /etc/passwd'. When Aspnet passes this header to a subprocess, Bash executes the malicious payload.
Aspnet Web API controllers are particularly susceptible when they log request data or pass headers to external services:
public class ShellController : ControllerBase
{
[HttpGet("api/echo")]
public IActionResult Echo([FromQuery] string data)
{
// DANGEROUS: data flows to shell without validation
var result = ExecuteShellCommand(data);
return Ok(result);
}
private string ExecuteShellCommand(string command)
{
var process = new Process {
StartInfo = new ProcessStartInfo {
FileName = "/bin/bash",
Arguments = $"-c '{command}'",
UseShellExecute = false
}
};
process.Start();
return "Executed";
}
}Another Aspnet-specific pattern involves middleware that executes shell commands for logging or monitoring:
public class RequestLoggingMiddleware
{
private readonly RequestDelegate _next;
public async Task InvokeAsync(HttpContext context)
{
// VULNERABLE: user input flows to shell
var command = $"log_request '{context.Request.Headers["User-Agent"]}'";
var process = new Process {
StartInfo = new ProcessStartInfo {
FileName = "/bin/bash",
Arguments = $"-c '{command}'",
UseShellExecute = false
}
};
process.Start();
await _next(context);
}
}Containerized Aspnet applications on Linux hosts are especially at risk since they often execute shell commands for deployment scripts, health checks, or configuration management.
Aspnet-Specific Detection
Detecting Shellshock in Aspnet applications requires both static analysis and runtime scanning. middleBrick's API security scanner specifically tests for this vulnerability by sending crafted payloads to your endpoints.
The scanner tests Aspnet endpoints with these patterns:
# middleBrick sends these test payloads
Referer: () { :;}; /bin/echo 'shellshock_test'
User-Agent: () { :;}; /bin/echo 'shellshock_test'
Cookie: () { :;}; /bin/echo 'shellshock_test'For Aspnet applications, middleBrick analyzes the HTTP pipeline to identify dangerous patterns:
- Process.Start() calls with user-controlled input
- System.Diagnostics.Process usage in controllers
- Shell command execution in middleware
- Environment variable manipulation from HTTP headers
- Unsafe string interpolation in command arguments
middleBrick's Aspnet-specific detection includes:
// middleBrick identifies these vulnerable patterns
if (source.Contains("ProcessStartInfo") &&
source.Contains("Arguments") &&
source.Contains("UseShellExecute = false"))
{
// HIGH RISK: potential Shellshock vector
}The scanner also tests for CVE-2014-6271 and related variants by sending multiple payload variations and monitoring for command execution indicators.
For CI/CD integration, the middleBrick GitHub Action can automatically scan your Aspnet APIs before deployment:
- name: Scan API Security
uses: middlebrick/middlebrick-action@v1
with:
url: https://your-aspnet-api.com
fail-on-severity: high
token: ${{ secrets.MIDDLEBRICK_TOKEN }}Aspnet-Specific Remediation
Remediating Shellshock in Aspnet requires eliminating shell command execution with user input. The most effective approach is using Aspnet's native libraries instead of shell commands.
For file operations, replace shell commands with System.IO:
// INSECURE - vulnerable to Shellshock
var process = new Process {
StartInfo = new ProcessStartInfo {
FileName = "/bin/bash",
Arguments = $"-c 'cat {path}'",
UseShellExecute = false
}
};
process.Start();
// SECURE - use Aspnet-native APIs
var content = System.IO.File.ReadAllText(path);
return content;For process execution, use Aspnet's Process class safely or avoid it entirely:
// SECURE pattern - validate and sanitize
public IActionResult SafeExecute([FromQuery] string command)
{
if (!IsValidCommand(command))
return BadRequest("Invalid command");
// Use Process without shell interpretation
var process = new Process {
StartInfo = new ProcessStartInfo {
FileName = "/usr/bin/env",
Arguments = command,
UseShellExecute = false,
RedirectStandardOutput = true
}
};
process.Start();
var output = process.StandardOutput.ReadToEnd();
return Ok(output);
}
private bool IsValidCommand(string command)
{
// Allow only specific commands
var allowedCommands = new[] { "ls", "pwd", "whoami" };
return allowedCommands.Contains(command.Split(' ')[0]);
}For Aspnet middleware, implement proper input validation:
public class SecureRequestLoggingMiddleware
{
private readonly RequestDelegate _next;
public async Task InvokeAsync(HttpContext context)
{
var userAgent = context.Request.Headers["User-Agent"];
// Validate input before any processing
if (!IsSafeHeader(userAgent))
{
context.Response.StatusCode = 400;
return;
}
// Log securely without shell commands
var logger = context.RequestServices.GetService<ILogger<SecureRequestLoggingMiddleware>>();
logger.LogInformation("Request from {UserAgent}", userAgent);
await _next(context);
}
private bool IsSafeHeader(string header)
{
// Block Shellshock patterns
var shellshockPatterns = new[] {
")()",
"{",
";",
"() {"
};
return !shellshockPatterns.Any(header.Contains);
}
}For Aspnet Core applications, use the built-in validation features:
public class ShellshockController : ControllerBase
{
[HttpGet("api/safe")]
public IActionResult SafeOperation([FromQuery] string data)
{
// Model validation prevents malicious input
if (!ModelState.IsValid)
return BadRequest(ModelState);
// Process data without shell execution
var result = ProcessDataSafely(data);
return Ok(result);
}
}