Mass Assignment in Aspnet with Dynamodb
Mass Assignment in Aspnet with Dynamodb — how this specific combination creates or exposes the vulnerability
Mass assignment in an ASP.NET application that uses Amazon DynamoDB as the persistence layer occurs when user-supplied input is directly bound to data model properties and then written to DynamoDB without explicit property filtering. In this context, the risk is not a DynamoDB injection issue, but an over-permissive model binding path that allows an attacker to set fields they should not control, such as administrative flags, tenant identifiers, or versioning attributes.
Consider an ASP.NET Core controller that accepts JSON to create or update an item stored in a DynamoDB table. If the action method uses a broad model-binding approach like FromBody on a class that maps directly to a DynamoDB document, an attacker can include additional properties in the request (for example, IsAdmin, AccountId, or CreatedBy). Because the DynamoDB mapper typically serializes the object into an attribute-value map, these unexpected properties are persisted, effectively changing privilege or ownership semantics.
For example, an attacker might send a PATCH or POST request with a payload that includes sensitive fields, relying on the default model binder to populate them. If the service layer writes the object to DynamoDB using a low-level PutItem or UpdateItem request that includes all properties from the bound model, the unauthorized fields are stored. This can lead to privilege escalation (e.g., turning a regular user into an admin) or data isolation violations (e.g., writing to another tenant’s partition key).
DynamoDB does not enforce schema-level restrictions on attributes beyond the primary key structure, which means once an unexpected attribute arrives in the attribute-value map, it is stored as-is. Therefore, the vulnerability surface is defined by the ASP.NET model-binding rules and the application’s mapping logic, not by DynamoDB itself. The framework’s behavior of binding arbitrary JSON keys to public settable properties enables this path, and the DynamoDB client trusts the resulting object graph, making the mass assignment impactful at the persistence layer.
In threat modeling terms, this maps to the OWASP API Top 10 category BOLA (Broken Object Level Authorization) when combined with insufficient authorization checks. An authenticated user can manipulate object properties across boundaries, and because the API might not validate whether the authenticated subject is allowed to set a given field, the control plane protections are bypassed.
Dynamodb-Specific Remediation in Aspnet — concrete code fixes
To remediate mass assignment in an ASP.NET application using DynamoDB, you must enforce strict input filtering, use explicit DTOs (Data Transfer Objects), and avoid binding user input directly to persistence models. Below are concrete code examples that demonstrate secure patterns.
1. Use explicit DTOs and selective mapping
Define a dedicated DTO for incoming requests that includes only the fields you intend to accept. Then map the DTO to your DynamoDB entity model explicitly, ignoring any extra properties.
// DTO for incoming requests
public class ItemUpdateDto
{
public string Name { get; set; }
public string Description { get; set; }
// Do not include IsAdmin, AccountId, or other sensitive fields here
}
// DynamoDB data model
public class Item
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool IsAdmin { get; set; }
public string AccountId { get; set; }
}
// Mapping and update logic using Amazon.DynamoDBv2
public async Task UpdateItemAsync(string id, ItemUpdateDto dto)
{
var request = new UpdateItemRequest
{
TableName = "Items",
Key = new Dictionary<string, AttributeValue>
{
{ "Id", new AttributeValue { S = id } }
},
UpdateExpression = "SET #name = :name, #desc = :desc",
ExpressionAttributeNames = new Dictionary<string, string>
{
{ "#name", "Name" },
{ "#desc", "Description" }
},
ExpressionAttributeValues = new Dictionary<string, AttributeValue>
{
{ ":name", new AttributeValue { S = dto.Name } },
{ ":desc", new AttributeValue { S = dto.Description } }
}
};
await _dynamoDbClient.UpdateItemAsync(request);
}
2. Use [JsonIgnore] or contract resolver to prevent over-posting
If you choose to bind directly to an entity model, decorate sensitive properties with [System.Text.Json.Serialization.JsonIgnore] or use a custom contract resolver to ensure they are never populated from incoming JSON.
public class Item
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
[System.Text.Json.Serialization.JsonIgnore]
public bool IsAdmin { get; set; }
[System.Text.Json.Serialization.JsonIgnore]
public string AccountId { get; set; }
}
3. Validate and authorize field-level changes
Even when using DTOs, implement explicit checks that the authenticated subject is allowed to modify specific fields, particularly sensitive ones. Combine this with DynamoDB condition expressions to enforce server-side safety.
var request = new UpdateItemRequest
{
TableName = "Items",
Key = new Dictionary<string, AttributeValue> { { "Id", new AttributeValue { S = id } } },
UpdateExpression = "SET #status = :status",
ConditionExpression = "attribute_exists(Id) AND ( :allowed = :true)",
ExpressionAttributeNames = new Dictionary<string, string> { { "#status", "Status" } },
ExpressionAttributeValues = new Dictionary<string, AttributeValue>
{
{ ":status", new AttributeValue { S = "Approved" } },
{ ":allowed", new AttributeValue { BOOL = UserCanModifyStatus } },
{ ":true", new AttributeValue { BOOL = true } }
}
};
By combining strict DTOs, explicit mapping, and condition expressions, you ensure that mass assignment cannot alter sensitive attributes, regardless of the content sent by the client.
Related CWEs: propertyAuthorization
| CWE ID | Name | Severity |
|---|---|---|
| CWE-915 | Mass Assignment | HIGH |