Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AWSSDK.DynamoDBv2 does not detect self-references in PutItem request #3722

Open
1 task
OleksandrKrutykh opened this issue Mar 25, 2025 · 2 comments
Open
1 task
Labels
bug This issue is a bug. dynamodb p3 This is a minor priority issue queued s Effort estimation: small

Comments

@OleksandrKrutykh
Copy link

Describe the bug

If the item passed into Amazon.DynamoDBv2.AmazonDynamoDBClient.PutItemAsync method contains an AttributeValue with a self-reference, the method call results in a StackOverflowException. Since this exception cannot be caught, I assume it will crash whatever runtime environment the code is running in.

Regression Issue

  • Select this option if this issue appears to be a regression.

Expected Behavior

The call results in AmazonDynamoDBException or one of its inheritors.

Current Behavior

A StackOverflowException is thrown. Please, see the stack trace in ExceptionStack.txt attached. Note that the stack trace has been shortened for readability, because it contained a lot of identical AttributeValueMarshaller.Marshall calls.

ExceptionStack.txt

Reproduction Steps

Assuming that we have a DynamoDB table with a numeric hash key attribute called Id:

using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;

using var dynamoDbClient = new AmazonDynamoDBClient();

// An attribute value with a self-reference
var badItem = new Dictionary<string, AttributeValue>();
badItem["C"] = new AttributeValue { M = badItem };

var request = new PutItemRequest
{
    TableName = "<Table name here>",
    Item = new Dictionary<string, AttributeValue>
    {
        ["Id"] = new AttributeValue { N = "1" },
        ["Data"] = new AttributeValue { M = badItem }
    }
};

await dynamoDbClient.PutItemAsync(request);

Possible Solution

No response

Additional Information/Context

No response

AWS .NET SDK and/or Package version used

AWSSDK.DynamoDBv2 3.7.406.7

Targeted .NET Platform

.NET 8

Operating System and version

Windows 11

@OleksandrKrutykh OleksandrKrutykh added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Mar 25, 2025
@ashishdhingra ashishdhingra self-assigned this Mar 25, 2025
@ashishdhingra ashishdhingra added needs-reproduction This issue needs reproduction. dynamodb p2 This is a standard priority issue and removed needs-triage This issue or PR still needs to be triaged. labels Mar 25, 2025
@ashishdhingra
Copy link
Contributor

@OleksandrKrutykh Good afternoon. Thanks for opening the issue. The issue is reproducible with the below stack trace:

>	AWSSDK.Core.dll!ThirdParty.Json.LitJson.JsonWriter.Put(string str) Line 200	C#
 	AWSSDK.Core.dll!ThirdParty.Json.LitJson.JsonWriter.PutString(string str) Line 225	C#
 	AWSSDK.Core.dll!ThirdParty.Json.LitJson.JsonWriter.WritePropertyName(string property_name) Line 515	C#
 	AWSSDK.DynamoDBv2.dll!Amazon.DynamoDBv2.Model.Internal.MarshallTransformations.AttributeValueMarshaller.Marshall(Amazon.DynamoDBv2.Model.AttributeValue requestObject, Amazon.Runtime.Internal.Transform.JsonMarshallerContext context) Line 92	C#
 	AWSSDK.DynamoDBv2.dll!Amazon.DynamoDBv2.Model.Internal.MarshallTransformations.AttributeValueMarshaller.Marshall(Amazon.DynamoDBv2.Model.AttributeValue requestObject, Amazon.Runtime.Internal.Transform.JsonMarshallerContext context) Line 102	C#
 	[The 1 frame(s) above this were repeated 1570 times]	
 	AWSSDK.DynamoDBv2.dll!Amazon.DynamoDBv2.Model.Internal.MarshallTransformations.AttributeValueMarshaller.Marshall(Amazon.DynamoDBv2.Model.AttributeValue requestObject, Amazon.Runtime.Internal.Transform.JsonMarshallerContext context) Line 102	C#
 	AWSSDK.DynamoDBv2.dll!Amazon.DynamoDBv2.Model.Internal.MarshallTransformations.PutItemRequestMarshaller.Marshall(Amazon.DynamoDBv2.Model.PutItemRequest publicRequest) Line 148	C#
 	AWSSDK.DynamoDBv2.dll!Amazon.DynamoDBv2.Model.Internal.MarshallTransformations.PutItemRequestMarshaller.Marshall(Amazon.Runtime.AmazonWebServiceRequest input) Line 48	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.Marshaller.PreInvoke(Amazon.Runtime.IExecutionContext executionContext) Line 93	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.Marshaller.InvokeAsync<Amazon.DynamoDBv2.Model.PutItemResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 55	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.DynamoDBv2.Model.PutItemResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.CallbackHandler.InvokeAsync<Amazon.DynamoDBv2.Model.PutItemResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 61	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.DynamoDBv2.Model.PutItemResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync<Amazon.DynamoDBv2.Model.PutItemResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 53	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.DynamoDBv2.Model.PutItemResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.MetricsHandler.InvokeAsync<Amazon.DynamoDBv2.Model.PutItemResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 94	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.RuntimePipeline.InvokeAsync<Amazon.DynamoDBv2.Model.PutItemResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 152	C#
 	AWSSDK.Core.dll!Amazon.Runtime.AmazonServiceClient.InvokeAsync<Amazon.DynamoDBv2.Model.PutItemResponse>(Amazon.Runtime.AmazonWebServiceRequest request, Amazon.Runtime.Internal.InvokeOptionsBase options, System.Threading.CancellationToken cancellationToken) Line 278	C#
 	AWSSDK.DynamoDBv2.dll!Amazon.DynamoDBv2.AmazonDynamoDBClient.PutItemAsync(Amazon.DynamoDBv2.Model.PutItemRequest request, System.Threading.CancellationToken cancellationToken) Line 4978	C#

This is due to the infinite self-referential chain. I'm unsure on the scenario which represents data model which refers to itself, causing the above issue. Perhaps, such data models should be revisited if it is determined that these would cause such infinite self-referencing chain.

Also, how is it expected to represent such a chain in DynamoDB table. It might be thoughtful to have logic in place to break the chain in case of such infinite loop and store the item. But it would have issues during deserialization process to back from DynamoDB table. Should we throw an exception for such scenario? Perhaps yes. Needs review with the team.

@ashishdhingra ashishdhingra added needs-review p3 This is a minor priority issue and removed needs-reproduction This issue needs reproduction. p2 This is a standard priority issue labels Mar 26, 2025
@OleksandrKrutykh
Copy link
Author

Hello @ashishdhingra. A PutItemRequest with self-references is definitely an example of bad data. An attempt to convert the data model from the example in Reproduction Steps to DynamoDB JSON would result in a piece of JSON of infinite depth, like this:

{
  "Id": { "N": "1" }
  "Data": {
    "M": {
      "C": {
        "M": {
          "C": {

A piece of code that creates such a data model certainly has a bug and needs to be fixed. Because of that, I don't think it would make sense to try convert the data model to a piece of valid DynamoDB JSON by breaking the infinite loop somewhere, because it would only hide the bug in the calling code. From my perspective, it would be OK for the AWS SDK to throw an exception when called with such a data model. What is important is that this exception should not be a StackOverflowException, but some exception that can be caught by a try .. catch block.

I did not stumble upon this issue because I had a piece of logic that produced a data model with self-references. I was just implementing a piece of business logic that had to recursively go through a data model before saving it to a DynamoDB. I added a guardrail to my code to prevent it from going into an infinite loop if the data model contained self-references and decided to check (out of curiosity) how the AWS SDK reacts to self-references.

@ashishdhingra ashishdhingra added queued s Effort estimation: small and removed needs-review labels Mar 27, 2025
@ashishdhingra ashishdhingra removed their assignment Mar 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. dynamodb p3 This is a minor priority issue queued s Effort estimation: small
Projects
None yet
Development

No branches or pull requests

2 participants