1

I have deployed a project using Capifony and getting an error upon a folder creation. The following code is inside a service. Could be inside a controller, too, doesn't matter.

$dir = $kernelDir . '/../web/newfolder/';// kerneldir is %kernel.root_dir%
$fs=new Filesystem();
$fs->mkdir($dir);

This will try to create a new folder inside web, but will fail.

The problem is the permissions for the web folder:

drwxrwxr-x 11 deploy deploy    4096 Feb 15 14:52 web

deploy is the user that did the deployment on the web server. The web server's user is the default one www-data, but isn't there a problem if I set www-data as the owner of the web directory? That means that everyone can modify everything in web.

I have also tried to create a folder in web/uploads folder and that fails, too.

How can I have www-data create a folder in a folder it doesn't have access to without damaging the security? Do I need to add one of the users to a new group or something? Do I need to modify my deploy file? Do I need to use www-data as the deploy user, instead? What is the way to solve this problem?

Here is also my Capifony file if it helps (I've replaced the domain with a string. The deployment works):

set :application, "test"
set :domain,      "domain"

set :deploy_to,   "/var/www/html/"
set :app_path,    "app"

set :repository,  "file:///var/www/testproj" 
set :scm,         :git
set :branch, "master"

set :ssh_options, {
  forward_agent: true,
  paranoid: true,
  keys: "~/.ssh/id_rsa"
}

set :deploy_via, :rsync_with_remote_cache
default_run_options[:pty] = true

set :user, "deploy"    
set :model_manager, "doctrine"


role :web,        domain                         # Your HTTP server, Apache/etc
role :app,        domain, :primary => true       # This may be the same as your `Web` server

set  :keep_releases,  3

set :use_sudo, false


set :clear_controllers, false
set :shared_files,      ["app/config/parameters.yml"]
set :shared_children,     [app_path + "/logs", web_path + "/uploads", "vendor"]



set :writable_dirs,     ["app/cache", "app/logs"]
set :webserver_user,    "www-data"
set :permission_method, :acl
set :use_set_permissions, true

# Be more verbose by uncommenting the following line
logger.level = Logger::MAX_LEVEL

set :assets_install,                true
set :dump_assetic_assets,     true
set :use_composer,              true
set :composer_options,  "--dev --verbose --prefer-dist --optimize-autoloader --no-progress"

I was thinking something like:

set :shared_children,     [app_path + "/logs", web_path + "/uploads", "vendor",web_path + "/newfolder"]


set :writable_dirs,     ["app/cache", "app/logs", web_path + "/newfolder", web_path + "/medics"]

And this will result in

drwxrwxrwx+ 4 deploy deploy   4096 Feb 15 15:36 cache

lrwxrwxrwx  1 deploy deploy     36 Feb 15 15:35 logs -> /var/www/html/testproj/shared/app/logs

lrwxrwxrwx  1 deploy deploy     38 Feb 15 15:35 newfolder-> /var/www/html/testproj/shared/web/newfolder

lrwxrwxrwx  1 deploy deploy     39 Feb 15 15:35 uploads -> /var/www/html/testproj/shared/web/uploads

Is it ok if Capifony gives these permissions to these folders?

George Irimiciuc
  • 4,573
  • 8
  • 44
  • 88
  • Try to avoid making public directory writable unless you have really really **really** strong reasons to do so. – Alex Blex Feb 15 '16 at 14:30
  • Well, that's what I'm trying to avoid. The question is how? – George Irimiciuc Feb 15 '16 at 14:31
  • `$dir = $kernelDir . '/any_other_dir_outside_web/newfolder/'`. Create a dedicated dir for your stuff, and apply the same method as you use for cache directory: http://symfony.com/doc/current/book/installation.html#checking-symfony-application-configuration-and-setup – Alex Blex Feb 15 '16 at 14:35
  • I was thinking about that, but if later I want to put some folders elsewhere or decide to change the structure, I need to change permissions, too. It's funny because on windows+xampp this works out of the box. – George Irimiciuc Feb 15 '16 at 14:38
  • Please read the docs behind the link. It is a step-by-step guide how to setup permissions for cache and log directories. Follow the same steps for your custom dir. – Alex Blex Feb 15 '16 at 14:41
  • Capifony already does that automatically. Please see edited question at the bottom. Are permissions alright like so? – George Irimiciuc Feb 15 '16 at 14:44
  • No. Please read http://capifony.org/cookbook/set-permissions.html how to set permissions "automatically". And for the sake of your users, remove uploads from web directory. – Alex Blex Feb 15 '16 at 14:53
  • I've already read that and that's exactly what I do. What do you mean by for the sake of my users? The web directory is public, where do I store their uploaded images, like avatars? – George Irimiciuc Feb 15 '16 at 15:01

1 Answers1

0
  1. Create a directory under which you will create directories runtime, e.g. app/mydirs, and add it to the vcs history.

  2. Add the directory to your deployment config:

    set :shared_children,     [app_path + "/logs", web_path + "/uploads", "vendor", app_path + "/mydirs"]
    set :writable_dirs,     ["app/cache", "app/logs", "app/mydirs"]
    
  3. Change your code to use this directory:

    $dir = $kernelDir . '/mydirs/newfolder/';// kerneldir is %kernel.root_dir%
    $fs=new Filesystem();
    $fs->mkdir($dir);
    

Explanation what it does "automatically":

set :permission_method, :acl

Uses setfacl to set permissions. It does not change ownership of directories.
The permissions are being applied at deployment time, and affect only directories that already exist.

Security concerns about writable public directories:

Files uploaded by users should never be trusted. Uploading files to public directory unlock many possible vulnerabilities, and must be done with great care. In case of uploaded avatars, it can be resolved by processing images with GD or imagick before writing them down to the public directory.

Alex Blex
  • 34,704
  • 7
  • 48
  • 75
  • I'm using SonataMediaBundle which uses GD. However, it makes more sense to have a resource public than to serve it through a controller. It's just faster. I was doing the same as you but in the public folder. Was thinking there is maybe another way than this. – George Irimiciuc Feb 15 '16 at 16:34