Secure File Upload to Amazon S3 with Lambda Virus Scanning

March 13, 2026

Serverless File Upload Architecture on AWS

Instead of allowing users to upload directly to your production S3 bucket, use a controlled flow.

Architecture Overview

  • User → Pre-Signed URL → Incoming S3 Bucket → Lambda Scan
    • If Clean → Move to Clean Bucket
    • If Infected → Move to Quarantine Bucket → Notify via SNS

This approach is called the Incoming / Clean / Quarantine Pattern.

Architecture diagram showing a secure serverless file upload workflow on AWS where users upload files to an incoming Amazon S3 bucket, AWS Lambda scans files for viruses, clean files move to a secure S3 bucket, infected files move to a quarantine bucket, and Amazon SNS sends notifications.
Figure: Secure Serverless File Upload Architecture on AWS

Step 1: Upload Files Securely Using Pre-Signed URLs

Users should never upload files through your backend server. Instead, generate a pre-signed URL that allows temporary direct upload to an isolated S3 bucket.

Pre-signed URLs in Amazon S3 provide time-limited access with controlled permissions. This results in reduced server load and no backend file handling.

Example – Generate Pre-Signed URL (Node.js)

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"

const s3 = new S3Client({ region: "us-east-1" })

export async function generateUploadUrl(userId, fileName) {
  const command = new PutObjectCommand({
    Bucket: "incoming-upload-bucket",
    Key: `uploads/${userId}/${fileName}`,
    ContentType: "application/pdf"
  })

  return await getSignedUrl(s3, command, { expiresIn: 600 })
}


Important security measures:

  • Enable Block Public Access
  • Enforce file size limits
  • Validate MIME type
  • Restrict upload to incoming bucket only

Never allow uploads directly into your clean or production bucket.

Step 2: Scan Files in Amazon S3 Using AWS Lambda

Once a file lands in your incoming bucket in Amazon S3, it can automatically trigger a Lambda function through an event notification. This keeps the workflow fully serverless and event-driven.

The Lambda function typically downloads the file into temporary storage, performs a malware scan, evaluates the result, and then moves the file to the appropriate destination. If the file is safe, it is transferred to a clean bucket. If it is infected, it is moved into quarantine. Finally, the function publishes a notification so the system and administrators know what happened.

Because everything is triggered by events, there are no background servers running continuously. The system reacts only when uploads occur, which keeps it efficient and cost-effective.

How to Scan Files for Viruses in S3

There are three common approaches to S3 virus scanning.

Option 1: ClamAV in AWS Lambda (Most Popular Serverless Method)

ClamAV is an open-source antivirus engine. You can package it as a Lambda layer and run scans inside the function.

Basic example:

import { execSync } from "child_process"

function scanFile(filePath) {
  const result = execSync(`clamscan ${filePath}`).toString()
  return result.includes("OK")
}


This approach is commonly used by SaaS startups and applications that deal with moderate file sizes (typically under 100MB). It works well in fully serverless architectures and is a cost-effective option because it does not rely on external APIs.

One advantage of this method is that everything runs inside your AWS environment, which keeps the workflow event-driven and reduces infrastructure overhead. However, there are some limitations to consider. Lambda cold starts can introduce slight latency, virus definitions must be updated periodically, and very large files may exceed Lambda limits.

Option 2: Container-Based Malware Scanning (Enterprise Scale)

For larger files or high-volume workloads, scanning can be offloaded to container-based services such as Amazon ECS or Amazon EKS.

This approach removes Lambda execution limits and allows the system to process much larger files and higher traffic volumes. It is often used in enterprise environments, particularly in financial or healthcare systems where files may exceed 500MB and compliance requirements are strict.

Option 3: Third-Party Malware Scanning API

Some enterprises choose to integrate with external security scanning providers through APIs. In this setup, the Lambda function sends the uploaded file or its contents to a third-party scanning service and waits for the response.

Example:

import axios from "axios"

async function scanWithAPI(fileBuffer) {
  const response = await axios.post("https://scanner-api.com/scan", fileBuffer)
  return response.data.status === "clean"
}


This model is commonly used in FinTech, HealthTech, and enterprise SaaS applications where strong malware detection and managed security updates are required. The trade-off is cost, as third-party services typically charge per scan or per volume processed.

Step 3: Clean and Quarantine Buckets

After the scanning process completes, the system decides where the file should go next.

If the file is clean, it is copied to the clean bucket, tagged with metadata such as scan-status=clean, and removed from the incoming bucket. If the file is infected, it is moved to the quarantine bucket and tagged with scan-status=infected. A security notification is then triggered so administrators are aware of the event.

Only the clean bucket should be connected to your production application. This separation enforces a zero-trust storage model where unverified files never interact with production systems.

Step 4: Notify Users or Admins Using SNS

Once the scanning process finishes, the system publishes a message using Amazon SNS to notify relevant systems or users about the result.

Example:

await sns.publish({
  TopicArn: process.env.TOPIC_ARN,
  Message: JSON.stringify({
    file: key,
    status: isClean ? "CLEAN" : "INFECTED"
  })
})


SNS can send email alerts, trigger additional Lambda functions, notify Slack channels, or push events into monitoring dashboards. This improves observability and creates an audit trail for security and compliance purposes.

Additional Security Best Practices for File Uploads

Malware scanning alone is not sufficient to fully secure a file upload pipeline. Additional validation layers should be implemented to ensure files are legitimate and safe to process.

These protections include verifying file extensions, validating MIME types, checking file signatures using magic bytes, enforcing strict file size limits, and applying strong IAM policies to control access. S3 object tagging, lifecycle rules, and versioning should also be enabled to support auditing and automated cleanup.

Example – Magic byte validation for PDF:

const isPDF = buffer.slice(0, 4).toString() === "%PDF"

Never trust file extensions alone.

How to Scale This Serverless File Upload Architecture

If upload traffic grows significantly, it can be helpful to introduce buffering into the event flow.

A common scalable architecture is: S3 → EventBridge → SQS → Lambda

This pattern allows retry handling, dead-letter queues, controlled concurrency, and backpressure protection. Instead of overwhelming Lambda during traffic spikes, events are queued and processed gradually, making the system more resilient and production-ready.

Cost Optimization Tips

To reduce AWS costs, several best practices can be applied. Lifecycle rules can automatically delete old quarantined files, preventing unnecessary storage expenses. Lambda memory should be optimized according to the workload, and unnecessary data transfers should be avoided.

Compressing files before scanning can reduce storage and transfer costs, and S3 Intelligent-Tiering may help optimize storage costs for files that are accessed infrequently. Since serverless infrastructure scales automatically with usage, you only pay for the resources actually consumed.

Final Architecture Recommendation

For most SaaS builders:

Amazon S3 + AWS Lambda + ClamAV + Amazon SNS

For high-scale enterprise systems:

S3 + SQS + ECS + Security API integration

Start simple. Scale when needed.

Conclusion

Building a secure file upload system on AWS is critical for modern SaaS applications.

By combining Amazon S3 for storage, AWS Lambda for malware scanning, and Amazon SNS for notification, you can create a fully serverless, scalable, and secure file upload pipeline.

This architecture ensures:

  • Only clean files enter production
  • Infected files are isolated
  • Users are notified
  • Compliance risk is reduced
  • Infrastructure remains serverless

Secure file upload design is responsible engineering.

References

Amazon S3 Documentation

https://docs.aws.amazon.com/s3/

AWS Lambda Documentation

https://docs.aws.amazon.com/lambda/

Amazon SNS Documentation

https://docs.aws.amazon.com/sns/

AWS Blog – Scan S3 Objects for Malware

https://aws.amazon.com/blogs/security/how-to-scan-amazon-s3-objects-for-malware/

ClamAV Official Site

https://www.clamav.net/

Serverless Handbook
Access free book

The dream team

At Serverless Guru, we're a collective of proactive solution finders. We prioritize genuineness, forward-thinking vision, and above all, we commit to diligently serving our members each and every day.

See open positions

Looking for skilled architects & developers?

Join businesses around the globe that trust our services. Let's start your serverless journey. Get in touch today!
Ryan Jones
Founder
Book a meeting
arrow
Founder
Eduardo Marcos
Chief Technology Officer
Chief Technology Officer
Book a meeting
arrow

Join the Community

Gather, share, and learn about AWS and serverless with enthusiasts worldwide in our open and free community.