diff options
| author | blotus | 2017-10-02 16:53:49 +0200 |
|---|---|---|
| committer | GitHub | 2017-10-02 16:53:49 +0200 |
| commit | 377cb2a15db578bc61f72c3f8d092599d7a44519 (patch) | |
| tree | ec8ccd072e77df0507bd5e0c4e38449653afed4d /doc | |
| parent | 15216b5b09b918a45f8ea9a68393ca178d716dc3 (diff) | |
| parent | 3552ac0647966ea8bd6ddf0df6ac899421503e8e (diff) | |
Merge pull request #19 from nbs-system/9-cookies-encryption-env-var
Allow to chose the environment variable to derive the cookie encryption key from.
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/source/config.rst | 44 | ||||
| -rw-r--r-- | doc/source/features.rst | 13 |
2 files changed, 39 insertions, 18 deletions
diff --git a/doc/source/config.rst b/doc/source/config.rst index 25a6b73..7170385 100644 --- a/doc/source/config.rst +++ b/doc/source/config.rst | |||
| @@ -38,7 +38,7 @@ global_strict | |||
| 38 | ^^^^^^^^^^^^^ | 38 | ^^^^^^^^^^^^^ |
| 39 | `default: disabled` | 39 | `default: disabled` |
| 40 | 40 | ||
| 41 | ``global_strict`` will enable the `strict <https://secure.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict>`_ mode globally, | 41 | ``global_strict`` will enable the `strict <https://secure.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict>`_ mode globally, |
| 42 | forcing PHP to throw a `TypeError <https://secure.php.net/manual/en/class.typeerror.php>`_ | 42 | forcing PHP to throw a `TypeError <https://secure.php.net/manual/en/class.typeerror.php>`_ |
| 43 | exception if an argument type being passed to a function does not match its corresponding declared parameter type. | 43 | exception if an argument type being passed to a function does not match its corresponding declared parameter type. |
| 44 | 44 | ||
| @@ -53,7 +53,7 @@ harden_random | |||
| 53 | ^^^^^^^^^^^^^ | 53 | ^^^^^^^^^^^^^ |
| 54 | * `default: enabled` | 54 | * `default: enabled` |
| 55 | * `more <features.html#weak-prng-via-rand-mt-rand>`__ | 55 | * `more <features.html#weak-prng-via-rand-mt-rand>`__ |
| 56 | 56 | ||
| 57 | ``harden_random`` will silently replace the insecure `rand <https://secure.php.net/manual/en/function.rand.php>`_ | 57 | ``harden_random`` will silently replace the insecure `rand <https://secure.php.net/manual/en/function.rand.php>`_ |
| 58 | and `mt_rand <https://secure.php.net/manual/en/function.mt-rand.php>`_ functions with | 58 | and `mt_rand <https://secure.php.net/manual/en/function.mt-rand.php>`_ functions with |
| 59 | the secure PRNG `random_int <https://secure.php.net/manual/en/function.random-int.php>`_. | 59 | the secure PRNG `random_int <https://secure.php.net/manual/en/function.random-int.php>`_. |
| @@ -85,7 +85,7 @@ unserialize_hmac | |||
| 85 | ^^^^^^^^^^^^^^^^ | 85 | ^^^^^^^^^^^^^^^^ |
| 86 | * `default: disabled` | 86 | * `default: disabled` |
| 87 | * `more <features.html#unserialize-related-magic>`__ | 87 | * `more <features.html#unserialize-related-magic>`__ |
| 88 | 88 | ||
| 89 | ``unserialize_hmac`` will add integrity check to ``unserialize`` calls, preventing | 89 | ``unserialize_hmac`` will add integrity check to ``unserialize`` calls, preventing |
| 90 | abritrary code execution in their context. | 90 | abritrary code execution in their context. |
| 91 | 91 | ||
| @@ -101,7 +101,7 @@ auto_cookie_secure | |||
| 101 | ^^^^^^^^^^^^^^^^^^ | 101 | ^^^^^^^^^^^^^^^^^^ |
| 102 | * `default: disabled` | 102 | * `default: disabled` |
| 103 | * `more <features.html#session-cookie-stealing-via-xss>`__ | 103 | * `more <features.html#session-cookie-stealing-via-xss>`__ |
| 104 | 104 | ||
| 105 | ``auto_cookie_secure`` will automatically mark cookies as `secure <https://en.wikipedia.org/wiki/HTTP_cookie#Secure_cookie>`_ | 105 | ``auto_cookie_secure`` will automatically mark cookies as `secure <https://en.wikipedia.org/wiki/HTTP_cookie#Secure_cookie>`_ |
| 106 | when the web page is requested over HTTPS. | 106 | when the web page is requested over HTTPS. |
| 107 | 107 | ||
| @@ -112,17 +112,19 @@ It can either be ``enabled`` or ``disabled``. | |||
| 112 | sp.auto_cookie_secure.enable(); | 112 | sp.auto_cookie_secure.enable(); |
| 113 | sp.auto_cookie_secure.disable(); | 113 | sp.auto_cookie_secure.disable(); |
| 114 | 114 | ||
| 115 | .. _cookie-encryption_config: | ||
| 115 | cookie_encryption | 116 | cookie_encryption |
| 116 | ^^^^^^^^^^^^^^^^^ | 117 | ^^^^^^^^^^^^^^^^^ |
| 117 | * `default: disabled` | 118 | * `default: disabled` |
| 118 | * `more <features.html#session-cookie-stealing-via-xss>`__ | 119 | * `more <features.html#session-cookie-stealing-via-xss>`__ |
| 119 | 120 | ||
| 120 | .. warning:: | 121 | .. warning:: |
| 121 | 122 | ||
| 122 | To use this feature, you **must** set the :ref:`global.secret_key <config_global>` variable. | 123 | To use this feature, you **must** set the :ref:`global.secret_key <config_global>` and |
| 124 | and the :ref:`global.cookie_env_var <config_global>` variables. | ||
| 123 | This design decision prevents attacker from | 125 | This design decision prevents attacker from |
| 124 | `trivially bruteforcing <https://www.idontplaydarts.com/2011/11/decrypting-suhosin-sessions-and-cookies/>`_ | 126 | `trivially bruteforcing <https://www.idontplaydarts.com/2011/11/decrypting-suhosin-sessions-and-cookies/>`_ |
| 125 | session cookies. | 127 | or re-using session cookies. |
| 126 | 128 | ||
| 127 | ``cookie_secure`` will activate transparent encryption of specific cookies. | 129 | ``cookie_secure`` will activate transparent encryption of specific cookies. |
| 128 | 130 | ||
| @@ -133,6 +135,26 @@ It can either be ``enabled`` or ``disabled``, and used in ``simulation`` mode. | |||
| 133 | sp.cookie_encryption.cookie("my_cookie_name"); | 135 | sp.cookie_encryption.cookie("my_cookie_name"); |
| 134 | sp.cookie_encryption.cookie("another_cookie_name"); | 136 | sp.cookie_encryption.cookie("another_cookie_name"); |
| 135 | 137 | ||
| 138 | Choosing the proper environment variable | ||
| 139 | """""""""""""""""""""""""""""""""""""""" | ||
| 140 | |||
| 141 | It's up to you to chose a meaningul environment variable to derive the key from. | ||
| 142 | Suhosin `is using <https://www.suhosin.org/stories/configuration.html#suhosin-session-cryptraddr>`_ | ||
| 143 | the ``REMOTE_ADDR`` one, tying the validity of the cookie to the IP address of the user; | ||
| 144 | unfortunately, nowadays, people are `roaming <https://en.wikipedia.org/wiki/Roaming>`_ a lot on their smartphone, | ||
| 145 | hopping from WiFi to 4G, … | ||
| 146 | |||
| 147 | This is why we recommend, if possible, to use the *extended master secret* | ||
| 148 | from TLS connections (`RFC7627 <https://tools.ietf.org/html/rfc7627>`_) | ||
| 149 | instead, to make the valitity of the cookie TLS-dependent, by using the ``SSL_SESSION_ID`` variable. | ||
| 150 | |||
| 151 | - In `Apache <https://httpd.apache.org/docs/current/mod/mod_ssl.html>`_, | ||
| 152 | it possible to enable by adding ``SSLOptions StdEnvVars`` in your Apache2 configuration. | ||
| 153 | - In `nginx <https://nginx.org/en/docs/http/ngx_http_ssl_module.html#variables>`_, | ||
| 154 | you have to use ``fastcgi_param SSL_SESSION_ID $ssl_session_id if_not_empty;``. | ||
| 155 | |||
| 156 | If you're not using TLS (you should.), you can always use the ``REMOTE_ADDR`` one, | ||
| 157 | or ``X-Real-IP`` if you're behind a reverse proxy. | ||
| 136 | 158 | ||
| 137 | readonly_exec | 159 | readonly_exec |
| 138 | ^^^^^^^^^^^^^ | 160 | ^^^^^^^^^^^^^ |
| @@ -151,7 +173,7 @@ upload_validation | |||
| 151 | * `default: disabled` | 173 | * `default: disabled` |
| 152 | * `more <features.html#remote-code-execution-via-file-upload>`__ | 174 | * `more <features.html#remote-code-execution-via-file-upload>`__ |
| 153 | 175 | ||
| 154 | ``upload_validation`` will call a given script upon a file upload, with the path | 176 | ``upload_validation`` will call a given script upon a file upload, with the path |
| 155 | to the file being uploaded as argument, and various information about it in the environment: | 177 | to the file being uploaded as argument, and various information about it in the environment: |
| 156 | 178 | ||
| 157 | * ``SP_FILENAME``: the name of the uploaded file | 179 | * ``SP_FILENAME``: the name of the uploaded file |
| @@ -192,8 +214,8 @@ Snuffleupagus provides virtual-patching, via the ``disable_functions`` directive | |||
| 192 | Admitting you have a call to ``system()`` that lacks proper user-input validation, thus leading to an **RCE**, this might be the right tool. | 214 | Admitting you have a call to ``system()`` that lacks proper user-input validation, thus leading to an **RCE**, this might be the right tool. |
| 193 | 215 | ||
| 194 | :: | 216 | :: |
| 195 | 217 | ||
| 196 | # Restrict calls to `system` to `id` in the `id.php` file | 218 | # Allow `id.php` to restrict system() calls to `id` |
| 197 | sp.disable_functions.function("system").filename("id.php").param("cmd").value("id").allow(); | 219 | sp.disable_functions.function("system").filename("id.php").param("cmd").value("id").allow(); |
| 198 | sp.disable_functions.function("system").filename("id.php").drop() | 220 | sp.disable_functions.function("system").filename("id.php").drop() |
| 199 | 221 | ||
| @@ -293,4 +315,4 @@ Miscellaneous examples | |||
| 293 | """""""""""""""""""""" | 315 | """""""""""""""""""""" |
| 294 | 316 | ||
| 295 | .. literalinclude:: ../../config/examples.ini | 317 | .. literalinclude:: ../../config/examples.ini |
| 296 | :language: python \ No newline at end of file | 318 | :language: python |
diff --git a/doc/source/features.rst b/doc/source/features.rst index fbb2a64..c0fade3 100644 --- a/doc/source/features.rst +++ b/doc/source/features.rst | |||
| @@ -61,17 +61,16 @@ Session-cookie stealing via XSS | |||
| 61 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 61 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 62 | 62 | ||
| 63 | The goto payload for XSS is often to steal cookies. | 63 | The goto payload for XSS is often to steal cookies. |
| 64 | Like *Suhosin*, we are encrypting the cookies with a secret key, the IP of the user | 64 | Like *Suhosin*, we are encrypting the cookies with a secret key, |
| 65 | an environment variable (usually the IP of the user) | ||
| 65 | and its user-agent. This means that an attacker with an XSS won't be able to use | 66 | and its user-agent. This means that an attacker with an XSS won't be able to use |
| 66 | the stolen cookie, since he (often) can't spoof the IP address of the user. | 67 | the stolen cookie, since he can't spoof the content of the value of the environment |
| 68 | variable for the user. Please do read the :ref:`documentation about this feature <cookie-encryption_config>` | ||
| 69 | if you're planning to use it. | ||
| 67 | 70 | ||
| 68 | This feature is roughly the same than the `Suhosin one <https://suhosin.org/stories/configuration.html#transparent-encryption-options>`_. | 71 | This feature is roughly the same than the `Suhosin one <https://suhosin.org/stories/configuration.html#transparent-encryption-options>`_. |
| 69 | 72 | ||
| 70 | Users behind the same IP address but with different browsers won't be able to use each other stolen cookies, | 73 | Having a secret server-side key will prevent anyone (even the user himself) |
| 71 | except if they can manage to guess the user agent. This isn't especially difficult, | ||
| 72 | but an invalid decryption will leave a trace in the logs. | ||
| 73 | |||
| 74 | Finally, having a secret server-side key will prevent anyone (even the user himself) | ||
| 75 | from reading the content of the cookie, reducing the impact of an application storing sensitive data client-side. | 74 | from reading the content of the cookie, reducing the impact of an application storing sensitive data client-side. |
| 76 | 75 | ||
| 77 | The encryption is done via the `tweetnacl library <https://tweetnacl.cr.yp.to/>`_, | 76 | The encryption is done via the `tweetnacl library <https://tweetnacl.cr.yp.to/>`_, |
