bug #40330 [SecurityBundle] Empty line starting with dash under "access_control" causes all rules to be skipped (monteiro)

This PR was squashed before being merged into the 4.4 branch.

Discussion
----------

[SecurityBundle] Empty line starting with dash under "access_control" causes all rules to be skipped

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets       | Fix #40235 ... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License       | MIT

When the IDE by mistake puts an empty line in `access_control` in security.yaml there is no warning that we have an empty row, making the rest of routes defined, to be ignored and possible to be accessed by anyone that can authenticate no matter the role.

# How to reproduce the issue

- git clone git@github.com:monteiro/symfony-issue-40235.git
- composer install
- symfony server:start
- open 127.0.0.1:8000/admin with username: "john_user" and password "123456"
- Since that user has only ROLE_USER should not be able to access the route... but because there is an empty line in "access_control" in `security.yaml`, "by mistake" it is possible to access the protected `ROLE_ADMIN` route.

Commits
-------

ee26ce5987 [SecurityBundle] Empty line starting with dash under "access_control" causes all rules to be skipped
This commit is contained in:
Alexander M. Turek 2021-04-12 16:25:43 +02:00
commit e1f2e81306
2 changed files with 56 additions and 0 deletions

View File

@ -191,6 +191,12 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
$attributes[] = $this->createExpression($container, $access['allow_if']);
}
$emptyAccess = 0 === \count(array_filter($access));
if ($emptyAccess) {
throw new InvalidConfigurationException('One or more access control items are empty. Did you accidentally add lines only containing a "-" under "security.access_control"?');
}
$container->getDefinition('security.access_map')
->addMethodCall('add', [$matcher, $attributes, $access['requires_channel']]);
}

View File

@ -415,6 +415,56 @@ class SecurityExtensionTest extends TestCase
$this->assertEquals(new Reference('security.user.provider.concrete.second'), $container->getDefinition('security.authentication.switchuser_listener.foobar')->getArgument(1));
}
public function testInvalidAccessControlWithEmptyRow()
{
$container = $this->getRawContainer();
$container->loadFromExtension('security', [
'providers' => [
'default' => ['id' => 'foo'],
],
'firewalls' => [
'some_firewall' => [
'pattern' => '/.*',
'http_basic' => [],
],
],
'access_control' => [
[],
['path' => '/admin', 'roles' => 'ROLE_ADMIN'],
],
]);
$this->expectException(InvalidConfigurationException::class);
$this->expectExceptionMessage('One or more access control items are empty. Did you accidentally add lines only containing a "-" under "security.access_control"?');
$container->compile();
}
public function testValidAccessControlWithEmptyRow()
{
$container = $this->getRawContainer();
$container->loadFromExtension('security', [
'providers' => [
'default' => ['id' => 'foo'],
],
'firewalls' => [
'some_firewall' => [
'pattern' => '/.*',
'http_basic' => [],
],
],
'access_control' => [
['path' => '^/login'],
['path' => '^/', 'roles' => 'ROLE_USER'],
],
]);
$container->compile();
$this->assertTrue(true, 'extension throws an InvalidConfigurationException if there is one more more empty access control items');
}
protected function getRawContainer()
{
$container = new ContainerBuilder();