What is a web shell?

The script an attacker leaves behind so that closing the original hole changes nothing.

By Ihor Havrysh ยท Last reviewed July 2026

Eaglepedia mascot

A web shell is a small script placed on a web server that an attacker can reach through a normal web request, giving them a way to run commands on that server. MITRE ATT&CK classifies it as a persistence technique, because its purpose is to keep access open long after the original way in has been closed.

What it is for

MITRE ATT&CK catalogues web shells as T1505.003, Server Software Component: Web Shell, and files the technique under persistence rather than under initial access. That classification is the most useful thing to understand about them.

A web shell is not how an attacker gets in. Something else does that: an unpatched component, a stolen credential, a misconfigured permission, an upload feature that accepted the wrong thing. The web shell is what they leave behind so that fixing the original problem does not remove them.

MITRE describes it as a server-side script placed on an accessible web server that grants gateway access into a network, providing command execution or a command-line interface on the compromised host. In plain terms, it turns a URL into a way of issuing instructions to your server, and it keeps working after the patch is applied and the passwords are rotated.

That is why they matter out of proportion to their size. A few lines of script can convert a single lapse into indefinite access.

How an upload feature becomes the route in

File upload is the classic delivery mechanism, and it works when three conditions happen to line up.

  1. The application accepts a file it should not. Usually because validation trusts the filename or the declared content type, or because a polyglot file satisfies a content check while also being valid as something executable
  2. The file lands somewhere the server will execute. Uploads written into a directory inside the web root, on a server configured to run scripts from it, are the dangerous combination. If the same file lands outside the web root it is inert
  3. The attacker can reach it. They need the resulting address, which is straightforward if you keep the original filename and store files in a predictable place

All three are required. Break any one and the route closes, which is what makes this defensible: you do not have to win the argument about whether a file is malicious in order to make it harmless.

The three conditions a web shell needs, each with the control that breaks it: allowlisting, storage location and renaming
You never have to settle the argument about whether a file is malicious. Removing any one of the three conditions is enough.

Two industry lists point at the same conclusions from different directions. PortSwigger's guidance is to rename uploaded files, keep them off the permanent filesystem until fully validated and check extensions against a permitted list. MITRE's mitigations are to remove dangerous functionality that is not needed, and to apply least privilege so that only authorised accounts can modify web directories. Those overlap on the same principle: the upload should never be able to become a resident, executable part of your application.

Why they are hard to find later

Web shells are small, and they sit among files that are supposed to be there. On a server with thousands of application files, one more does not announce itself, and requests to it look like ordinary web traffic in a log full of ordinary web traffic.

MITRE's detection guidance is instructive because it does not attempt to describe what the file looks like. It points at behaviour instead:

  • Scripts appearing unexpectedly in web-accessible directories, particularly followed by the web server process spawning a command shell
  • Unauthorised script files in directories the web server serves, followed by execution of system utilities
  • Abnormal process creation from a web server process after files have been written to web directories

The common thread is that a web server has a narrow job. It should serve content and talk to your application. When it starts a command interpreter, something has gone wrong regardless of which file caused it, and that signal holds even against a script nobody has catalogued.

For an application team, the practical version is that file integrity monitoring on served directories, and alerting on unexpected process creation from the web server, will tell you more than trying to recognise the script itself.

Keeping them out

The controls that matter are mostly about where files live and what is allowed to happen to them, not about detection.

  • Store uploads outside the web root, ideally in object storage rather than on the application server, and serve them through code that reads the file rather than by exposing a path
  • Take away execution. The directory holding user content should not be a place the server will run anything from
  • Rename every upload to an identifier you generate, and keep the original name as metadata for display only
  • Serve user content from a separate origin, which also limits what a file could do in a visitor's browser
  • Restrict write permissions so the web server account cannot write into the directories it serves, per MITRE's least-privilege mitigation
  • Rebuild what you accept. Re-encoding images and applying content disarm and reconstruction to documents means what you store is assembled from legitimate content rather than merely permitted to pass

Notice that most of these hold even when validation is wrong. That is deliberate, and it is the right way to think about the problem. Validation is a filter that will occasionally be beaten. Storage location and execution permissions decide what happens on the occasion it is.

Our guide to file upload security covers how these fit together in a working upload pipeline.

Where it lands matters. So does what it is. Storage and permissions limit what an unexpected file could do. The Red Eagle Tech CDR API handles the other half, rebuilding documents from their safe components before you ever store them. Published per-document pricing, and you can be running in minutes.

Frequently asked questions

Because it is what an attacker leaves behind rather than how they got in. MITRE ATT&CK catalogues it as T1505.003, Server Software Component: Web Shell, under the persistence tactic. Something else provided the initial access. The web shell exists so that access survives the patch, the password reset and the incident review.

Three conditions have to line up. The application accepts a file it should not, that file lands somewhere the web server will execute rather than merely serve, and the attacker can work out the resulting address. Break any one of the three and the route closes, which is why the standard advice is to validate content, store uploads outside the web root and rename files on the way in.

A web shell can be very small and it lives among legitimate application files, so it does not stand out in a directory listing. Requests to it look like ordinary web traffic to the server it is running on. This is why MITRE's detection guidance focuses on behaviour rather than file contents: a web server process spawning a command shell is unusual regardless of what the script looks like.

Two, and both are structural. Disable or remove dangerous functionality that is not needed, such as language features that execute arbitrary strings. And apply least privilege to account management, so that the accounts able to write into web-accessible directories are restricted to the ones that genuinely need to. If your web server cannot write to the directory it serves from, an upload cannot become a resident script there.

Yes, as one layer among several. Rebuilding a document from its safe components means what you store is structurally clean rather than merely permitted, which removes files that are valid as two formats at once. It sits alongside the other controls rather than replacing them, because storage location and execution permissions decide what an unexpected file could do if one ever does get through.
Ihor Havrysh - Software Engineer at Red Eagle Tech

About the author

Ihor Havrysh

Software Engineer

Software Engineer at Red Eagle Tech with expertise in cybersecurity, Power BI, and modern software architecture. I specialise in building secure, scalable solutions and helping businesses navigate complex technical challenges with practical, actionable insights.

Read more about Ihor

Discovery call

A friendly 15-minute video call with Kat to understand your needs. No preparation needed.

  • Discuss your project
  • Get honest advice
  • No obligation
Kat Korson, Founder of Red Eagle Tech

Kat Korson

Founder & Technical Director

Our team has 10+ years delivering software solutions for growing businesses across the UK.

Send us a message

Your information is secure. See our privacy policy.

Find us