diff --git a/docs/source/theory/interfaces.rst b/docs/source/concepts/interfaces.rst similarity index 100% rename from docs/source/theory/interfaces.rst rename to docs/source/concepts/interfaces.rst diff --git a/docs/source/theory/philosophy.rst b/docs/source/concepts/philosophy.rst similarity index 100% rename from docs/source/theory/philosophy.rst rename to docs/source/concepts/philosophy.rst diff --git a/docs/source/theory/request_life_cycle.rst b/docs/source/concepts/request_life_cycle.rst similarity index 100% rename from docs/source/theory/request_life_cycle.rst rename to docs/source/concepts/request_life_cycle.rst diff --git a/docs/source/theory/resource_tree.rst b/docs/source/concepts/resource_tree.rst similarity index 99% rename from docs/source/theory/resource_tree.rst rename to docs/source/concepts/resource_tree.rst index b7d2626..5611b93 100644 --- a/docs/source/theory/resource_tree.rst +++ b/docs/source/concepts/resource_tree.rst @@ -15,7 +15,7 @@ subcommands. Overview -------- -.. code-block:: plain +.. code-block:: text / │ diff --git a/docs/source/theory/route_matching.rst b/docs/source/concepts/route_matching.rst similarity index 100% rename from docs/source/theory/route_matching.rst rename to docs/source/concepts/route_matching.rst diff --git a/docs/source/theory/routes.rst b/docs/source/concepts/routes.rst similarity index 100% rename from docs/source/theory/routes.rst rename to docs/source/concepts/routes.rst diff --git a/docs/source/examples/index.rst b/docs/source/examples/index.rst index 745e80d..184719e 100644 --- a/docs/source/examples/index.rst +++ b/docs/source/examples/index.rst @@ -362,8 +362,8 @@ In this example we respond back with the line count of the file received in the file.txt has 2 lines -Protecting again Command Injection Attacks -++++++++++++++++++++++++++++++++++++++++++ +Protecting again Parameter Injection Attacks +++++++++++++++++++++++++++++++++++++++++++++ When you resolve variable values be careful to tokenize correctly by using double quotes. Otherwise you could be vulnerable to **parameter injection @@ -401,9 +401,12 @@ request: ls "$(kapow get /request/matches/value)" | kapow set /response/body EOF -.. note:: - If want to read more about command injection, you can check `OWASP site `_ +.. warning:: + + Quotes around parameters only protect against injection of additional + arguments, but not against turning a non-option into option or vice-versa. + See the "Security Concern" section on the docs. Sending HTTP error codes diff --git a/docs/source/index.rst b/docs/source/index.rst index 0a901d4..f78955b 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -59,25 +59,9 @@ Table of Contents :caption: The Project the_project/quickstart + the_project/security the_project/install_and_configure -.. toctree:: - :maxdepth: 2 - :caption: Usage Examples - - examples/index - -.. toctree:: - :maxdepth: 2 - :caption: Theory - - theory/interfaces - theory/philosophy - theory/request_life_cycle - theory/resource_tree - theory/route_matching - theory/routes - .. toctree:: :maxdepth: 2 :caption: Tutorial @@ -90,6 +74,23 @@ Table of Contents tutorial/tutorial04 tutorial/tutorial05 +.. toctree:: + :maxdepth: 2 + :caption: Usage Examples + + examples/index + +.. toctree:: + :maxdepth: 2 + :caption: Concepts + + concepts/interfaces + concepts/philosophy + concepts/request_life_cycle + concepts/resource_tree + concepts/route_matching + concepts/routes + Indices and Tables ================== diff --git a/docs/source/the_project/security.rst b/docs/source/the_project/security.rst new file mode 100644 index 0000000..e0bdc5a --- /dev/null +++ b/docs/source/the_project/security.rst @@ -0,0 +1,86 @@ +Security Concerns +================= + +Special care has to be taken when using parameters provided by the user when +composing command line invocations. + +Sanitizing user input is not a new problem, but in the case of **Kapow!**, we +have to take into account also the way that the shell parses its arguments, +as well as the way the command itself interprets them, in order to get it right. + +.. warning:: + + It is **imperative** that the user input is sanitized properly if we are + going feed it as a parameter to a command line program. + + +Example of Unsafe Parameter Handling +------------------------------------ + +Let's consider the following route: + +.. code-block:: bash + + #!/bin/sh + kapow route add /find -c <<-'EOF' + BASEPATH=$(kapow get /request/params/path) + find "$BASEPATH" | kapow set /response/body + EOF + + +The expected use for this endpoint is something like this: + +.. code-block:: console + + $ curl http://kapow-host/find?path=/tmp + /tmp + /tmp/.X0-lock + /tmp/.Test-unix + /tmp/.font-unix + /tmp/.XIM-unix + /tmp/.ICE-unix + /tmp/.X11-unix + /tmp/.X11-unix/X0 + + +.. todo:: Meanwhile, in Russia: + +Let's suppose that a malicious attacker gets access to this service and +makes this request: + +.. code-block:: console + + $ curl http://kapow-host/find?path=-delete + + +Let's see what happens: + +The command that will eventually be executed by ``bash`` is: + +.. code-block:: bash + + find -delete | kapow set /response/body + +This will silently delete all the files below the current directory, no +questions asked. Probably not what you expected. + +This happens because ``find`` has the last word on how to interpret its arguments. +For ``find`` the argument `-delete` is not a path, + + +Let's see how we can handle this particular case: + +.. code-block:: bash + + #!/bin/sh + kapow route add /find -c <<-'EOF' + USERINPUT=$(kapow get /request/params/path) + BASEPATH=$(dirname -- "$USERINPUT")/$(basename -- "$USERINPUT") + find "$BASEPATH" | kapow set /response/body + EOF + +.. note:: + + Since this is critical for keeping your Kapow! services secure, we are working + on a way to make this more transparent and safe, while at the same time keeping + it Kapowy.