Skip to content

[Security] add port in access_control #28061

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

Merged
merged 1 commit into from
Oct 10, 2018
Merged

[Security] add port in access_control #28061

merged 1 commit into from
Oct 10, 2018

Conversation

roukmoute
Copy link
Contributor

@roukmoute roukmoute commented Jul 25, 2018

Q A
Branch? master for features
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #26071
License MIT
Doc PR symfony/symfony-docs#10359

Add port in access_control

Please Squash this P.R.

* @param string|string[]|null $methods
* @param string|string[]|null $ips
* @param array $attributes
* @param string|string[]|null $schemes
*/
public function __construct(string $path = null, string $host = null, $methods = null, $ips = null, array $attributes = array(), $schemes = null)
public function __construct(string $path = null, string $host = null, $port = null, $methods = null, $ips = null, array $attributes = array(), $schemes = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a BC break, you should add the new arguments at the end of the list

*/
public function matchPort($port)
{
$this->port = (int) $port;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(int) null => 0 (in this case the value is not clear)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also use a type hint here.

@@ -167,6 +184,10 @@ public function matches(Request $request)
return false;
}

if (0 < $this->port && $request->getPort() !== $this->port) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to ignore null here

@javiereguiluz
Copy link
Member

@chalasr this looks like a useful feature for some people and I can't see any security issue if we introduce this change, but could you please review it? Thanks!

@chalasr chalasr changed the title Security add port [Security] add port in access_control Sep 18, 2018
* @param string|string[]|null $methods
* @param string|string[]|null $ips
* @param array $attributes
* @param string|string[]|null $schemes
*/
public function __construct(string $path = null, string $host = null, $methods = null, $ips = null, array $attributes = array(), $schemes = null)
public function __construct(string $path = null, string $host = null, $methods = null, $ips = null, array $attributes = array(), $schemes = null, $port = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be int $port = null

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, now we can use typehint in this version 👍

@@ -140,6 +140,7 @@ private function addAccessControlSection(ArrayNodeDefinition $rootNode)
->example('^/path to resource/')
->end()
->scalarNode('host')->defaultNull()->end()
->scalarNode('port')->defaultNull()->end()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably don't want to deal with strings here, should be an integerNode() to me

$methods = isset($firewall['methods']) ? $firewall['methods'] : array();
$matcher = $this->createRequestMatcher($container, $pattern, $host, $methods);
$matcher = $this->createRequestMatcher($container, $pattern, $host, $port, $methods);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$firewall['port'] ?? null, removing the assignment above

Copy link
Contributor Author

@roukmoute roukmoute Sep 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I do the same things for the rest (host, …) or is it must be in another P.R.?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would keep them unchanged to avoid conflicts when merging lower branches up to master

@@ -668,20 +670,20 @@ private function createExpression($container, $expression)
return $this->expressions[$id] = new Reference($id);
}

private function createRequestMatcher($container, $path = null, $host = null, $methods = array(), $ip = null, array $attributes = array())
private function createRequestMatcher($container, $path = null, $host = null, $port = null, $methods = array(), $ip = null, array $attributes = array())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int $port = null

*
* @param int|null $port The port number to connect to
*/
public function matchPort($port)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one should use int $port = null, the existing public methods of this class have been added before php scalar typehints and cannot be changed for BC

{
$portInt = (int) $port;

$this->port = is_numeric($port) || $port == $portInt ? $portInt : null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should just assign $this->port to $port (see my comment above)

*
* @param int|null $port The port number to connect to
*/
public function matchPort(int $port): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing = null :) (see tests)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove the return type also, we don't use void generally

@@ -5,6 +5,7 @@ CHANGELOG
-----

* added `getAcceptableFormats()` for reading acceptable formats based on Accept header
* added `port` property and `matchPort()` in RequestMatcher
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only the method is relevant here, the property is private

@@ -245,7 +245,7 @@ public function testAccess()

$rules = array();
foreach ($container->getDefinition('security.access_map')->getMethodCalls() as $call) {
if ('add' == $call[0]) {
if ('add' === $call[0]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one should be reverted

@@ -247,7 +248,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
$pattern = isset($firewall['pattern']) ? $firewall['pattern'] : null;
$host = isset($firewall['host']) ? $firewall['host'] : null;
$methods = isset($firewall['methods']) ? $firewall['methods'] : array();
$matcher = $this->createRequestMatcher($container, $pattern, $host, $methods);
$matcher = $this->createRequestMatcher($container, $pattern, $host, $firewall['port'] ?? null, $methods);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks for a port option on a firewall but it does not exist yet

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we add the option to firewalls (I think we should but it could be done in another PR, in this case null should be passed here) then it should be covered by tests and mentioned in the CHANGELOG as for access_controls

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I kept this and I do another P.R. for adding this options to firewall, or I remove all?
Does it finally make sense to put it on for the firewall?

Copy link
Member

@chalasr chalasr Sep 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the check can't be true, let's remove it (pass null) for now and discuss it separately.
All the existing access_control options are also available at the firewall level, I see no reason for not adding this one wrong, ip is not available for firewalls. let's discuss it elsewhere :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should pass null here, the option does not exist.

$httpRequest = $request = $request = Request::create('');
$httpsRequest = $request = $request = Request::create('', 'get', array(), array(), array(), array('HTTPS' => 'on'));
$httpRequest = Request::create('');
$httpsRequest = Request::create('', 'get', array(), array(), array(), array('HTTPS' => 'on'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please revert this :)

@@ -442,7 +442,7 @@ public function testCustomAccessDecisionManagerService()
*/
public function testAccessDecisionManagerServiceAndStrategyCannotBeUsedAtTheSameTime()
{
$container = $this->getContainer('access_decision_manager_service_and_strategy');
$this->getContainer('access_decision_manager_service_and_strategy');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to revert

@@ -5,6 +5,7 @@ CHANGELOG
-----

* added `getAcceptableFormats()` for reading acceptable formats based on Accept header
* added `port` property
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's the inverse actually :) we need to mention the addition of RequestMatcher::matchPort(), not the private port property as it's not exposed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oups sorry…

@chalasr
Copy link
Member

chalasr commented Sep 30, 2018

@roukmoute What's the state of this PR?
I see that you finally added the port option to firewalls as well, no objection from me but it should be covered by tests as for access controls.
Please tell us when it's ready to review or if you need some help :)

@@ -180,6 +181,7 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto
$firewallNodeBuilder
->scalarNode('pattern')->end()
->scalarNode('host')->end()
->integerNode('port')->defaultNull()->end()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should remove this option, we want it only for the access control

@@ -275,7 +276,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
$pattern = isset($firewall['pattern']) ? $firewall['pattern'] : null;
$host = isset($firewall['host']) ? $firewall['host'] : null;
$methods = isset($firewall['methods']) ? $firewall['methods'] : array();
$matcher = $this->createRequestMatcher($container, $pattern, $host, $methods);
$matcher = $this->createRequestMatcher($container, $pattern, $host, null, $methods);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the port always null here? Shouldn't we use the configured value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it is :)
#28061 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks :)

Copy link
Member

@fabpot fabpot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really get the use case, but ok.

@fabpot
Copy link
Member

fabpot commented Oct 10, 2018

Thank you @roukmoute.

@fabpot fabpot merged commit 6413dcb into symfony:master Oct 10, 2018
fabpot added a commit that referenced this pull request Oct 10, 2018
This PR was squashed before being merged into the 4.2-dev branch (closes #28061).

Discussion
----------

[Security] add port in access_control

| Q             | A
| ------------- | ---
| Branch?       | master for features
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #26071
| License       | MIT
| Doc PR        | symfony/symfony-docs#10359

Add port in access_control

__Please Squash this P.R.__

Commits
-------

6413dcb [Security] add port in access_control
@roukmoute roukmoute deleted the security_add_port branch October 10, 2018 12:14
@nicolas-grekas nicolas-grekas modified the milestones: next, 4.2 Nov 1, 2018
This was referenced Nov 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants