summaryrefslogtreecommitdiff
path: root/doc/source/config.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/source/config.rst')
-rw-r--r--doc/source/config.rst283
1 files changed, 283 insertions, 0 deletions
diff --git a/doc/source/config.rst b/doc/source/config.rst
new file mode 100644
index 0000000..8318e7d
--- /dev/null
+++ b/doc/source/config.rst
@@ -0,0 +1,283 @@
1Configuration
2=============
3
4Since PHP *ini-like* configuration model isn't flexible enough,
5Snuffleupagus is using its own format.
6
7Options are chainable by using dots (``.``), and string parameters
8**must** be quoted, while booleans and integers aren't.
9
10Comments are prefixed either with ``#``, or ``;``.
11
12Some rules applies in a specific ``function`` (context), on a specific ``variable``
13(data), like ``disable_functions``, others can only be enabled/disabled, like
14``harden_random``.
15
16.. warning::
17
18 Careful, a wrongly configured Snuffleupagus might break your website.
19 It's up to you to understand its :doc:`features <features>`,
20 read the present documentation about how to configure them,
21 evaluate your threat model, and write your configuration file accordingly.
22
23The rules are evaluated in the order that they are written, and the **first** one
24to match will terminate the evaluation (except for rules in simulation mode).
25
26Bugclass-killer features
27------------------------
28
29global_strict
30^^^^^^^^^^^^^
31`default: disabled`
32
33``global_strict`` will enable the `strict <https://secure.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict>`_ mode globally,
34forcing PHP to throw a `TypeError <https://secure.php.net/manual/en/class.typeerror.php>`_
35exception if an argument type being passed to a function does not match its corresponding declared parameter type.
36
37It can either be ``enabled`` or ``disabled``
38
39::
40
41 sp.global_strict.disable();
42 sp.global_strict.enable();
43
44harden_random
45^^^^^^^^^^^^^
46 * `default: enabled`
47 * `more <features.html#weak-prng-via-rand-mt-rand>`__
48
49``harden_random`` will silently replace the insecure `rand <https://secure.php.net/manual/en/function.rand.php>`_
50and `mt_rand <https://secure.php.net/manual/en/function.mt-rand.php>`_ functions with
51the secure PRNG `random_int <https://secure.php.net/manual/en/function.random-int.php>`_.
52
53It can either be ``enabled`` or ``disabled``.
54
55::
56
57 sp.harden_random.enable();
58 sp.harden_random.disable();
59
60.. _config_global:
61
62global
63^^^^^^
64
65This configuration variable contain parameters that are used by other ones:
66
67- ``secret_key``: A secret key used by various cryptographic features,
68 like `cookies protection <features.html#session-cookie-stealing-via-xss>`__ or `unserialize protection <features.html#unserialize-related-magic>`__,
69 so do make sure that it's random and long enough.
70 You can generate it with something like this: ``head -c 256 /dev/urandom | tr -dc 'a-zA-Z0-9'``.
71
72::
73
74 sp.global.secret_key("44239bd400aa82e125337c9d4eb8315767411ccd");
75
76unserialize_hmac
77^^^^^^^^^^^^^^^^
78 * `default: disabled`
79 * `more <features.html#unserialize-related-magic>`__
80
81``unserialize_hmac`` will add integrity check to ``unserialize`` calls, preventing
82abritrary code execution in their context.
83
84::
85
86 sp.unserialize_hmac.enable();
87 sp.unserialize_hmac.disable();
88
89
90auto_cookie_secure
91^^^^^^^^^^^^^^^^^^
92 * `default: disabled`
93 * `more <features.html#session-cookie-stealing-via-xss>`__
94
95``auto_cookie_secure`` will automatically mark cookies as `secure <https://en.wikipedia.org/wiki/HTTP_cookie#Secure_cookie>`_
96when the web page is requested over HTTPS.
97
98It can either be ``enabled`` or ``disabled``.
99
100::
101
102 sp.auto_cookie_secure.enable();
103 sp.auto_cookie_secure.disable();
104
105cookie_encryption
106^^^^^^^^^^^^^^^^^
107 * `default: disabled`
108 * `more <features.html#session-cookie-stealing-via-xss>`__
109
110.. warning::
111
112 To use this feature, you **must** set the :ref:`global.secret_key <config_global>` variable.
113 This design decision prevents attacker from
114 `trivially bruteforcing <https://www.idontplaydarts.com/2011/11/decrypting-suhosin-sessions-and-cookies/>`_
115 session cookies.
116
117``cookie_secure`` will activate transparent encryption of specific cookies.
118
119It can either be ``enabled`` or ``disabled``.
120
121::
122
123 sp.cookie_encryption.cookie("my_cookie_name");
124 sp.cookie_encryption.cookie("another_cookie_name");
125
126
127readonly_exec
128^^^^^^^^^^^^^
129 * `default: disabled`
130
131``readonly_exec`` will prevent the execution of writable PHP files.
132
133It can either be ``enabled`` or ``disabled``.
134
135::
136
137 sp.readonly_exec.enable();
138
139upload_validation
140^^^^^^^^^^^^^^^^^
141 * `default: disabled`
142 * `more <features.html#remote-code-execution-via-file-upload>`__
143
144``upload_validation`` will call a given script upon a file upload, with the path
145to the file being uploaded as argument, and various information about it in the environment:
146
147* ``SP_FILENAME``: the name of the uploaded file
148* ``SP_FILESIZE``: the size of the file being uploaded
149* ``SP_REMOTE_ADDR``: the ip address of the uploader
150* ``SP_CURRENT_FILE``: the current file being executed
151
152This feature can be used, for example, to check if an uploaded file contains php
153code, with something like `vld <https://derickrethans.nl/projects.html#vld>`_
154(``php -d vld.execute=0 -d vld.active=1 -d extension=vld.so yourfile.php``).
155
156The upload will be **allowed** if the script return the value ``0``. Every other
157value will prevent the file from being uploaded.
158
159::
160
161 sp.upload_validation.script("/var/www/is_valid_php.py").enable();
162
163
164disable_xxe
165^^^^^^^^^^^
166 * `default: enabled`
167 * `more <features.html#xxe>`__
168
169``disable_xxe`` will prevent XXE attacks by disabling the loading of external entities (``libxml_disable_entity_loader``) in the XML parser.
170
171::
172
173 sp.disable_xxe.enable();
174
175
176Virtual-patching
177----------------
178
179Snuffleupagus provides virtual-patching, via the ``disable_functions`` directive, allowing you to stop or control dangerous behaviours.
180Admitting you have a call to ``system()`` that lacks proper user-input validation, thus leading to an **RCE**, this might be the right tool.
181
182::
183
184 # Allow `id.php` to restrict system() calls to `id`
185 sp.disable_functions.function("system").filename("id.php").param("cmd").value("id").allow();
186 sp.disable_functions.function("system").filename("id.php").drop()
187
188Of course, this is a trivial example, and a lot can be achieved with this feature, as you will see below.
189
190
191Filters
192^^^^^^^
193
194- ``alias(:str)``: human-readable description of the rule
195- ``cidr(ip/mask:str)``: match on the client's `cidr <https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing>`_
196- ``filename(name:str)``: match in the file ``name``
197- ``filename_r(regexp:str)``: the file name matching the ``regexp``
198- ``function(name:str)``: match on function ``name``
199- ``function_r(regexp:str)``: the function matching the ``regexp``
200- ``hash(:str)``: match on the file's `sha256 <https://en.wikipedia.org/wiki/SHA-2>`_ sum
201- ``param(name:str)``: match on the function's parameter ``name``
202- ``param_r(regexp:str)``: match on the function's parameter ``regexp``
203- ``param_type(type:str)``: match on the function's parameter ``type``
204- ``ret(value:str)``: match on the function's return ``value``
205- ``ret_r(regexp:str)``: match with a ``regexp`` on the function's return
206- ``ret_type(type_name:str)``: match on the ``type_name`` of the function's return value
207- ``value(:str)``: match on a litteral value
208- ``value_r(:regexp)``: match on a value matching the ``regexp``
209- ``var(name:str)``: match on a **local variable** ``name``
210
211The ``type`` must be one of the following values:
212
213- ``FALSE``: for boolean false
214- ``TRUE``: for boolean true
215- ``NULL``: for the **null** value
216- ``LONG``: for a long (also know as ``integer``) value
217- ``DOUBLE``: for a **double** (also known as ``float``) value
218- ``STRING``: for a string
219- ``OBJECT``: for a object
220- ``ARRAY``: for an array
221- ``RESOURCE``: for a resource
222
223Actions
224^^^^^^^
225
226- ``allow()``: **allow** the request if the rule matches
227- ``drop()``: **drop** the request if the rule matches
228- ``dump(directory:str)``: dump the request in the ``directory`` if it matches the rule
229- ``simulation()``: enabled the simulation mode
230
231Details
232^^^^^^^
233
234The ``function`` filter is able to do various dereferencing:
235
236- ``function("AwesomeClass::my_method")`` will match in the method ``my_method`` in the class ``AwesomeClass``
237
238The ``param`` filter is also able to do some dereferencing:
239
240- ``param(foo[bar])`` will get match on the value corresponding to the ``bar`` key in the hashtable ``foo``.
241 Remember that in PHP, almost every data structure is a hashtable. You can of course nest this like
242 ``param(foo[bar][baz][batman])``.
243- The ``var`` filter will walk the calltrace until it finds the variable's name, or the end of it,
244 allowing to match on global variables: ``.var("_GET[param]")`` will match on the GET parameter ``param``.
245
246For clarity's sake, the presence of the ``allow`` or ``drop`` action is **mandatory**.
247
248.. warning::
249
250 When you're writing rules, please do keep in mind that the **order matters**.
251 For example, if you're denying a call to ``system()`` and then allowing it in a
252 more narrowed way later, the call will be denied,
253 because it'll match the deny first.
254
255If you're paranoid, we're providing a php script to automatically generate
256hash of files containing dangerous functions,
257and blacklisting them everywhere else.
258
259Examples
260^^^^^^^^
261
262Evaluation order of rules
263"""""""""""""""""""""""""
264
265The following rules will:
266
2671. Allow calls to ``system("id")``
2682. Issue a trace in the logs on calls to ``system`` with its parameters starting with ``ping``,
269 and pursuing evaluation of the remaining rules.
2703. Drop calls to ``system``.
271
272
273::
274
275 sp.disable_functions.function("system").param("cmd").value("id").allow();
276 sp.disable_functions.function("system").param("cmd").value_r("^ping").drop().simulation();
277 sp.disable_functions.function("system").param("cmd").drop();
278
279Miscellaneous examples
280""""""""""""""""""""""
281
282.. literalinclude:: ../../config/examples.ini
283 :language: python \ No newline at end of file