Web Development 4 min read

What the laravel-lang Attack Means for Small Projects (And Everyone Else)

Earlier this week, the PHP ecosystem got a sharp reminder that supply chain attacks are not a theoretical concern.

A grey mesh wire container filled to the brim with silver paperclips sitting on a wooden table, with loose paperclips spilling out onto the surface.
Photo: Brett Hondow

The laravel-lang/lang package was compromised with malicious code injected into its autoloader — code that runs on every request, before your application even boots.

If you're running a small Laravel project, or any Composer-based PHP app, here's what actually happened and why it matters.

The Attack Vector

The malicious package didn't target user-facing features. It targeted Composer's autoloader. In PHP, the autoloader is infrastructure: it runs before your routes, before your middleware, before your auth checks. If it's compromised, your entire application is executing attacker-controlled code with the privileges of your web server process.

This is not a Laravel problem specifically. It's a Composer problem. It's a "trusting strangers on the internet to run code in your production environment" problem.

Why Small Projects Are Not Immune

The temptation is to think "this only matters for big enterprise apps." The opposite is true. Large organisations have security teams, audit budgets, and vendored dependencies. Solo developers and small teams are the ones pulling packages blindly mid-week because a tutorial said to.

Here's the uncomfortable reality: when you run composer require, you're installing not just the package you looked at, but every package it depends on. Most of us have never audited those transitive dependencies. I certainly hadn't, until this week.

What We Did on Our Stack (CloudHerder)

After reading about the attack, I ran composer audit on CloudHerder and found we were carrying a HIGH severity vulnerability in our markdown editor (mckenziearts/livewire-markdown-editor), plus nine separate CVEs across Symfony packages we never explicitly installed.

The fixes were straightforward — update, test, deploy — but they shouldn't have been sitting there for weeks. The gap wasn't in our package selection. It was in our visibility.

So we made two changes:

1. Faster Detection

composer audit is now part of our deploy workflow. If a HIGH or CRITICAL advisory exists in the lockfile, the deployment stops until it's resolved. No exceptions.

2. Better Visibility

We had model-level activity logging (via spatie/laravel-activitylog) for content changes, but nothing for auth events. Login attempts — successful and failed — were invisible. API access via Sanctum tokens was invisible.

We added listeners for Login, Logout, and Failed auth events, plus middleware to log every API request. Now the activity log shows:

  • Who logged in, from where, and when
  • Failed login attempts (including the source IP)
  • Every authenticated API call and every failed token authentication

This isn't about preventing attacks. It's about knowing they happened.

Practical Steps You Can Take Today

If you maintain a Composer-based project, here's the minimum viable security posture:

  1. Run composer audit before every deploy. It takes seconds. Make it a hard gate.
  2. Check transitive dependency count before installing anything new. composer show --tree <package> will show you exactly what you're dragging in.
  3. Disable Composer scripts in production. Run composer install --no-scripts in CI, then run any necessary post-install steps manually where a compromise does less damage.
  4. Log auth events. If someone compromises an account, you need to know when and from where.
  5. Pin your lockfile and review diffs. Don't run composer update casually. Update specific packages for specific reasons.

The Bigger Picture

The laravel-lang package was where someone noticed this particular compromise. It won't be the last. Package maintainers get tired, accounts get hijacked, and attackers are getting more sophisticated about targeting the earliest possible execution point.

You can't eliminate the risk entirely without rewriting every dependency by hand. What you can do is shrink your exposure, improve your detection, and shorten the window between a CVE being published and your deployment of the patch.

Upstream, tools like Aikido Security integrate with Composer to scan tagged releases automatically. Stable version immutability prevents attackers from silently rewriting existing tags. There's also serious pressure across the ecosystem — npm, PyPI, Composer — to require multi-factor authentication before a maintainer can distribute a release. These are the right moves, and they matter. But registry-level hardening is a complement to your own gates, not a replacement. Defence in depth means not assuming any single layer will hold.

Security isn't a product you buy. It's a process you maintain.

D

Dallum Brown

Writer and curator exploring the impact of technology on everyday life.

View All Articles

Subscribe to
The Brief

Our curated selection of tech news and other discoveries, delivered every month.

No spam. Unsubscribe anytime.

Comments (0)

Please sign in to leave a comment.

No comments yet. Be the first to share your thoughts!

Further Reading

Privacy Notice

We use essential cookies for site functionality (session management, CSRF protection) and do not track you across the web. By using this site, you acknowledge our Privacy Policy and New Zealand Privacy Act 2020 compliance.

Learn More