Server Side Template Injection in Aspnet with Bearer Tokens
Server Side Template Injection in Aspnet with Bearer Tokens — how this specific combination creates or exposes the vulnerability
Server Side Template Injection (SSTI) in ASP.NET occurs when an attacker can inject template code that is later evaluated by a server-side templating engine such as Razor or StringTemplate. When bearer tokens are used for API authentication, the token value itself can become a source of risk if it is reflected into a template context without proper validation or encoding. For example, if an endpoint accepts a token via a query parameter or header and includes it directly in a Razor view or a dynamically constructed string that is parsed as a template, an attacker can craft a token containing template syntax to execute arbitrary code on the server.
Consider an ASP.NET Core controller that logs or renders the bearer token for debugging purposes:
@{
var token = Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
}
<div>Token: @token</div>
If the token contains Razor syntax such as @{throw new Exception("pwned")}, and the view or downstream processing engine evaluates it, the server may execute the injected code. This is a classic SSTI pattern. The presence of bearer tokens amplifies the impact because tokens often carry scope or impersonation context; an injected template can potentially access sensitive data or invoke backend services using the token’s privileges. Additionally, if the token is stored in a database or log and later rendered in a template without sanitization, stored SSTI can persist across sessions. The vulnerability is not in bearer tokens per se, but in the unsafe handling of token values within template evaluation contexts.
In the context of middleBrick’s checks, this scenario maps to the BOLA/IDOR and Input Validation categories, where reflected or stored data is improperly handled. The scanner tests whether token-like inputs can alter template behavior, and reports findings aligned with OWASP API Top 10 and related compliance frameworks.
Bearer Tokens-Specific Remediation in Aspnet — concrete code fixes
To remediate SSTI risks when bearer tokens are involved, ensure token values are never interpreted as executable template content. Treat bearer tokens as opaque strings and avoid inserting them directly into Razor or other server-side template contexts. If you must display or log a token, treat it as plain text and encode or escape it appropriately.
Secure logging and display in Razor
Instead of outputting the token as Razor code, encode it using Html.Encode or display it within a plain HTML element:
@{
var authHeader = Request.Headers["Authorization"].ToString();
var token = authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)
? authHeader.Substring("Bearer ".Length)
: string.Empty;
}
<div>Token: @System.Net.WebUtility.HtmlEncode(token)</div>
Avoid token usage in dynamic template construction
If your application builds templates or commands using token values, switch to parameterized approaches. For example, do not concatenate tokens into SQL or script templates. Use prepared statements or strongly typed models instead:
// Unsafe: string command = $"echo {token}";
// Safe: use parameters or avoid token interpolation entirely
var message = $"Token length: {token.Length}";
API endpoint design
Design endpoints to avoid returning or processing bearer tokens in template-evaluated contexts. If you need to confirm token validity, validate it against your authentication provider without reflecting it back as executable content:
[HttpGet("validate")]
public IActionResult Validate([FromHeader] string authorization)
{
if (string.IsNullOrWhiteSpace(authorization) || !authorization.StartsWith("Bearer "))
{
return Unauthorized();
}
var token = authorization.Substring("Bearer ".Length);
// Perform validation using your auth provider, do not render token
var isValid = ValidateWithAuthProvider(token);
return Ok(new { IsValid = isValid });
}
Input validation and encoding
Apply strict input validation to all incoming data, including headers and query parameters. Use model binding with validation attributes and encode any user-controlled data before rendering:
public class TokenRequest
{
[RegularExpression("^[^\x00-\x1F\x7F<>]+$", ErrorMessage = "Invalid token format")]
public string Token { get; set; }
}