Ignoring the 11 months since Part 3 was posted, it would be nice to share a tale between yours truly & Laravel, whomst've have tried their best avoiding a line of code that I believe is exploitable, present for over 6 years.
The year was 2021; upon discovering what I perceived to be an exploitable piece of code that existed within Laravel since at least 2016, I did what any good Samaritan would do.
Attempted to get a CVE issued against the framework.
The Exploit
Is a line of code within Scheduler's Command Builder that does not escape shell arguments.
I would never call myself an expert on security, but to my untrained eyes it appeared to resonate the profile of an command injection.
https://owasp.org/www-community/attacks/Command_Injection
return $event->user && ! windows_os() ?
'sudo -u '.$event->user.' -- sh -c \''.$command.'\'' :
$command;
(Formatted for readability) https://github.com/illuminate/console/blob/6678d8f63c1f0dd8fb1c98010d9893673f444e84/Scheduling/CommandBuilder.php#L73
With assistance of this line of code, using the Laravel Framework we're able to schedule the execution of any arbitrary shell command (Outside of Laravel).
Timeline
Feb 2021
I submit a vulnerability @ Snyk with details surrounding the supposed exploit
Response (excerpt)
I recognise that the lines you pointed to show unescaped inputs. However, your description does not clarify how an attacker can alter these input parameters in the context of this package and how it's implemented by its users.
It would be helpful if you could provide the details showing the possible attack path, or, better yet, a working PoC of an injected command.
Fair enough.
6 hours later
Created & replied with this PoC
Laravel - Shell Escape PoC
Proof of Concept to prove Laravel package vendors can exploit the command scheduler to run self-scheduled arbitrary shell commands.
Meaning the host can execute an arbitrary command in a child process shell, invoked by the Laravel scheduler.
This package uses head -n 1 /etc/passwd > /tmp/really-cool.log
for the example.
Affecting all Laravel versions above 5.4 (Lumen is untested) when the scheduler artisan schedule:run
is used.
Installation
composer create-project laravel/laravel example-app
- Include this package
composer require shell-escape/poc:dev-master
Due to the nature of this package I will not be adding it to packagist.
You will have to add the repository manually https://getcomposer.org/doc/05-repositories.md#repository
Running
> php artisan schedule:run
Running scheduled command: sudo -u YOURUSER $(cat /etc/passwd > /tmp/really-cool.log || true) -- sh -c ''/usr/bin/php' 'artisan' the:poc > '/dev/null' 2>&1'
Process finished with exit code
…
(Technical details are inside ^ README)
Later in Feb 2021
Received a follow up
I've verified the PoC you attached and have contacted the maintainers. I’ll let you know how the disclosure progresses.
March 2021
Received a follow up
The guys at Laravel responded as follows:
But, isn't users installing a malicious internal package always a security vulnerability. ANY package can just list a file to be autoloaded in their composer.json file that for example deletes your entire database, etc.
I think the point they're making is that they cannot (or rather, should not have to) protect against malicious vendors. In that sense, I tend to agree with them.
--
I feel it's relevant to provide OWASP's definition of a 'vulnerability' here:
"A vulnerability is a weakness in an application (frequently a broken or missing control) that enables an attack to succeed."
March 2021
I reply with a mini essay expressing my disagreement, but ultimately concede become I am not the security expert.
The reported vulnerability case is closed with no further action.
April 2022
Factoring in Laravel have stated their views on the issue, and not fixed it a year onward - I figure the 'type' of issue this would fall under is an Improvement, or Bug fix - which I would report as an issue to their GitHub repo.
Task scheduler does not escape shell arguments #42014
- Laravel Version: 8+
- PHP Version: 7.4+
- Database Driver & Version: *
Description:
Originally submitted this as a vulnerability report over a year ago, but it was dismissed due to "malicious package vendors being out of the control of the framework." [paraphrased] Reporting it as a bug now, instead of security issue.
Task Scheduler unnecessarily allows 'command injection', there is no command argument escaping in the CommandBuilder
I was close to submitting a PR/fix https://github.com/VeryStrongFingers/framework/commit/2b8aa5ea57a59f8a167583ab617f4283443ad10e (haven't confirmed if it's fixed on Windows), but unfortunately lost interest due to perceived shared concern was lacking.
Steps To Reproduce:
https://github.com/VeryStrongFingers/laravel-shell-escape-poc has a detailed explanation and demo
I made the mistake of listing the affected Laravel version as "Laravel 8+"
tl;dr response
Unfortunately we don't support this version anymore.
????
April, 1 day later
Copy pasting the same issue content, but explicitly included "Laravel 9" this time.
https://github.com/laravel/framework/issues/42037
response:
I don't see any big issues here. I don't see how this could lead to security issues. Please also do not publicly submit security issues, see our readme.
Let's disregard the contradictory statements.
In Closing
After 3 attempts of reporting what I believe is an unnecessarily existing attack vector existing within Laravel's control, I will concede;
However, genuinely curious to hear the thoughts of you lovely external unbiased readers perspectives.
Have I been pushing a non-issue?
or are Command escape vulnerabilities not as easily recognised because this is a web framework?'
Will this remain forever as is because changing it could be perceived as acknowledging it as a security issue?
P.S. In case you missed it, vector details are provided in the README of https://github.com/VeryStrongFingers/laravel-shell-escape-poc
Top comments (2)
Hello !
I love your posts. That describe perfectly what I feel since I started coding with Laravel.
Do you have time to continue your 100-reasons-why-Laravel-sucks-odyssey ?
I don’t work much with PHP (nor Laravel) much these days which is why it’s slower down a bit, but I do intend on writing more soon. 🌚