Skip to main content

Sensitive information sent via URL parameters - Session

Need

Secure transmission of sensitive information in session tokens

Context

  • Usage of C# for developing robust and efficient software applications
  • Usage of Microsoft.AspNetCore.Mvc for building web applications using the ASP.NET Core MVC framework
  • Usage of System.IdentityModel.Tokens.Jwt for JWT (JSON Web Token) authentication and authorization

Description

Non compliant code

[HttpGet]
public IActionResult Login(string returnUrl = "/")
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, "User")
};

var jwt = new JwtSecurityToken(claims: claims);
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

// Redirecting the user to the returnUrl with the JWT token as a URL parameter
return Redirect($"{returnUrl}?token={encodedJwt}");
}

In the above code, an HTTP GET request is made to the Login method. This method creates a JWT token with some claims, encodes it, and then redirects the user to the returnUrl with the JWT token as a URL parameter.

The vulnerability here is that the JWT token, which is sensitive information, is sent via URL parameters. This is a security risk because URLs are logged in various places such as browser history, web server logs, and network appliances. This exposes the JWT token to potential attackers who could gain unauthorized access to the system.

Moreover, if the URL is shared or bookmarked, the JWT token would also be shared which could lead to unauthorized access. Additionally, URLs can also be leaked via the Referer header when navigating to other sites or in the browser history.

In this case, the JWT token represents a session, which is a very sensitive piece of information that should be protected. If an attacker gets hold of this token, they could impersonate the user and perform actions on their behalf. This is why it is not recommended to send sensitive information via URL parameters.

Steps

  • Do not include sensitive information, such as session tokens, in the URL parameters.
  • Use secure methods to transmit sensitive information, such as using HTTP headers or request bodies.
  • Consider using secure session management techniques, such as using server-side sessions or encrypted cookies.
  • Implement proper access controls to prevent unauthorized access to sensitive information.
  • Regularly review and update the application's security measures to address any potential vulnerabilities.

Compliant code

[HttpGet]
public IActionResult Login(string returnUrl = "/")
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, "User")
};

var jwt = new JwtSecurityToken(claims: claims);
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

// Store the JWT token in a secure HttpOnly cookie
Response.Cookies.Append("jwt", encodedJwt, new CookieOptions { HttpOnly = true, Secure = true });

// Redirecting the user to the returnUrl without the JWT token as a URL parameter
return Redirect(returnUrl);
}

The original code was vulnerable because it was sending the JWT session token as a URL parameter. This is a security risk because URLs can be logged in various places such as browser history, web server logs, and network appliances, making it possible for an attacker to steal the session token.

The fixed code no longer sends the JWT session token as a URL parameter. Instead, it stores the JWT session token in a secure HttpOnly cookie. This is a more secure method of transmitting sensitive information because it prevents the session token from being accessed by client-side scripts, reducing the risk of cross-site scripting (XSS) attacks. The Secure flag is also set to true to ensure the cookie is only sent over HTTPS, preventing the session token from being intercepted during transmission.

In addition to these changes, it's important to implement proper access controls to prevent unauthorized access to sensitive information and regularly review and update the application's security measures to address any potential vulnerabilities.

References