4

I'm working with a fresh PHP Laravel framework installation, and I've noticed that the ownership of all files and folders within the public directory has been recursively changed to the web server user, www-data. Here's an overview of the public folder's files and ownership:

vagrant@dev:/laravel-app/public$ ls -al
total 20
drwxr-xr-x  2 www-data www-data 4096 Aug 10 09:19 .
drwxr-xr-x 12 www-data www-data 4096 Sep 15 10:39 ..
-rw-r--r--  1 www-data www-data    0 Aug 10 09:19 favicon.ico
-rw-r--r--  1 www-data www-data  603 Aug 10 09:19 .htaccess
-rw-r--r--  1 www-data www-data 1710 Aug 10 09:19 index.php
-rw-r--r--  1 www-data www-data   24 Aug 10 09:19 robots.txt

Do I need to remove "writable" permissions to make application file structure more secure?

16
  • This has already been asked two days ago and has an answer, has something changed since then? Commented Sep 18, 2023 at 7:14
  • 3
    The correct permission is 755 (drwxr-xr-x) for directories and 644 (-rw-r--r--) for files Commented Sep 18, 2023 at 7:18
  • 2
    It's not a suggestion, it's the standard permission accross the php ecosystem, everywhere you look it's always 755/644, sometimes 750/640 but that's it. I guess that if nobody does remove the w permission, it's because it does not add security, if a user has already access to www-data you have a bigger problem i guess Commented Sep 18, 2023 at 7:27
  • 2
    @Lk77 that sounds like a bad design. Read and execute permission should be sufficient. Source code should not be writable by the webserver. There is rarely, if ever, any good reason for that. Commented Sep 18, 2023 at 8:56
  • 1
    @JasonOlson well, enabling logging and caching wouldn't mean that the source code needs to be writable, it only requires the log file and the cache to be writeable. And as for wordpress...well I can see your point, however Wordpress is also well known as one of the platforms which most commonly falls victim to various forms of hacking and code injection attacks...it's hard to imagine that a setup where the source code is overwritable by the webserver account is not contributing to that to some extent. Commented Sep 21, 2023 at 21:41

3 Answers 3

8
+100

No. Well, sort of. Sometimes it can't be helped. But you're using Laravel, so the answer is no.


Why we don't want to allow source code files to be writable:

In general, the files shouldn't be writable by the webserver, because it significantly lowers both your attack surface, and the maximum damage a hacker can inflict. For example, even if a user somehow exploits a security flaw in one of your plugins to have the ability to upload files, they can't upload a replacement index.php with a keylogger or javascript-based bitcoin miner inside, if the webserver itself doesn't write access.


Why we might want to allow source code files to be writable anyway:

HOWEVER. Some CMSs get annoyed if they don't have write access. For example, Wordpress has an extremely user-friendly Install updates button that won't work if the webserver doesn't have write access (Because it can't update the files without write access), and in such a situation, you'd need to upload updates via FTP (Or via cloning stage, or however your devops runs).

Whereas, for example, Drupal uses a command-line tool called composer to install updates, but because composer is run from the command line via the ssh user, the webserver itself doesn't need write access.

(Wordpress subscribes to the idea that we can't always expect every web admin to know how to SSH into the server, so it just accepts the increased security risk for the sake of user-friendly updates.)


Exceptions:

That said, many CMSs, like Wordpress or Drupal, allow admins to upload files (E.g. images or pdfs). For those CMSs, the server SHOULD have a writable directory called uploads, that the server can modify.

Sometimes they'll also need to be able to write to other folders, like caching plugins may have a directory they use.

Each individual type of website will have slightly different directories, so generally, you can ask google what the correct permissions for your website ought to be.


Bottom line, for Laravel:

Laravel runs updates via composer, which means YOU will be running updates. So no, your webserver shouldn't need write access. The correct permissions are:

User: YourUsername Group: www-data

Directories: 2755 Files: 644

The cache directory and the storage directory SHOULD be writable by the server, however, so we'll change them to 2775 and 664...

This ought to do it:

cd /path/to/laravel-project/
sudo chown -r YourUsername:www-data .
sudo find ./ -type f -exec chmod 644 {} \;    
sudo find ./  -type d -exec chmod 2755 {} \;

sudo chmod -R g+w storage
sudo chmod -R g+w bootstrap/cache
Sign up to request clarification or add additional context in comments.

3 Comments

Why exactly does it require execute permissions? This seems needless and permissive for PHP. Additionally, this approach presumes (without stating/asking?) if they are doing file-based logging (Laravel default), permitting uploads, or any number of things where there is intentional local disk access from within the application. Of the main modules of Laravel is a File System component, which while isn't exclusive of local storage, certainly illustrates the point that many sites require storage systems.
@JasonOlson Why exactly does it require execute permissions Directories need execute permissions for them to work properly, but PHP doesn't... which is why we didn't give execute to PHP. (644 doesn't allow execute.) --- RE: The rest - Yes, these settings are for a typical setup. I suppose it's POSSIBLE that e.g. OP doesn't want to allow admins to add pictures to the websites, but most websites look better with pictures, which means they need to permit file uploads or sit next to the content editor at all times. (Unless everything is done in STAGE, I suppose.)
@JasonOlson If you feel the need to disable the features that you don't want, and you want to granulate your permissions further, I suppose you COULD use laravel.com/docs/10.x/structure to look through each directory, and decide if you need it. But many developers aren't sure EXACTLY which directories they need, so settings of "Allow Laravel to write to the directories it wants to, and block everything that Laravel doesn't want to write to" is standard practice.
0

The storage and bootstrap/cache directories need to be writable by Laravel. We'll set their permissions to 0775, giving the owner and group read, write, and execute permissions, while others can only read and execute. Also If You session, cache driver are file and filesystem driver are like s3 then you don't need 755 permission for storage also only you need to give permission for storage/framework/view.

Comments

-1

TLDR; Removing write permissions for the www-data user in Laravel is not recommended. It provides no practical security benefit, as Laravel relies on write access for essential tasks like logging, caching, and accepting user uploads. While a principle of least access approach can be taken, it's non-standard and may lead to issues with future code changes. Concerns about malicious users gaining access to www-data should prompt broader security considerations, and for multiple websites on one server, it's better to isolate user accounts.

Allowing the www-data user to have write access to your files serves a vital purpose in Laravel. It enables necessary functions such as generating log and cache files, compiling Blade templates, managing file uploads, and facilitating file generation, like creating and storing PDF files locally. Depending on your deployment method, additional file maintenance tasks may also require write access.

It's worth noting that Laravel documentation explicitly states: "Laravel may require some permissions to be configured: folders within and require write access by the web server."

While you can theoretically adopt a principle of least access approach and meticulously assign write permissions only to directories and files expected to be modified, this approach deviates from the standard setup. Consequently, future changes to your code, like adding a component requiring write access, may lead to unexpected issues, potentially causing code failures due to file permissions errors.

Concerns about malicious users gaining access to the www-data user and executing unsanitized code should prompt a comprehensive review of server security practices. Granting write access is just one aspect, and there are broader vulnerabilities to address. Furthermore, since the user is highly restricted and does not allow interactive logins, the primary attack vector is through your code, and addressing security concerns should encompass more than just file writing permissions.

An important exception arises when hosting multiple websites or virtual hosts on the same server. In this scenario, it is crucial to isolate user accounts for each website to prevent one website's code from accessing or modifying another's. Isolating user accounts, however, should not be framed as merely removing write access; it involves setting up separate user environments for each website to maintain security and independence.

2 Comments

The irony of your statement is that if you disabled write access you would fundamentally break the built in automatic update features of Woocommerce. So by that fact you would promote not having 3rd party plugins able to update automatically. Furthermore, most of the major woo breaches have leaked data regardless of write access to the path.
@JasonOlson: Actually, (also WordPress) automatic updates are not secure, so the irony is within the statement of your statement. But that's a longer discussion likely out of scope here, so just FYI and no harsh feelings, we can't solve all problems at once for the software we introduce, only at their beginning.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.