Skip to content

Commit

Permalink
[#4606] Updating thanks to comments from everyone!
Browse files Browse the repository at this point in the history
  • Loading branch information
weaverryan committed Dec 31, 2014
1 parent d9a9310 commit 95d6a7d
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 49 deletions.
29 changes: 16 additions & 13 deletions components/security/secure-tools.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
Securely Comparing Strings and Generating Random Numbers
========================================================

.. versionadded:: 2.2
The ``StringUtils`` and ``SecureRandom`` classes were introduced in Symfony
2.2

The Symfony Security component comes with a collection of nice utilities related
to security. These utilities are used by Symfony, but you should also use
them if you want to solve the problem they address.
The Symfony Security component comes with a collection of nice utilities
related to security. These utilities are used by Symfony, but you should
also use them if you want to solve the problem they address.

Comparing Strings
~~~~~~~~~~~~~~~~~
Expand All @@ -22,10 +18,15 @@ algorithm; you can use the same strategy in your own code thanks to the

use Symfony\Component\Security\Core\Util\StringUtils;

// is password1 equals to password2?
$bool = StringUtils::equals($password1, $password2);
// is some known string (e.g. password) equal to some user input?
$bool = StringUtils::equals($knownString, $userInput);

.. caution::

To avoid timing attacks, the known string must be the first argument
and the user-entered string the second.

Generating a secure random Number
Generating a Secure random Number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Whenever you need to generate a secure random number, you are highly
Expand All @@ -39,13 +40,15 @@ encouraged to use the Symfony

The
:method:`Symfony\\Component\\Security\\Core\\Util\\SecureRandom::nextBytes`
methods returns a random string composed of the number of characters passed as
method returns a random string composed of the number of characters passed as
an argument (10 in the above example).

The SecureRandom class works better when OpenSSL is installed but when it's
The SecureRandom class works better when OpenSSL is installed. But when it's
not available, it falls back to an internal algorithm, which needs a seed file
to work correctly. Just pass a file name to enable it::

use Symfony\Component\Security\Core\Util\SecureRandom;

$generator = new SecureRandom('/some/path/to/store/the/seed.txt');
$random = $generator->nextBytes(10);

Expand All @@ -54,4 +57,4 @@ to work correctly. Just pass a file name to enable it::
If you're using the Symfony Framework, you can access a secure random
instance directly from the container: its name is ``security.secure_random``.

.. _`Timing attack`: http://en.wikipedia.org/wiki/Timing_attack
.. _`Timing attack`: http://en.wikipedia.org/wiki/Timing_attack
52 changes: 22 additions & 30 deletions cookbook/security/access_control.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
How does the Security access_control Work?
How Does the Security access_control Work?
==========================================

For each incoming request, Symfony checks each ``access_control`` entry
Expand Down Expand Up @@ -150,33 +150,24 @@ options:

.. _book-security-securing-ip:

Securing by IP
--------------
Matching access_control By IP
-----------------------------

Certain situations may arise when you may need to restrict access to a given
path based on IP. This is particularly relevant in the case of
:ref:`Edge Side Includes <edge-side-includes>` (ESI), for example. When ESI is
enabled, it's recommended to secure access to ESI URLs. Indeed, some ESI may
contain some private content like the current logged in user's information. To
prevent any direct access to these resources from a web browser (by guessing the
ESI URL pattern), the ESI route **must** be secured to be only visible from
the trusted reverse proxy cache.

.. versionadded:: 2.3
Version 2.3 allows multiple IP addresses in a single rule with the ``ips: [a, b]``
construct. Prior to 2.3, users should create one rule per IP address to match and
use the ``ip`` key instead of ``ips``.
Certain situations may arise when you need to have an ``access_control``
entry that *only* matches requests coming from some IP address or range.
For example, this *could* be used to deny access to a URL pattern to all
requests *except* those from a trusted, internal server.

.. caution::

As you'll read in the explanation below the example, the ``ip`` option
does not restrict to a specific IP address. Instead, using the ``ip``
As you'll read in the explanation below the example, the ``ips`` option
does not restrict to a specific IP address. Instead, using the ``ips``
key means that the ``access_control`` entry will only match this IP address,
and users accessing it from a different IP address will continue down
the ``access_control`` list.

Here is an example of how you might secure all ESI routes that start with a
given prefix, ``/esi``, from outside access:
Here is an example of how you configure some example ``/internal*`` URL
pattern so that it is only accessible by requests from the local server itself:

.. configuration-block::

Expand All @@ -186,8 +177,9 @@ given prefix, ``/esi``, from outside access:
security:
# ...
access_control:
- { path: ^/esi, roles: IS_AUTHENTICATED_ANONYMOUSLY, ips: [127.0.0.1, ::1] }
- { path: ^/esi, roles: ROLE_NO_ACCESS }
#
- { path: ^/internal, roles: IS_AUTHENTICATED_ANONYMOUSLY, ips: [127.0.0.1, ::1] }
- { path: ^/internal, roles: ROLE_NO_ACCESS }
.. code-block:: xml
Expand Down Expand Up @@ -227,19 +219,19 @@ given prefix, ``/esi``, from outside access:
),
));
Here is how it works when the path is ``/esi/something`` coming from the
``10.0.0.1`` IP:
Here is how it works when the path is ``/internal/something`` coming from
the external IP address ``10.0.0.1``:

* The first access control rule is ignored as the ``path`` matches but the
``ip`` does not match either of the IPs listed;
IP address does not match either of the IPs listed;

* The second access control rule is enabled (the only restriction being the
``path`` and it matches): as the user cannot have the ``ROLE_NO_ACCESS``
role as it's not defined, access is denied (the ``ROLE_NO_ACCESS`` role can
be anything that does not match an existing role, it just serves as a trick
to always deny access).
``path``) and so it matches. If you make sure that no users ever have
``ROLE_NO_ACCESS``, then access is denied (``ROLE_NO_ACCESS`` can be anything
that does not match an existing role, it just serves as a trick to always
deny access).

Now, if the same request comes from ``127.0.0.1`` or ``::1`` (the IPv6 loopback
But if the same request comes from ``127.0.0.1`` or ``::1`` (the IPv6 loopback
address):

* Now, the first access control rule is enabled as both the ``path`` and the
Expand Down
12 changes: 7 additions & 5 deletions cookbook/security/form_login_setup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ How to Build a Traditional Login Form
.. tip::

If you need a login form and are storing users in some sort of a database,
then see you should consider using `FOSUserBundle`_, which helps you
build your ``User`` object and gives you many routes and controllers
for common tasks like login, registration and forgot password.
then you should consider using `FOSUserBundle`_, which helps you build
your ``User`` object and gives you many routes and controllers for common
tasks like login, registration and forgot password.

In this entry, you'll build a traditional login form. Of course, when the
user logs in, you can load your users from anywhere - like the database.
Expand Down Expand Up @@ -69,7 +69,9 @@ First, enable form login under your firewall:
.. tip::

The ``login_path`` and ``check_path`` can also be route names.
The ``login_path`` and ``check_path`` can also be route names (but cannot
have mandatory wildcards - e.g. ``/login/{foo}`` where ``foo`` has no
default value).

Now, when the security system initiates the authentication process, it will
redirect the user to the login form ``/login``. Implementing this login form
Expand Down Expand Up @@ -99,7 +101,6 @@ under your ``form_login`` configuration (``/login`` and ``/login_check``):
// src/AppBundle/Controller/SecurityController.php
// ...
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class SecurityController extends Controller
Expand Down Expand Up @@ -410,6 +411,7 @@ for the login page:
# ...
firewalls:
# order matters! This must be before the ^/ firewall
login_firewall:
pattern: ^/login$
anonymous: ~
Expand Down
2 changes: 1 addition & 1 deletion reference/configuration/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ Each part will be explained in the next section.
# use the urldecoded format
path: ~ # Example: ^/path to resource/
host: ~
ip: ~
ips: []
methods: []
roles: []
role_hierarchy:
Expand Down

0 comments on commit 95d6a7d

Please sign in to comment.