Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate relative path for cached images: CacheManager::generateUrl() #1050

Closed
nmuntyanov opened this issue Feb 7, 2018 · 7 comments
Closed
Labels
Attn: Minor This issue or PR is a minor problem or minor change. Level: New Feature 🆕 This item involves the introduction of new functionality. State: Confirmed This item has been confirmed by maintainers as legitimate. Type: Configuration This item pertains to configuration of this project. Type: Source Code This item pertains to the source code of this project. Type: Support This item pertains to support for this project.

Comments

@nmuntyanov
Copy link

Q A
Bug Report? no
Feature Request? yes
BC Break Report? no
RFC? no
Imagine Bundle Version 1.7

Hi guys!
I'm using Let's encrypt + Nginx proxy docker images to secure my application.
But because of this solution - Symfony can't resolve request scheme (Http or Https).
And CacheManager::generateUrl() generates absolute image path with http scheme by default,
so browser says: Your connection is not fully secured.

I think it's a good idea to add ability into CacheManager::generateUrl() to generate relative paths

@robfrawley
Copy link
Collaborator

NOTE: New features should be targeted at the 2.0 branch, as the 1.0 branch will only be getting bug and security fixes moving forward. Please amend your issue to target only the 2.0 branch. Similarly, any PRs you may submit should target the 2.0 branch as well.


Regarding your described issue, there are solutions available that do not require turning the resolved absolute paths into relative paths. Others have described similar issues in the past and they have all been solved without adding the ability to generate relative paths, but if you would still like such a feature, I'd be happy to review a PR from you enabling a configuration option that does such.

Pending that, there are currently two different solutions (that I know of) that will allow you to create absolute paths with the desired protocol.

1. Configuring Nginx

THE FIRST SOLUTION ADDS A FASTCGI NGINX CONFIGURATION OPTION.

You can easily "fake" the protocol of the request when handing it over to the FastCGI component (used to communicate with PHPFPM). This kind of setup is important when you are behind a proxy, or for a number of different setups that result in Symfony-generated absolute URLs being the wrong protocol (HTTP when they should be HTTPS). To force the enabling of HTTPS, add the following configuration line within your framework location block (which itself is in the server block):

fastcgi_param HTTPS on;

To provide some additional context as to where the fastcgi_param HTTPS on configuration option should go, the following provides a complete, working Nginx example configured for Symfony ^2.0|^3.0:

server {

  listen      80;
  listen      443 ssl http2;
  server_name site.com;
  root        /web/site-com/current/web;

  # setup logging behavior and disable symlinks
  log_not_found    off;
  log_subrequest   on;
  access_log       /var/log/nginx/access_site-com.log combined buffer=256k flush=10m;
  error_log        /var/log/nginx/errors_site-com.log error;
  disable_symlinks on;

  # define ssl protocol behavior and setup certificate
  ssl_protocols             TLSv1.2 TLSv1.1;
  ssl_ciphers               AES256+EECDH:AES256+EDH:!aNULL;
  ssl_ecdh_curve            secp384r1;
  ssl_dhparam               /etc/ssl/nginx/_ephemeral-dh.pem;
  ssl_session_cache         shared:SSL:10m;
  ssl_session_timeout       10m;
  ssl_stapling              on;
  ssl_stapling_verify       on;
  ssl_prefer_server_ciphers on;
  ssl_certificate           /etc/letsencrypt/live/site.com/fullchain.pem;
  ssl_certificate_key       /etc/letsencrypt/live/site.com/privkey.pem;
  ssl_trusted_certificate   /etc/letsencrypt/live/site.com/cert.pem;

  # enable strict transport security (optionaL)
  add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
  add_header X-Frame-Options DENY;
  add_header X-Content-Type-Options nosniff;

  # redirect all non-https connections to https
  if ($https != "on") {
    return 301 https://$host$request_uri;
  }

  # disable serving any hidden file (dot-file)   
  location ~ /\. {
    error_log      off;
    access_log     off;
    log_not_found  off;
    log_subrequest off;

    satisfy all;
    deny    all;
  }

  # disable serving any temporary editor files
  location ~ ~$ {
    error_log      off;
    access_log     off;
    log_not_found  off;
    log_subrequest off;

    satisfy all;
    deny    all;
  }

  # attempt to load favicon from disk, but provide empty gif as favicon if non exists
  location = /favicon.png { try_files /favicon.png @empty_gif; }
  location = /favicon.ico { try_files /favicon.ico @empty_gif; }
  location @empty_gif     { empty_gif; }

  # attempt to load the url from disk; fall-back to the framework if file does not exist
  location / {
    try_files $uri $uri/ @rewrite_framework;
  }

  # defines the framework handler
  location @rewrite_framework {
    # this file lives at the root of /etc/nginx and may be called something else, like "fastcgi_params"
    include                 fastcgi.conf
    fastcgi_read_timeout    1m;
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    # this must be set according to how you've configured PHPFPM in `/etc/php/7.x/fpm/pool.d/www.conf`
    fastcgi_pass            127.0.0.1:9090;
    # change from "app_prod.php" to "app_dev.php" to change between prod/dev environments
    fastcgi_param           SCRIPT_FILENAME $document_root/app_prod.php;
    # change from "on" to "off" to disable forced (faked) SSL
    fastcgi_param           HTTPS on;
  }

}

2. Configuring Symfony

THE SECOND SOLUTION ADDS ACCESS CONTROL RULES TO THE SYMFONY CONFIGURATION.

The security.access_control option allows you to define access control rules within the security component of the Symfony configuration. Generally, this section is used as part of a firewall configuration, but it can also be used to affect different behaviors.

In the context of your issue, we can set the requires_channel option to https to require the HTTPS protocol. This doesn't just affect incoming requests; it also changed the behavior of the route generator (which is what this bundle uses to create its absolute paths).

As an example, suppose your assets are cached at "https://site.com/your/custom/cache/path" and you would like their paths to use the HTTPS protocol. You would add the following configuration entry under the security.access_control option:

- { path: ^/your/custom/cache/path, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }

If you also want to force the resolver routes used by this bundle (see: Resources/config/routing.yaml) to also use the HTTPS protocol, add the following under the security.access_control option:

- { path: ^/media/cache/resolve, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }

Combining the above two rules and putting everything together, you would want to add the following to your app/config/config.yml configuration file:

security:
    access_control:
        - { path: ^/your/custom/cache/path, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
        - { path: ^/media/cache/resolve, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }

@robfrawley robfrawley added Level: New Feature 🆕 This item involves the introduction of new functionality. Type: Support This item pertains to support for this project. State: Confirmed This item has been confirmed by maintainers as legitimate. Type: Configuration This item pertains to configuration of this project. Type: Source Code This item pertains to the source code of this project. Attn: Minor This issue or PR is a minor problem or minor change. labels Feb 10, 2018
@nmuntyanov
Copy link
Author

Thank you for response.
I've used first solution and it works. But I think it's not good practice.
So i've decided to make a pull request ))

@OLTC-fperrin
Copy link

Hello,
Do you have any news on this ? Any chance we'll get this as a configuration option in the near future ?
Thank you,

@nmuntyanov
Copy link
Author

@LTC-fperrin I've made a pull request:
#1059
But I don't know when guys will accept it

@dbu
Copy link
Member

dbu commented Oct 6, 2021

see #1233

@dbu dbu closed this as completed Oct 6, 2021
@bellu
Copy link

bellu commented Dec 3, 2021

I tried to use the configuration suggested above, but it's not working:
- { path: ^/media/cache/resolve, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }

Is there a way to generate a relative URL?
I saw that CacheManager->generateUrl could accept UrlGeneratorInterface::RELATIVE_PATH?
Should i override this class?

@dbu
Copy link
Member

dbu commented Dec 3, 2021

somebody picket up the topic of relative url in #1233 - if you have time to look into that pull request and maybe wrap it up, that would be great.

we are currently in the process of preparing a version 3 - if you target the 3.x branch the changes would be allowed to do BC breaks if necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Attn: Minor This issue or PR is a minor problem or minor change. Level: New Feature 🆕 This item involves the introduction of new functionality. State: Confirmed This item has been confirmed by maintainers as legitimate. Type: Configuration This item pertains to configuration of this project. Type: Source Code This item pertains to the source code of this project. Type: Support This item pertains to support for this project.
Projects
None yet
Development

No branches or pull requests

5 participants