Skip to content

Create rule S7613 #5143

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

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions rules/S7613/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
24 changes: 24 additions & 0 deletions rules/S7613/python/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"title": "AWS Lambda handlers should return only JSON serializable values",
"type": "BUG",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
],
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-7613",
"sqKey": "S7613",
"scope": "All",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "infeasible",
"code": {
"impacts": {
"MAINTAINABILITY": "LOW",
"RELIABILITY": "HIGH"
},
"attribute": "CONVENTIONAL"
}
}
124 changes: 124 additions & 0 deletions rules/S7613/python/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
This rule raises an issue when AWS Lambda handlers return values that are not JSON serializable.

== Why is this an issue?

For synchronous AWS Lambda invocations, like via API Gateway or direct SDK calls, the value returned by the handler is automatically serialized into a JSON string before being sent back in the response. If the return value contains objects that are not native JSON types like `datetime` objects, sets, or custom class instances, the serialization will fail, causing a `TypeError`. This will prevent the Lambda from returning a valid response to the client.

== How to fix it

Convert non-JSON-serializable objects to their string representation or to native JSON types before returning them:

* For `datetime` objects: Convert to ISO format strings using `.isoformat()`
* For sets: Convert to lists using `list(set_object)`
* For custom objects: convert them to dictionaries using the `++__dict__++` field, `dataclasses.asdict(...)` for dataclasses or a custom `todict()` method.

For more control over serialization, return a string instead and handle the serialization logic yourself.

Here are examples of serializing a custom class using different methods:

[source,python]
----
import json
import dataclasses

# A custom class representing a user
@dataclasses.dataclass
class User:
name: str
age: int

def to_dict(self) -> dict:
return { "name": self.name, "age": self.age }

user = User("Alice", 30)

# Method 1: Using __dict__ field
json.dumps(user.__dict__)

# Method 2: Using dataclasses.asdict()
json.dumps(dataclasses.asdict(user))

# Method 3: Using custom to_dict() method
json.dumps(user.to_dict())
----

=== Code examples

==== Noncompliant code example

[source,python,diff-id=1,diff-type=noncompliant]
----
import datetime

def lambda_handler(event, context):
return {
"message": "Request processed successfully",
"timestamp": datetime.datetime.now() # Noncompliant: not JSON serializable
}
----

==== Compliant solution

[source,python,diff-id=1,diff-type=compliant]
----
import datetime

def lambda_handler(event, context):
return {
"message": "Request processed successfully",
"timestamp": datetime.datetime.now().isoformat() # Compliant: converted to string
}
----


== Resources

=== Documentation

* AWS Documentation - https://docs.aws.amazon.com/lambda/latest/dg/python-handler.html#python-handler-return[Define Lambda function handler in Python
]
* Python Documentation - https://docs.python.org/3/library/json.html[json — JSON encoder and decoder]
* Python Documentation - https://docs.python.org/3/reference/datamodel.html#object.__dict__[object.++__dict__++ field]
* Python Documentation - https://docs.python.org/3/library/datetime.html#datetime.date.isoformat[datetime.date.isoformat()]
* Python Documentation - https://docs.python.org/3/library/dataclasses.html#dataclasses.asdict[dateclasses.asdict()]

ifdef::env-github,rspecator-view[]
== Implementation Specification
visible only on this page

The implementation should check for these common non-serializable types:
* `datetime.datetime`, `datetime.date`, `datetime.time`
* `set`, `frozenset`
* `bytes`, `bytearray`
* `complex` numbers
* Custom class instances without proper serialization methods
* `decimal.Decimal` objects
* File objects
* Functions and methods
* Module objects
* `re.Pattern` objects

Since business logic and the handler should be separated, it is possible that the lambda handler as the last statement class a function and returns its result. If this is detect, it might be worth also checking the return type of the function.

Furthermore, it is common that the lambda handler has early returns which return a different JSON in case an error occurs. In this case, the rule should also check the return type of the handler in all branches.

[source,python]
----
def process_event(event):
if not event.get("valid"):
return {"error": "Invalid event"}

result = {"status": "success", "data": event["data"]}
return result

def lambda_handler(event, context):
return process_event(event)
----

=== Message
Lambda handler returns a value that is not JSON serializable.

=== Highlighting
The non-serializable value or object in the return statement.

endif::env-github,rspecator-view[]