...
We are aware of the recently disclosed PHP2Shell vulnerabilities (CVE-2026-109618 and CVE-2026-109619) and can confirm Filestack is not impacted by these vulnerabilities.

You Can Vibe Code a File Uploader, but Should You?

An AI assistant writes a working uploader in one prompt. Keeping it safe, fast and running in production takes services that no prompt can run.

AI assistant
You
Build me a file uploader that saves to S3.
AI
Done. Here's a server that signs upload URLs and a browser script that sends the file.
server.mjs upload.js
Left to do 6 open items
  • Resume a 2 GB upload after the signal drops
  • Google Drive approval and a yearly assessment
  • Login checks, size limits and safe file types
  • Malware scanning before anyone opens a file
  • A CDN, thumbnails and document previews
  • Runtime, SDK and provider API upgrades
Trusted by
SendGrid logo with stylized gray text and overlapping square shapes on the left.
LinkedIn logo followed by the word SlideShare in gray text on a light background.
The word teachable is written in all lowercase, sans-serif letters with a colon between teach and able, in a light purple color on a light background.
A gray Airtable logo featuring a geometric cube design to the left of the word Airtable in bold, modern font.
Executive summary

The Prompt Writes the Upload. Production Needs the Rest.

Ask an AI assistant for a file uploader and a first prompt can return as little as one request and one bucket. It works, and for a prototype it’s enough. This page uses that short version for brevity. A detailed prompt or an agent session can build a full framework project.

A production upload system is a set of services around that one request: an ingestion network, OAuth apps with certifications behind them, a policy engine, a malware scanner, a CDN, a document converter and an audited control environment. A prompt can draft code for most of them. It can’t pass a certification, run the infrastructure, or keep any of it working once the runtime, the SDK or a provider’s API changes.

Six gaps separate a vibe-coded uploader from a production one: large uploads, cloud sources, security, malware, delivery and upkeep. Each chapter below shows what closing the gap yourself takes, then how Filestack closes it.

56%
Average security pass rate of AI-generated code, with no security-specific prompting.
Veracode, 20261
15%
Pass rate for cross-site scripting, the flaw behind a script hidden in an uploaded file.
Veracode, 20261
5GB
The largest file one PUT to S3 accepts. Bigger files need multipart upload code.
AWS S3 docs4
18 MB
The most our SDK sends again when a 2 GB upload drops at 90%. One PUT sends all 2,048 MB again.
filestack-js defaults12
import express from "express";import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";import { getSignedUrl } from "@aws-sdk/s3-request-presigner";import crypto from "node:crypto"; const app = express();const s3 = new S3Client({ region: "us-east-1" }); app.get("/upload-url", async (req, res) => {  const key = `uploads/${crypto.randomUUID()}-${req.query.name}`;  const command = new PutObjectCommand({    Bucket: "my-app-uploads",    Key: key,    ContentType: req.query.type,  });  const url = await getSignedUrl(s3, command, { expiresIn: 300 });  res.json({ url, key });}); app.listen(3000);
This one works

What One Prompt Gives You

Ask Claude, ChatGPT or Cursor for a file uploader and a first prompt can come back with something like this: a server that signs an S3 upload URL, and a browser script that sends the file to it. Point it at a bucket and files land in S3.

The example is simplified for brevity. It is a reference point, not the most an AI can write. Keep prompting and the code gets a lot better.

Ask for More and You Get More

An agent working in a framework will split the uploader across many files, validate input, handle errors, upload in parts and write tests. All of it is code in your repository, running on servers you pay for.

One prompt

Two files
  • A presigned S3 upload URL
  • One PUT from the browser

A detailed prompt

Several files
  • Input validation and a login check
  • Error handling and retries
  • Upload in parts for large files

An agent session

A full framework project
  • Routes, services and config in Next.js or NestJS
  • Resumable uploads
  • Tests and a CI pipeline
No prompt adds these
  • Servers and storage to run
  • A malware scan engine
  • Google’s security assessment
  • A SOC 2 audit
  • A global CDN
  • Ongoing upkeep
So yes, you can vibe code a file uploader, even a good one. Everything that keeps it safe, fast and working in production is still your job after the prompt ends.
The gap

A Garage-Built Car and a McLaren Both Get You Across Town

The uploader from the prompt and a production upload system both move a file from a browser into storage, the way both cars reach the same finish line. What separates them is everything around the engine.

The garage-built go-kart has one numbered part, its engine, which stands for the upload request a prompt writes. The supercar has seven numbered parts, one for each service a production upload system runs. The legend below lists them. GARAGE-BUILT BUILT FOR PRODUCTION Across town Both arrive 1 1 2 3 4 5 6 7
  1. 1Engine. The upload request itself. Both cars have one, and it's the part a prompt writes.
  2. 2Transmission. Resumable parts that shrink when the network slows.
  3. 3Brakes. Signed, expiring policies on every upload and download.
  4. 4Crash structure. Malware scanning and safe headers before anyone opens a file.
  5. 5Navigation. Google Drive, OneDrive and Box sign-in through certified OAuth apps.
  6. 6Road legal. SOC 2 and Google's yearly security assessment.
  7. 7Pit crew. Upgrades, fixes and monitoring after every dependency change.

The Same Gap, as an Iceberg

Picture the upload request as the tip of an iceberg. It’s the part the prompt writes, and the only part anyone sees in a demo.

Below the waterline sit the services that make uploads survive real networks, reach the places users keep their files, stay safe to open, load fast everywhere, and keep working after every dependency changes.

Each one took design work, testing on real networks and devices, and years of fixes to get where it is.

The prompt writes what’s above the waterline. Production runs on what’s below it.

Above the water: one PUT to S3, what the prompt writes. Below the water: Resumable uploads, Adaptive chunking, Global ingestion, Cloud sources, Signed policies, Malware scanning, Security headers, CDN delivery, File conversion, SOC 2 audited, Ongoing upkeep. Resumable uploads Adaptive chunking Global ingestion Cloud sources Signed policies Malware scanning Security headers CDN delivery File conversion SOC 2 audited Ongoing upkeep One PUT to S3 What the prompt writes WATERLINE Illustration. Not to scale.
Below the waterline

What a Full-Featured Upload System Is Made Of

Break a full-featured upload system into parts and one way to count them comes to 61 components in 8 layers. Yours depends on what your app does. A prototype uses a handful, and a product that takes files from anyone uses most of them. An AI assistant can write code for many of them. Each one still has to be built, hosted, certified or kept current by someone. On Filestack, all 8 layers sit behind one API.

Build it yourself

8 layers, 61 components
Security UX Sources Ingest Manage AI Deliver Infra Upload files
61 / 61components builtNow maintain all 61

Every layer built, then wired to the upload button.

With Filestack

8 layers, 1 API
FilestackUpload, transform, AI, store, deliver Upload files Security UX Sources Ingest Manage AI Deliver Infra
1 / 1API integratedReady to ship

All 8 layers, behind one API.

Illustration, not to scale.

Feature by feature

What Production Needs, and What Filestack Has Ready

Every layer of that iceberg, one row at a time. The left column is the work that stays with you after the code is written. The right column is already running.

What a production upload system needs: vibe-coded and yours to build, certify and fix, against Filestack, ready-built
What production needs Vibe-coded, yours to build, certify and fix Filestack, ready-built
Upload code AI writes it, and it works Ready. Picker and SDK
Google Drive access AI writes the sign-in. You apply for Google's OAuth verification, pass a third-party security assessment, and repeat it every year Ready. Our registered OAuth apps carry Google's restricted-scope verification
OneDrive, Box, Facebook A separate app review for each provider, and a fix each time its API changes Ready. One line per source in the picker config
SOC 2 An independent audit of your own controls, every year Ready. Audited for SOC 2 every year, report on request
Ingestion network Upload servers in regions near your users, deployed and paid for by you Ready. Our Content Ingestion Network receives each file at the nearest server
Retries on bad networks Multipart and retry code, tested by you on real phones and dropping connections Ready. Each part retried on its own, and parts shrink on a weak signal
Upload security Auth checks, size limits and content type rules you write and review Ready. Short-lived signed policies, and a CSP header on every file
Malware scanning A scan engine to run, virus signatures to keep current, and a quarantine to build Ready. Virus detection on upload, results sent to your webhook
Delivery and previews A CDN, an image pipeline and a document viewer to deploy Ready. One CDN URL per file, resized, converted or previewed
Security testing Vulnerability scans and penetration tests you schedule Ready. Daily vulnerability scans and a yearly third-party penetration test
When it breaks You find the bug, prompt for a fix and test it yourself. Each prompt can return a different fix, and none comes with a guarantee Ours to fix. Monitored around the clock, with a public status page
01Uploads

A Dropped Connection Can Restart a Large Upload From Zero

The short uploader on this page sends the whole file in one request. If a 2 GB video drops at 90% on a train, the next attempt starts from the first byte. S3 also caps a single request at 5 GB.4

Ask the AI to upload in parts next, and the code gets a lot more complicated. It has to split the file, track which parts landed, resume after a page reload, and abort abandoned uploads. S3 keeps the parts of an unfinished upload and bills them as storage until the upload is aborted or a lifecycle rule removes them.5

Data sent again when a 2 GB upload drops at 90%
A worked example, using our SDK's default settings.12
Data sent again when a 2 GB upload drops at 90%
Uploader Data sent again
Single-request uploader 2,048 MB
Filestack SDK 18 MB at most

Assumes the connection returns while the SDK is still retrying. Parts that already arrived are kept.

With Filestack

Only the Failed Part Is Sent Again

Our SDK sends the file in small parts and retries only the part that failed, so a dropped connection costs a few megabytes instead of the whole file. On a weak phone signal, Intelligent Ingestion makes the parts smaller until they get through. The Content Ingestion Network takes each file at the server nearest the user, then moves it to final storage, ours or your own bucket, while the file is already usable.8

“We have thousands of users uploading files on our platform every day. Upload failures can decrease conversion by creating a poor user experience. We’re thrilled to see Filestack tackling this challenge to ensure an uninterrupted experience for our users.”
Dorian Collier Dorian Collier
Director of Product at JibJab
Top: a single-request upload reaches 90 percent, the signal drops, and all 2 GB is sent again. Bottom: the Filestack SDK sends 6 MB parts and only the failed part is sent again. One request all 2 GB sent again Signal drops at 90%Filestack SDK6 MB parts, 3 at a time Only this part is sent againIllustration. A real 2 GB file has hundreds of 6 MB parts.
02Cloud sources

Google Drive Imports Need Approval AI Can’t Get

Unless you ask for more, the code you get back only reads files from the user’s computer. Users keep files in Google Drive, OneDrive, Box, Google Photos and Facebook. Each is a separate integration with its own registered OAuth app, its own review, and its own API changes.

Google Drive is the hardest. Letting a user browse their whole Drive needs access Google classes as restricted. Restricted access requires Google’s OAuth app verification plus a Cloud App Security Assessment by an authorized third-party assessor, and Google revalidates the app every year.2,3 AI can write the sign-in code. It can’t pass Google’s security assessment for you.

A narrower path exists. Google’s own file picker can hand your app single files without the assessment. It covers Google Drive only, and every other provider still needs its own integration.

1
Sign-in flow and Drive API calls
The code that opens Google sign-in and lists files
AI can write this
2
Google OAuth app verification
Required for restricted Drive access
No prompt does this
3
Cloud App Security Assessment
Run by an authorized third-party assessor
No prompt does this
4
Revalidation every year
The assessment comes back annually
No prompt does this
Then again for OneDrive, Box and Facebook, each with its own app review
With Filestack

Cloud Sources Are One Line of Config

Users sign in through our registered OAuth apps, so adding Google Drive, OneDrive or Box is one entry in the picker config.

Select files to upload
  • My Device
  • Google Drive
  • OneDrive
  • Box
  • Google Photos
  • Facebook
Google Drive / My Drive
02Security

Three Security Flaws in the Short Example

The server code from the prompt, the part that hands out upload URLs, has three security flaws. Another model or a more careful prompt might avoid all of them. Whether yours did is something you have to check line by line.

  1. Anyone can call it.No login check, so anyone who finds the URL gets signed upload URLs for your bucket, and you pay for whatever they store.
  2. The browser picks the content type.A caller can send type=text/html and upload a page with a script in it. Serve that bucket from your own domain through a CDN, and the script runs on your domain when someone opens the file.
  3. There's no size cap.Someone can fill your bucket with 5 GB files, and you pay to store them.
server.mjs, the lines that matter
app.get("/upload-url", async (req, res) => {1  const key = `uploads/${crypto.randomUUID()}-${req.query.name}`;  const command = new PutObjectCommand({    Bucket: "my-app-uploads",    Key: key,    ContentType: req.query.type,2  });  const url = await getSignedUrl(s3, command, { expiresIn: 300 });3

A follow-up prompt fixes each flaw once someone spots it. Spotting it is the hard part. Veracode’s 2026 report puts the average security pass rate of AI-generated code at 56% with no security-specific prompting, and 15% for cross-site scripting, the class the second flaw belongs to.1

How the second flaw plays out
Five steps: a caller asks for an upload URL with type text/html and no login; the server signs it; a page with a script lands in the bucket; the CDN serves it on your domain; someone opens the link and the script runs on your domain. 1A caller asks for an upload URLtype=text/html, no login needed 2The server signs itNo check on who asked, or for what type 3A page with a script lands in your bucketStored as text/html 4Your CDN serves it on your domaincdn.yourapp.com/uploads/page.html 5Someone opens the linkThe script runs on your domain
How often AI-generated code passes security tests
Average pass rate by vulnerability type, with no security-specific prompting.
How often AI-generated code passes security tests
Vulnerability type Pass rate
Cryptographic algorithms 87%
SQL injection 83%
Average, all tasks 56%
Cross-site scripting 15%
Log injection 12%

Source: Veracode, 2026 GenAI Code Security Report.1

With Filestack

All Three Flaws, Fixed

Every upload and download can require a short-lived security policy that your server signs. It limits what the request can do, how big the file can be and where it goes, and the secret that signs it never reaches the browser. Each policy expires on a timer you set, so your server issues fresh ones as it goes and a leaked policy stops working on its own.9

Every file our CDN serves carries a Content-Security-Policy header that blocks inline scripts. We’re audited for SOC 2 every year, and the report is available on request.

  • 1Anyone can call it A signed policy that expires
  • 2The browser picks the content type A CSP header that blocks inline scripts
  • 3There's no size cap A maximum file size in the policy
  • SOC 2 Independently audited controls
04Malware

Malware Scanning Is a Service, Not a Function

Unless you ask for scanning, the code you get back stores whatever arrives. A user uploads an infected PDF, and the next person to open it downloads the infection from your app.

Adding a scan yourself means building another service. One option is running the open-source ClamAV scanner on your own server, keeping its virus signatures up to date, and hiding each file until its scan passes. The other is AWS’s GuardDuty Malware Protection for S3, which scans new files and reports the result.6 You still build the part that quarantines an infected file and stops your app from serving a file that hasn’t been scanned.

An infected file is uploaded, stored as is, and downloaded by every user who opens it. Without a scanwhat gets stored Upload Storage Every user who opens it
Scanning it yourselfEvery blue box is yours to build and run
Upload→ S3 bucket→ Scan engine→ Signature updates→ Quarantine rule→ "Scanned yet?" check before serving

ClamAV on your server, or GuardDuty plus your own quarantine and serving logic.

With Filestack

Scanned as Soon as It Lands

Virus detection runs as a Workflows task as soon as a file reaches storage. Your server hears about an infected file, and the name of the threat, as soon as the scan finishes. Virus detection runs on the Start plan and above.

A file is uploaded, scanned by the virus detection workflow as it arrives, and an infected result is sent to your webhook. Upload Scanned on arrival Infected: flaggedto your webhook
05Delivery

CDN, Thumbnails and Previews Are Separate Projects

The short uploader gives you an S3 key in a private bucket, so showing the file to anyone needs another signed URL. An AI can write each missing piece, and each is then a service you deploy and run.

Image pipelineConversion serviceDocument viewerCDN configuration
Six users around a stylised world map. Dashed lines run from every user to one S3 bucket in one region. Short orange lines connect each user to a nearby CDN edge. S3 one bucket, one region Every download crosses to one region CDN edge near each userWhere each download comes from
With Filestack

One URL Does All Four Jobs

Every uploaded file gets a URL on our CDN, which caches each unique URL for 30 days.10 Resizing an image, converting a Word file to PDF, or showing a Word, Excel or PowerPoint file in our document viewer is a change to that URL. The document viewer runs on the Grow plan and above.11

cdn.filestackcontent.com/HANDLEThe file, from the CDN
cdn.filestackcontent.com/resize=width:800/output=format:webp/HANDLEA resized WebP thumbnail, instead of an image pipeline
cdn.filestackcontent.com/output=format:pdf/HANDLEA Word file as PDF, instead of a conversion service
cdn.filestackcontent.com/preview/HANDLEThe document in a browser viewer, instead of building one
06Upkeep

Someone Has to Keep It Current

A prompt produces code on the day you ask. Everything that code depends on keeps changing after that: the runtime, the SDK, Google’s assessment and every provider’s API.

Each change lands on whoever owns the uploader, on top of the work of building an upload service in house in the first place.

30 Apr 2025
Node.js 18 stops getting security fixes7
8 Sep 2025
AWS SDK for JavaScript v2 reaches end of support13
30 Apr 2026
Node.js 20 stops getting security fixes7
Every year
Google revalidates apps with restricted Drive access3
Any week
A cloud provider changes its API, and the integration breaks until someone updates it
With Filestack

The Upgrades Are Ours to Make

We ship the runtime upgrades, provider API changes and fixes. Your side of the integration stays the few lines below.

Your side of the integration
import * as filestack from "filestack-js"; const client = filestack.init("YOUR_API_KEY");client.picker({  fromSources: ["local_file_system", "googledrive"],}).open();

Your Roadmap Starts on Day One

Same team, same roadmap. The only difference is who builds and keeps up the upload stack.

Illustration, not to scale. Features shown are examples.

Skip the infrastructure sprint

Uploads, processing, storage, delivery and security come ready.

Skip the upkeep

We scale, monitor and maintain the stack after launch.

Ship feature one sooner

Your first sprint goes to something customers can see.

“It’s simplified the process of managing users photos while allowing us to focus on building new features that address the challenges our customers are facing.”
Rob Eanes Rob Eanes
CTO at Pingboard.com
The verdict

So, Should You Vibe Code Your Uploader?

Sometimes, yes. It depends on who uploads, from where, and who opens the file afterwards.

Only your team uploads? Small files from a desktop? Nobody else opens them? Three yes answers lead to vibe code it. Any no leads to build on Filestack. Only your team uploads? No Yes Small files from a desktop? No Yes Nobody else opens them? No Yes Build onFilestackany customer-facing answer Vibe code it

Vibe code it when

  • It's a prototype or an internal tool
  • A few trusted people do the uploading
  • Files are small and come from a desktop
  • Nobody else opens what gets uploaded

The code from the prompt does that job.

Build on Filestack when

  • Customers upload from phones on weak or dropping connections
  • Files are large, like video, and a failed upload can't start over
  • Users pick files from Google Drive, OneDrive or Box
  • Anyone outside your team can upload
  • Uploads need limits on size, type and who sent them
  • Other users open what gets uploaded
  • Every file has to be scanned before anyone opens it
  • Images need several sizes or formats
  • Word, Excel or PowerPoint files need a preview in the browser
  • Files load for users in more than one region
  • A customer's security review asks for SOC 2
  • Nobody on the team wants to own runtime, SDK and provider API upgrades

Each of these becomes a feature your product owns once it applies. On our SDK, each one is configuration.

Best of both

Keep Vibe Coding, on Top of Filestack

Our Filestack plugin for Claude Code, which also works in Cursor, gives your assistant tools that upload, transform, convert and secure files on your own account, plus skills for SDK integration, workflow design, webhook setup and error diagnosis.14

Ask for an uploader built on Filestack, and the assistant writes it against the picker, signed policies and virus scanning instead of a bare request to S3. Policy signing runs on your machine, so your app secret stays local.

19 MCP tools 5 skills Claude Code and Cursor Local policy signing
Install in Claude Code
# add the marketplace, then install/plugin marketplace add https://github.com/filestack/filestack-claude-plugin.git/plugin install filestack-claude-plugin@filestack-plugin
The same uploader on our SDK
import * as filestack from "filestack-js"; // policy and signature come from your serverconst security = await fetch("/filestack-security").then((r) => r.json());const client = filestack.init("YOUR_API_KEY", { security }); client.picker({  fromSources: ["local_file_system", "googledrive", "onedrive",                "box", "url", "webcam"],  accept: ["image/*", "application/pdf"],  maxSize: 100 * 1024 * 1024,  storeTo: { workflows: ["YOUR_WORKFLOW_ID"] }, // virus scan  onUploadDone: (res) => console.log(res.filesUploaded),}).open();
Common questions

Frequently Asked Questions

Can't we ask the AI to add each missing piece?

For most of the code, yes, one prompt at a time. Each piece is then yours to test, run and update when its dependencies change. Google’s restricted-scope verification, its yearly security assessment and a SOC 2 audit aren’t code, so no prompt produces them.

Isn't building it ourselves cheaper?

The first version can be fast. What it costs to run depends on your team, and our file upload cost calculator estimates it with your own numbers. What it can’t produce is Google’s restricted-scope approval, a SOC 2 audit or a global CDN.

Do we have to stop using AI coding tools?

No. Our Filestack plugin for Claude Code and Cursor lets your assistant build on the picker, signed policies and virus scanning, so you keep the speed of a prompt.

Can files stay in our own storage?

Yes. Uploads can go to your own Amazon S3, Google Cloud Storage, Azure or Dropbox storage, or to Filestack storage by default.

Is Filestack SOC 2 compliant?

Yes. We’re audited for SOC 2 every year, and the report is available on request. Our file upload security page lists the audits and the contract documents behind them.

Which plans include virus detection and document preview?

Virus detection runs on the Start plan and above. The document viewer runs on the Grow plan and above. Every plan, including Free, includes the CDN.

We already built an uploader with AI. Can we move to Filestack?

Yes. Talk to our team about moving your current upload code to the picker, signed policies and CDN URLs.

References

Sources

  1. Veracode. 2026 GenAI Code Security Report.
  2. Google. Choose Google Drive API scopes, restricted scope classification.
  3. Google. Security assessment for restricted scopes, annual revalidation.
  4. Amazon Web Services. Uploading objects, 5 GB single PUT limit.
  5. Amazon Web Services. Uploading and copying objects using multipart upload.
  6. Amazon Web Services. GuardDuty Malware Protection for S3.
  7. Node.js. Release schedule, end-of-life dates.
  8. Filestack. Uploading, Intelligent Ingestion and the Content Ingestion Network.
  9. Filestack. Security policies.
  10. Filestack. CDN, caching.
  11. Filestack. Document viewer.
  12. Filestack. filestack-js 3.51.6, upload defaults: 6 MB parts, 3 concurrent, 10 retries.
  13. Amazon Web Services. End of support for AWS SDK for JavaScript v2.
  14. Filestack. Filestack plugin for Claude Code and Cursor, version 1.3.0.