HIGH mass assignmentazure

Mass Assignment on Azure

How Mass Assignment Manifests in Azure

Mass assignment vulnerabilities in Azure applications typically emerge through model binding and serialization mechanisms that automatically map HTTP request data to C# objects. In Azure Functions, ASP.NET Core Web APIs, and Azure App Service applications, developers often rely on framework features that bind request payloads directly to data models without explicit property whitelisting.

The most common pattern occurs when Azure developers use [FromBody] or [FromForm] attributes in controller actions. Consider this Azure Function that processes user profile updates:

[HttpTrigger(AuthorizationLevel.Anonymous, "put", Route = "users/{id}")]
public static async Task<User> UpdateUser(
    [FromBody] UserUpdateModel model, 
    string id, 
    ILogger log, 
    ExecutionContext context)
{
    var user = await _userRepository.GetById(id);
    user.UpdateFromModel(model); // Mass assignment vulnerability
    await _userRepository.Save(user);
    return user;
}

The vulnerability appears in the UpdateFromModel method, which might look like this:

public void UpdateFromModel(UserUpdateModel model)
{
    // Dangerous: copies ALL properties without validation
    FirstName = model.FirstName;
    LastName = model.LastName;
    Email = model.Email;
    Role = model.Role; // Admin role can be escalated
    IsActive = model.IsActive;
    LastLogin = model.LastLogin; // Timestamp manipulation
}

In Azure environments, this becomes particularly dangerous because many applications use Azure Active Directory for authentication and authorization. An attacker could exploit mass assignment to escalate privileges by setting the Role property to "Admin" or modify audit trails by manipulating LastLogin timestamps.

Azure Storage integration introduces another attack vector. When using Azure Table Storage or Cosmos DB with automatic serialization, developers might bind request data directly to entity models:

public class UserEntity : TableEntity
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Role { get; set; }
    public bool IsActive { get; set; }
    public DateTime LastLogin { get; set; }
}

[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "users")]
public static async Task<IActionResult> CreateUser(
    [FromBody] UserEntity user,
    [Table("Users")] CloudTable table)
{
    await table.ExecuteAsync(TableOperation.Insert(user));
    return new OkObjectResult(user);
}

Here, an attacker can submit any properties they want, including PartitionKey or RowKey, potentially overwriting existing records or accessing other users' data.

Azure Logic Apps and Azure Functions with Durable Entities present unique mass assignment risks. Durable Entities use stateful objects that persist across function invocations:

[FunctionName("UserEntity")]
public static Task<UserState> UserEntityOperation([
    EntityTrigger] IDurableEntityContext context)
{
    return context.DispatchAsync<UserState>();
}

[JsonObject(MemberSerialization.OptIn)]
public class UserState
{
    [JsonProperty("firstName")]
    public string FirstName { get; set; }
    
    [JsonProperty("lastName")]
    public string LastName { get; set; }
    
    [JsonProperty("role")]
    public string Role { get; set; }
}

The DispatchAsync method automatically maps JSON properties to object properties, creating a mass assignment vulnerability where attackers can modify any exposed property without validation.

Azure-Specific Detection

Detecting mass assignment vulnerabilities in Azure applications requires both static code analysis and dynamic runtime testing. middleBrick's Azure-specific scanning identifies these issues through several techniques.

Static analysis in middleBrick examines C# source code for common mass assignment patterns in Azure Functions and Web APIs. The scanner looks for:

// Patterns that trigger alerts:
[FromBody] T model // Generic binding without validation
[FromForm] T model // Form data binding
context.DispatchAsync() // Durable Entities mass assignment
JsonSerializer.Deserialize() // Unvalidated deserialization

// Dangerous method patterns:
public void UpdateFromModel(T model) // No property filtering
public void ApplyChanges(T changes) // Blind property copying

Dynamic scanning tests Azure endpoints by submitting crafted payloads that attempt to modify sensitive properties. For a User model, middleBrick sends requests with additional fields like "Role=admin", "IsActive=false", or "LastLogin=2020-01-01" and observes whether the server accepts these modifications.

middleBrick's Azure-specific checks include:

Check TypeAzure-Specific PatternDetection Method
Model Binding[FromBody] User modelPayload injection testing
Durable Entitiescontext.DispatchAsync<User>()State manipulation attempts
Table StorageCloudTable.ExecuteAsyncPartitionKey/RowKey injection
Cosmos DBContainer.CreateItemAsyncProperty escalation testing

For Azure Logic Apps, middleBrick analyzes workflow definitions (JSON) to identify operations that bind external inputs to internal models without validation. The scanner flags patterns like:

// Logic App workflow analysis:
{
  "type": "ApiConnection",
  "inputs": {
    "body": {
      "@triggerBody()" // Direct binding without filtering
    }
  }
}

middleBrick also tests Azure API Management APIs by examining backend configurations and policy definitions. It identifies cases where API Management policies automatically transform or bind request data to backend services without proper validation.

The scanner generates Azure-specific findings with severity levels based on the sensitivity of properties that can be manipulated. Modifying a "Role" property receives a higher severity than modifying a "DisplayName" property. Each finding includes the exact code location and recommended remediation steps.

Azure-Specific Remediation

Remediating mass assignment vulnerabilities in Azure applications requires a defense-in-depth approach using Azure's native security features and C# best practices. The most effective strategy combines explicit property whitelisting with Azure's built-in validation mechanisms.

For Azure Functions and Web APIs, implement explicit model binding with property filtering:

public class UserUpdateModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    
    // Exclude sensitive properties from binding
    [BindNever]
    public string Role { get; set; }
    
    [BindNever]
    public bool IsActive { get; set; }
    
    [BindNever]
    public DateTime LastLogin { get; set; }
}

[HttpTrigger(AuthorizationLevel.Anonymous, "put", Route = "users/{id}")]
public static async Task<User> UpdateUser(
    [FromBody] UserUpdateModel model, 
    string id, 
    ILogger log)
{
    var user = await _userRepository.GetById(id);
    
    // Explicit property assignment with validation
    user.FirstName = SanitizeInput(model.FirstName);
    user.LastName = SanitizeInput(model.LastName);
    user.Email = ValidateEmail(model.Email);
    
    // Sensitive properties remain unchanged
    await _userRepository.Save(user);
    return user;
}

private static string SanitizeInput(string input)
{
    return WebUtility.HtmlEncode(input?.Trim());
}

private static string ValidateEmail(string email)
{
    if (!Regex.IsMatch(email, @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"))
        throw new ArgumentException("Invalid email format");
    return email;
}

For Azure Durable Entities, implement explicit state management instead of relying on automatic dispatch:

[FunctionName("UserEntity")]
public static Task<UserState> UserEntityOperation([
    EntityTrigger] IDurableEntityContext context)
{
    switch (context.OperationName)
    {
        case "UpdateProfile":
            var update = context.GetInput<UserUpdateModel>();
            return UpdateProfile(context, update);
            
        default:
            throw new InvalidOperationException($"Unknown operation: {context.OperationName}");
    }
}

private static Task<UserState> UpdateProfile(
    IDurableEntityContext context, 
    UserUpdateModel update)
{
    var state = context.GetState<UserState>();
    
    // Explicit property assignment with validation
    state.FirstName = SanitizeInput(update.FirstName);
    state.LastName = SanitizeInput(update.LastName);
    state.Email = ValidateEmail(update.Email);
    
    context.SetState(state);
    return Task.FromResult(state);
}

For Azure Table Storage and Cosmos DB operations, use strongly-typed entities with explicit property mapping:

public class UserEntity : TableEntity
{
    public UserEntity() { }
    
    public UserEntity(string userId)
    {
        PartitionKey = "Users";
        RowKey = userId;
    }
    
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    
    // Sensitive properties not exposed in entity
    [IgnoreProperty]
    public string Role { get; set; }
    
    [IgnoreProperty]
    public bool IsActive { get; set; }
}

[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "users")]
public static async Task<IActionResult> CreateUser(
    [FromBody] UserCreateRequest request,
    [Table("Users")] CloudTable table)
{
    var user = new UserEntity(request.UserId)
    {
        FirstName = SanitizeInput(request.FirstName),
        LastName = SanitizeInput(request.LastName),
        Email = ValidateEmail(request.Email)
    };
    
    await table.ExecuteAsync(TableOperation.Insert(user));
    return new OkObjectResult(user);
}

Azure API Management policies can add an additional layer of protection by validating and filtering request bodies before they reach backend services:

<policies>
    <validate-content 
        contentType="application/json" 
        schema="@/schemes/user-update.json" />
    <set-backend-service 
        base-url="https://your-backend.azurewebsites.net" />
</policies>

The schema file (user-update.json) defines exactly which properties are allowed, preventing mass assignment at the API Management layer.

Related CWEs: propertyAuthorization

CWE IDNameSeverity
CWE-915Mass Assignment HIGH

Frequently Asked Questions

How does middleBrick detect mass assignment vulnerabilities in Azure Functions?
middleBrick analyzes Azure Functions source code for dangerous patterns like [FromBody] binding without validation, context.DispatchAsync calls, and automatic deserialization. It then tests endpoints by sending crafted payloads with sensitive properties (Role, IsActive, timestamps) to verify if the server accepts unauthorized modifications. The scanner provides exact code locations and severity ratings based on which properties can be manipulated.
Can mass assignment vulnerabilities in Azure Table Storage be exploited to access other users' data?
Yes, if an Azure Table Storage application binds request data directly to TableEntity objects without validation, attackers can manipulate PartitionKey or RowKey properties to access or modify other users' records. middleBrick tests for this by attempting to set these properties to values belonging to other users and verifies if the backend accepts the unauthorized access attempt.