Skip to content

run-time json encoded environment variable string does not work in security.yml #27683

Closed
@farazive

Description

@farazive

Symfony Version 3.4, PHP 7, Apache 2.4

What we are trying to do?

We are trying to restrict a route (/anon/foo) to a set of IPs via Symfony's security access_control. The IPs will be read as a runtime environment variable from Apache. To group the IPs together, we will use a json encoded string containing multiple IPs and then have symfony decode them using Symfony's Json environment variable processor.

STEP 1:
Set up an environment variable as a json encoded string in Apache as below:

<VirtualHost *:443>
    ...
    SetEnv whitelisted_ip "[\"127.0.0.1\", \"127.0.0.2\"]
</VirtualHost>

STEP 2:
Set up your application's parameter.yml to decode that environment variable as below:

    whitelisted_ips_for_access_control: '%env(json:whitelisted_ip)%'

Step 3:
Observe the parameter in \Symfony\Component\HttpKernel\Kernel::handle after $this->boot(); The values have been decoded into an array perfectly.

        $this->boot();
        $foo = $this->getContainer()->getParameter( 'whitelisted_ips_for_access_control');

Step 4:
Set security.yml so that the route is only accessibly via certain IPs as below:

security:
...
    firewalls:
        anon_area:
            pattern: ^/anon
            anonymous: true
...
    access_control:
        - { path: ^/anon/foo, roles: IS_AUTHENTICATED_ANONYMOUSLY, ips: '%whitelisted_ips_for_access_control%' }
        - { path: ^/anon/foo, roles: ROLE_NO_ACCESS}

Step 5:
Clear cache and observe the container file var/cache/test/ContainerP59owun/getSecurity_AccessMapService.php. Notice that the variable has been passed to RequestMatcher as an array array(0 => $this->getEnv('json:whitelisted_ip'))

<?php

use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;

// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
// Returns the private 'security.access_map' shared service.

$this->services['security.access_map'] = $instance = new \Symfony\Component\Security\Http\AccessMap();

$a = new \Symfony\Component\HttpFoundation\RequestMatcher('^/anon/foo');

$instance->add(new \Symfony\Component\HttpFoundation\RequestMatcher('^/anon/foo', NULL, array(), array(0 => $this->getEnv('json:whitelisted_ip'))), array(0 => 'IS_AUTHENTICATED_ANONYMOUSLY'), NULL);

Step 6:
Go back to your application's parameters.yml that you changed in Step 2. Now change that parameter as below:

    whitelisted_ips_for_access_control: ["127.0.01", "127.0.02"]

Step 7:
Clear cache again and observe the same container file Tests/_app/var/cache/test/ContainerAjyqbl9/getSecurity_AccessMapService.php

<?php

use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;

$this->services['security.access_map'] = $instance = new \Symfony\Component\Security\Http\AccessMap();

$a = new \Symfony\Component\HttpFoundation\RequestMatcher('^/anon/foo');

$instance->add(new \Symfony\Component\HttpFoundation\RequestMatcher('^/anon/foo', NULL, array(), $this->parameters['whitelisted_ips_for_access_control']), array(0 => 'IS_AUTHENTICATED_ANONYMOUSLY'), NULL);

Step 8:
Compare the following two lines from Step 7 and Step 5

with parameter set as whitelisted_ips_for_access_control: '%env(json:whitelisted_ip)%'

$instance->add(new \Symfony\Component\HttpFoundation\RequestMatcher('^/anon/foo', NULL, array(), array(0 => $this->getEnv('json:whitelisted_ip'))), array(0 => 'IS_AUTHENTICATED_ANONYMOUSLY'), NULL);

with parameter set as whitelisted_ips_for_access_control: ["127.0.01", "127.0.02"]

$instance->add(new \Symfony\Component\HttpFoundation\RequestMatcher('^/anon/foo', NULL, array(), $this->parameters['whitelisted_ips_for_access_control']), array(0 => 'IS_AUTHENTICATED_ANONYMOUSLY'), NULL);

When the parameter is being read at runtime, a ContextErrorException is thrown at vendor\symfony\symfony\src\Symfony\Component\HttpFoundation\IpUtils.php (line 66) since the run time environment variable was wrapped in an array rather than be passed directly.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions