# Fake Laravel Packages on Packagist Are Installing Backdoors. Here Is How to Check.

> Three malicious Packagist packages disguised as Laravel utilities deploy a cross-platform RAT that gives attackers full shell access, reads your .env, and exfiltrates credentials. Here is what happened, how to check if you are affected, and what to do.

**Author:** Matt King | **Published:** March 16, 2026 | **Category:** Security

---

On March 4, 2026, security researchers flagged three malicious packages on Packagist — PHP's primary package repository — that were disguised as Laravel utilities. The packages install a cross-platform remote access trojan (RAT) that works on Windows, macOS, and Linux, giving attackers full shell access to any server running the compromised application.

This is not a theoretical vulnerability. Any Laravel application that installed these packages is running a persistent backdoor with access to your `.env` file, database credentials, API keys, and every file on the server.

## The malicious packages

| Package | Downloads | Contains malware directly? |
|---------|-----------|---------------------------|
| `nhattuanbl/lara-helper` | 37 | Yes |
| `nhattuanbl/simple-queue` | 29 | Yes |
| `nhattuanbl/lara-swagger` | 49 | No — but requires `lara-helper` as a dependency |

The attacker also published three clean packages (`nhattuanbl/lara-media`, `nhattuanbl/snooze`, `nhattuanbl/syslog`) to build credibility on Packagist before publishing the malicious ones. This is a common supply chain attack pattern: establish trust first, then weaponise.

## How the attack works

Both `lara-helper` and `simple-queue` contain a file named `src/helper.php` that uses heavy obfuscation:

- **Control flow obfuscation** — scrambled execution paths that make static analysis difficult
- **Encoded strings** — domain names, command names, and file paths are encoded rather than stored as plaintext
- **Randomised identifiers** — variable and function names are random strings to evade pattern matching

When your Laravel application boots or autoloads the package's classes, `helper.php` executes automatically. It:

1. **Profiles your system** — collects hostname, OS, PHP version, and installed packages
2. **Reads your environment** — extracts the full contents of `.env` including database credentials, API keys, and `APP_KEY`
3. **Opens a reverse shell** — connects to the attacker's command-and-control (C2) server
4. **Persists** — retries the C2 connection every 15 seconds in a loop, so even if the server is temporarily down, the RAT will reconnect when it comes back

Because the RAT runs in the same PHP process as your Laravel application, it has identical filesystem permissions and access to every environment variable. There is no privilege boundary between the RAT and your application code.

## The C2 server is down — am I safe?

No. The RAT is configured to retry indefinitely. If the attacker brings the C2 server back online, or if the domain is re-registered, every compromised application will reconnect automatically. A non-responsive C2 server means the attacker is not currently issuing commands, not that the backdoor is gone.

## How to check if you are affected

### Step 1: Search your dependencies

```bash
# Check installed packages
composer show | grep nhattuanbl

# Search composer.lock directly
grep -r "nhattuanbl" composer.lock
```

If either command returns results, your application is compromised.

### Step 2: Search your vendor directory

```bash
# Look for the malicious helper file
find vendor -name "helper.php" -path "*/nhattuanbl/*"
```

### Step 3: Check composer.json history

Even if the packages have been removed, check your git history to see if they were ever installed:

```bash
git log -p --all -S "nhattuanbl" -- composer.json composer.lock
```

## Remediation steps

If you find any of these packages in your project, treat it as a full compromise:

### 1. Remove the packages immediately

```bash
composer remove nhattuanbl/lara-helper nhattuanbl/simple-queue nhattuanbl/lara-swagger
```

### 2. Rotate every secret

Every credential in your `.env` file must be considered compromised:

- **APP_KEY** — run `php artisan key:generate` and redeploy
- **Database passwords** — change in your database server, then update `.env`
- **API keys** — regenerate keys for every third-party service (Stripe, AWS, SendGrid, etc.)
- **Mail credentials** — reset SMTP passwords
- **OAuth secrets** — regenerate client secrets for any OAuth integrations

### 3. Audit for lateral movement

```bash
# Check for recently modified files outside vendor/
find . -newer composer.lock -not -path "./vendor/*" -not -path "./.git/*" -name "*.php" -type f

# Check for unauthorized cron jobs
crontab -l

# Review recent database activity
php artisan tinker --execute="DB::table('users')->where('created_at', '>', now()->subDays(7))->get(['id','email','created_at'])"
```

### 4. Check outbound network connections

```bash
# Look for suspicious outbound connections from the PHP process
ss -tp | grep php
netstat -an | grep ESTABLISHED | grep php
```

### 5. Consider re-provisioning

If you confirm the RAT was active while the C2 server was responsive, the safest approach is to re-provision your server from a clean state rather than trying to clean a compromised system.

## Why this keeps happening

This attack exploits the same trust model that makes Composer convenient: you run `composer require` and trust that the package does what it says. Packagist does not perform security review on uploaded packages. Anyone can publish anything.

This is not unique to PHP. The npm ecosystem sees hundreds of malicious packages per month. PyPI has the same problem. The [OWASP Top 10 2025](https://owasp.org/Top10/2025/) elevated Software Supply Chain Failures to position #3, reflecting how systemic this risk has become.

### How to reduce your supply chain risk

1. **Audit new dependencies before installing** — check the author's profile, download count, and repository activity
2. **Run `composer audit` in CI** — catches known CVEs in your dependency tree
3. **Pin exact versions** — use exact version constraints in `composer.json` rather than `^` ranges for critical packages
4. **Review autoloaded files** — check what a package registers in its `composer.json` autoload section before installing
5. **Monitor your application externally** — supply chain attacks change what your application does in production, and external monitoring catches behavioral changes that code review misses
6. **Use `composer.lock`** — always commit your lock file and run `composer install` (not `update`) in production

## The bigger picture

Low download counts (37, 29, 49) might make this seem like a small incident. But consider:

- Each download potentially represents a production application
- The attacker built credibility with clean packages first, showing sophistication
- The RAT persists indefinitely and will reconnect if the C2 comes back
- The packages had legitimate-sounding names that a developer might install without suspicion

Supply chain attacks do not need to be widespread to be devastating. A single compromised dependency in a single application is enough to exfiltrate every secret in your environment.

---

## Frequently Asked Questions

### Which Laravel packages on Packagist are malicious?

The malicious packages are nhattuanbl/lara-helper (37 downloads), nhattuanbl/simple-queue (29 downloads), and nhattuanbl/lara-swagger (49 downloads). The lara-swagger package does not contain malicious code directly, but lists lara-helper as a dependency, causing the RAT to install automatically. The same author published three clean packages (lara-media, snooze, syslog) to build credibility.

### How do I check if my Laravel project installed a malicious package?

Run composer show | grep nhattuanbl in your project directory. If any results appear, your application is compromised. Also check your composer.lock file for any of the three package names. Even if the C2 server is currently non-responsive, the RAT retries the connection every 15 seconds, so it will activate if the server comes back online.

### What does the Laravel Packagist RAT do?

The RAT gives the attacker full remote shell access to your server. It runs in the same process as your Laravel application with the same filesystem permissions, meaning it can read your .env file, database credentials, API keys, and any file accessible to the web server. It also profiles your system and sends host information to the command-and-control server.

### What should I do if I installed one of the malicious Laravel packages?

Assume full compromise. Remove the packages immediately with composer remove. Rotate every secret in your .env file: database passwords, API keys, APP_KEY, mail credentials, and any third-party service tokens. Audit outbound network traffic for connections to the C2 server. Check for any unauthorized changes to your codebase or database. Consider re-provisioning the server from a clean state.

