Home About Lessons Blog On The Mic Contact Projects
Lessons DEPLOY · C#

Neighbor-Site Risk on Shared Hosting and VDS Isolation

9 min read · Emre Ulutabak
1
The real incident: unfamiliar files in the css folder

After a deploy, you check the css/ folder on the server and see files that shouldn't be there: oddly-named files like 1Zi847pw4.php, G2Hx052.asp, vRWZ4h.aspx. You're publishing an ASP.NET Core project — a .php file can never come from your own project.

The first reflex is panic: "is my computer infected, did I upload this myself?" But the real question should be: where did these files actually come from?

💡
Files with .php, .asp, .aspx extensions, random/meaningless names, and no fit with your project structure are usually a web shell — a backdoor an attacker leaves to access the file system.
2
Where did the files come from, and how was it confirmed?

At first, your own publish output seems like the obvious suspect. But a simple check quickly rules that out: looking at the suspicious files' creation/modification date in FTP or the hosting panel's file manager shows a date and time you never ran a deploy.

Next, the local publish output and the project folder (wwwroot/) get checked one by one — no such file exists there either. So the file never left your machine at all; it was dropped straight onto the server, from outside.

At this point only one explanation remains: another customer's site on the same physical server has a vulnerability (an outdated WordPress or Joomla version, for example), and the attacker got in through it, walked the file system, and left a shell in your folder too.

powershell
# FTP / hosting panelinin dosya yöneticisinde bakacağın işaret: tarih uyuşmazlığı
# Senin son deploy'unu yaptığın tarih:  12.04.2026 14:20
# Şüpheli dosyaların değişme tarihi:

css/1Zi847pw4.php    14.04.2026 03:11   <- sen o gün deploy yapmadın
css/G2Hx052.asp      14.04.2026 03:11
css/vRWZ4h.aspx      14.04.2026 03:12

# Aynı klasörü yerel publish çıktınla karşılaştır:
# yerelde bu isimde dosya yoksa, sunucuya dışarıdan atılmış demektir
3
Why is isolation weak on shared hosting?

The core idea of shared hosting is: one physical server, hundreds of customers. Everyone's site sits on the same disk, under the same operating system, separated only by folders.

This model is cheap and convenient, but it carries two major risks:

  • A neighbor site's vulnerability — if another site on the same server runs outdated/unpatched software (a WordPress plugin, a Joomla core), an attacker can get in through it, and if file-system permissions are weak, reach other customers' folders too.
  • FTP brute force — if an FTP account with a weak password is cracked, an attempt can be made to jump to other accounts on the same server.

No matter how clean your own code is, a neighbor's vulnerability isn't your responsibility, but it can still affect you. This is a risk baked into the nature of shared hosting.

💡
"This isn't your fault" doesn't mean "you have no responsibility to take precautions." Getting into the habit of comparing the files on your server against your own project after every release (manually or with a simple script) is a cheap and effective defense against this risk.
4
How does isolation work on a VDS?

A VDS (Virtual Dedicated Server) is a model where resources are separated at the hardware level. CPU cores, RAM, and disk space are genuinely allocated to your own partition — a neighboring account does not share the same file system as you.

The comparison can be summarized like this:

  • Shared Hosting — one file system, separation by folder, a neighbor's vulnerability can affect you, no root.
  • VPS — separated via virtualization, resources are mostly isolated but the physical hardware is shared, you have root.
  • VDS — separated at the hardware level, the strongest isolation, root is yours, a fully independent environment.

On a VDS, a "neighbor site" can never touch your file system — because technically there is no shared file system to begin with. You have your own OS, your own IIS/Plesk setup, your own security configuration. Responsibility shifts fully to you too — patching, the firewall, and backups are now yours to manage.

5
Protective measures

If you're going to stay on shared hosting, you can reduce the risk even if you can't eliminate it entirely:

  • Regularly compare the files on your server against your own project — downloading folders via FTP and comparing them to your local publish output (or writing a simple comparison script) helps you spot an unfamiliar file quickly.
  • Keep FTP passwords strong — the cheapest and most effective defense against brute force.
  • Report suspicious files to the hosting company immediately — stating which files, in which folder, and on which date they were found.
  • Check your other sites too — if you have more than one site on the same server, the breach may not be limited to just one of them.

For a critical component (something like a license validation API that needs to stay reachable at all times), the healthiest decision once you reach a certain growth point is to move it to a VDS. Shared hosting is still a reasonable starting point for development and lower-risk pages.

💡
When you find a breach, before deleting the file, note its name, path, and the date it was found — this information speeds up the hosting company's investigation a lot when you report it.
6
Golden rules
  • ✅ Take it seriously if you see a file with an extension that doesn't fit your project (.php, .asp, .aspx on an ASP.NET Core site)
  • ✅ To confirm the suspicion, check the file date first, then the local publish output — prove whether it came from your own output or not
  • ✅ File-system isolation on shared hosting is limited — a neighbor's vulnerability isn't your fault but can still affect you
  • ✅ A VDS raises isolation to the hardware level — the concept of a "neighbor" technically disappears
  • ✅ Plan to move critical/always-reachable services to a VDS once you reach a certain growth point
7
Mini quiz
MINI QUIZ
You find a file on your server that doesn't match your project. What's the most practical first step to figure out whether it came from your own release or from outside?
Comparing the file's creation/modification date and content against your local publish output
Deleting the file immediately and forgetting about it
Restarting the IIS App Pool
Renaming the file's extension and trying again