Pii Leakage in Aspnet
How Pii Leakage Manifests in Aspnet
PII leakage in ASP.NET applications typically occurs through several Asp-specific patterns. One common scenario involves ModelState errors in API controllers where exception details expose sensitive user data. Consider this vulnerable pattern:
public async Task<ActionResult> UpdateProfile([FromBody] UserProfileModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// Process update...
return Ok();
}
When ModelState contains validation errors, the default JSON serialization exposes the raw input values, including PII like email addresses, phone numbers, or social security numbers that failed validation. An attacker can trigger these error responses to harvest data.
Another Asp-specific vulnerability appears in exception handling. The default developer exception page in ASP.NET Core can expose stack traces with PII:
app.UseExceptionHandler("/error");
app.UseStatusCodePages();
In production, this might return detailed exception information including database queries containing PII, connection strings, or user identifiers.
ASP.NET Web Forms applications face different PII leakage patterns through view state. The ViewStateUserKey property, when not properly implemented, can expose user-specific data:
protected void Page_Init(object sender, EventArgs e)
{
// Vulnerable: missing user-specific key
// ViewState can be manipulated across users
}
Session state misconfiguration also leads to PII exposure. Using InProc session mode without proper isolation can cause data from one authenticated user to be accessible to another:
protected void Application_Start()
{
// Vulnerable: default session configuration
SessionStateSection sessionState =
ConfigurationManager.GetSection("system.web/sessionState") as SessionStateSection;
}
ASP.NET Core's DataAnnotations can inadvertently expose PII through validation error messages. Custom attributes that include raw data in error messages create leakage paths:
public class CustomEmailAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string email = value as string;
if (string.IsNullOrWhiteSpace(email))
{
// Vulnerable: includes raw email in error message
return new ValidationResult($"Invalid email: {email}");
}
return ValidationResult.Success;
}
}
ASP.NET-Specific Detection
Detecting PII leakage in ASP.NET applications requires both manual code review and automated scanning. For manual detection, search for these Asp-specific patterns:
ModelState exposure: Look for controller actions returning BadRequest(ModelState) or similar patterns that serialize validation state directly to clients.
Exception handling: Check for unhandled exceptions in async methods that might bubble up to middleware, and verify custom error pages don't expose stack traces.
View state configuration: In Web Forms, verify ViewStateUserKey is set to a user-specific value like HttpContext.Current.User.Identity.Name.
Session configuration: Review session state mode and ensure proper isolation between users.
DataAnnotations usage: Audit custom validation attributes for error messages containing raw user input.
For automated detection, middleBrick's ASP.NET-specific scanning identifies these patterns across your API endpoints. The scanner tests unauthenticated endpoints for PII exposure by submitting crafted payloads and analyzing responses for sensitive data patterns including:
- Email addresses, phone numbers, and social security numbers in error responses
- Stack traces containing database queries with PII
- Session identifiers that could be manipulated
- Validation error messages exposing raw input
middleBrick's scanning process for ASP.NET applications takes 5-15 seconds and requires no credentials or configuration. Simply provide your API endpoint URL:
npx middlebrick scan https://yourapi.com/api/users
The scanner tests 12 security categories including PII leakage, returning a risk score (0-100) with letter grades and prioritized findings. For ASP.NET applications, it specifically checks for Asp-specific vulnerability patterns and maps findings to OWASP API Top 10 categories.
middleBrick also analyzes OpenAPI/Swagger specifications for ASP.NET Web API projects, cross-referencing spec definitions with runtime findings to identify discrepancies where PII might be exposed through undocumented endpoints or parameter handling.
ASP.NET-Specific Remediation
Remediating PII leakage in ASP.NET requires leveraging the framework's native features for secure data handling. Here are Asp-specific fixes:
Secure ModelState handling: Instead of returning ModelState directly, create sanitized error responses:
public async Task<ActionResult> UpdateProfile([FromBody] UserProfileModel model)
{
if (!ModelState.IsValid)
{
var errors = ModelState.Values.SelectMany(v => v.Errors)
.Select(e => e.ErrorMessage ?? e.Exception?.Message)
.ToList();
return BadRequest(new {
error = "Validation failed",
details = errors
});
}
return Ok();
}
Proper exception handling: Configure ASP.NET Core to return generic error responses in production:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
context.Response.StatusCode = 500;
await context.Response.WriteAsync("An error occurred. Please try again.");
});
});
}
}
Secure View State: In ASP.NET Web Forms, implement proper user isolation:
protected void Page_Init(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
ViewStateUserKey = User.Identity.Name;
}
else
{
ViewStateUserKey = Session.SessionID;
}
}
Session state configuration: Use StateServer or SQLServer mode for better isolation:
<system.web>
<sessionState mode="StateServer"
stateConnectionString="tcpip=127.0.0.1:42424"
cookieless="false"
timeout="20" />
</system.web>
Secure DataAnnotations: Create validation attributes that don't expose raw data:
public class SafeEmailAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string email = value as string;
if (string.IsNullOrWhiteSpace(email))
{
return new ValidationResult("Email is required");
}
if (!IsValidEmailFormat(email))
{
return new ValidationResult("Invalid email format");
}
return ValidationResult.Success;
}
}
Input sanitization: Use ASP.NET Core's built-in model binding protections:
public class UserProfileModel
{
[PersonalData] // Marks as PII for framework handling
[EmailAddress(ErrorMessage = "Invalid email address format")]
public string Email { get; set; }
[Phone(ErrorMessage = "Invalid phone number format")]
public string PhoneNumber { get; set; }
[StringLength(11, MinimumLength = 11, ErrorMessage = "SSN must be 11 characters")]
[RegularExpression(@"^\d{3}-\d{2}-\d{4}$", ErrorMessage = "Invalid SSN format")]
public string SocialSecurityNumber { get; set; }
}
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |