This Lambda function is designed for EventBridge-triggered malware workflows. It reads S3 object details from the event, replaces the infected file with empty content, deletes object tags, and sends an SNS notification for audit and incident response.
Environment Variables
SNS_REGION– AWS region for SNS clientSNS_TOPIC_ARN– SNS topic for incident notifications
Lambda Handler (Python)
import boto3
import logging
import json
import os
s3_client = boto3.client('s3')
sns_region = os.environ.get('SNS_REGION')
if not sns_region:
raise ValueError("Environment variable 'SNS_REGION' is not set")
sns_client = boto3.client('sns', region_name=sns_region)
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# Retrieve sns topic arn from env
sns_topic_arn = os.environ.get('SNS_TOPIC_ARN')
if not sns_topic_arn:
raise ValueError("Environment variable 'SNS_TOPIC_ARN' is not set")
def lambda_handler(event, context):
logger.info("Received event: %s", event)
try:
# Extract info from event
s3_details = event.get("detail", {}).get("s3ObjectDetails", {})
bucket_names = s3_details.get("bucketName", [])
object_keys = s3_details.get("objectKey", [])
if not bucket_names or not object_keys:
raise ValueError("Bucket name or object key not found in the event.")
bucket_name = bucket_names[0] if isinstance(bucket_names, list) else bucket_names
object_key = object_keys[0] if isinstance(object_keys, list) else object_keys
logger.info("Processing object '%s' in bucket '%s'", object_key, bucket_name)
scan_result = event.get("detail", {}).get("scanResultDetails", {})
scan_status = scan_result.get("scanResultStatus", "UNKNOWN")
# Replace the object
put_response = s3_client.put_object(
Bucket=bucket_name,
Key=object_key,
Body=b''
)
logger.info("Replaced object with empty file. Response: %s", put_response)
# Delete all tags from the object
tag_response = s3_client.delete_object_tagging(
Bucket=bucket_name,
Key=object_key
)
logger.info("Deleted object tags. Response: %s", tag_response)
# Prepare sns message
message = (
f"Topic: Malware File Replaced\n"
f"S3 Bucket: {bucket_name}\n"
f"File: {object_key}\n"
f"Scan Status: {scan_status}\n"
f"Timestamp: {event.get('time', 'N/A')}\n"
f"Event ID: {event.get('id', 'N/A')}\n"
f"Action Taken: File replaced with empty content and tags removed"
)
# Publish to sns using the correct variable name
sns_response = sns_client.publish(
TopicArn=sns_topic_arn,
Message=message,
Subject=f"Malware Detected and Replaced: {object_key}",
MessageAttributes={
'Severity': {
'DataType': 'String',
'StringValue': 'HIGH'
}
}
)
logger.info("SNS notification sent. Response: %s", sns_response)
return {
'statusCode': 200,
'body': f"Object '{object_key}' in bucket '{bucket_name}' replaced with an empty file, tags removed, and notification sent."
}
except Exception as e:
logger.error("Error processing object: %s", e, exc_info=True)
return {
'statusCode': 500,
'body': f"Error processing object: {str(e)}"
}
Sample EventBridge Input
{
"detail": {
"s3ObjectDetails": {
"bucketName": ["my-malware-bucket"],
"objectKey": ["uploads/suspicious-file.bin"]
},
"scanResultDetails": {
"scanResultStatus": "THREATS_FOUND"
}
},
"id": "event-id-123",
"time": "2026-05-28T10:00:00Z"
}
Operational Notes
- Ensure this action is approved for your malware workflow because it overwrites object content.
- Enable object versioning if rollback is required after automated replacement.
- Audit SNS notifications and CloudWatch logs for incident traceability.
Official Documentation
- AWS Lambda Developer Guide: https://docs.aws.amazon.com/lambda/latest/dg/welcome.html
- Amazon EventBridge User Guide: https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html
- Amazon S3 delete_object_tagging: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3/client/delete_object_tagging.html
- Amazon SNS publish: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sns/client/publish.html
