diff --git a/docs/source/examples/index.rst b/docs/source/examples/index.rst index 9e61232..81cbcdb 100644 --- a/docs/source/examples/index.rst +++ b/docs/source/examples/index.rst @@ -1,6 +1,3 @@ -Examples -======== - Using a .pow file +++++++++++++++++ @@ -11,21 +8,22 @@ A .pow file is a plain text with shell instructions, usually, you can use Kapow! .. code-block:: console :linenos: - $ kapow server example.pow + $ kapow server example.pow With the example.pow: .. code-block:: console :linenos: - # - # This is a simple example of a .pow file - # - echo "[*] Starting my script" + $ cat example.pow + # + # This is a simple example of a .pow file + # + echo "[*] Starting my script" - # We add 2 Kapow! routes - kapow route add '/my/route' -c 'echo "hello world" | kapow set /response/body' - kapow route add -X POST /echo -c 'kapow get /request/body | kapow set /response/body' + # We add 2 Kapow! routes + kapow route add '/my/route' -c 'echo "hello world" | kapow set /response/body' + kapow route add -X POST /echo -c '"$(kapow get /request/body)" | kapow set /response/body' .. note:: @@ -39,14 +37,14 @@ You can load more than one .pow file at time. This can help you have your .pow f .. code-block:: console :linenos: - $ ls pow-files/ - example-1.pow example-2.pow - $ kapow server <(cat *.pow) + $ ls pow-files/ + example-1.pow example-2.pow + $ kapow server <(cat pow-files/*.pow) Add a new route +++++++++++++++ -.. note:: +.. warning:: Be aware when you defined more than routes in same path, only first routed added will be resolved. @@ -64,15 +62,15 @@ Defining route: .. code-block:: console :linenos: - $ kapow route add '/my/route' -c 'echo "hello world" | kapow set /response/body' + $ kapow route add '/my/route' -c 'echo "hello world" | kapow set /response/body' Calling route: .. code-block:: console :linenos: - $ curl http://localhost:8080/my/route - hello world + $ curl http://localhost:8080/my/route + hello world **POST route** @@ -81,15 +79,15 @@ Defining route: .. code-block:: console :linenos: - $ kapow route add -X POST /echo -c 'kapow get /request/body | kapow set /response/body' + $ kapow route add -X POST /echo -c '"$(kapow get /request/body)" | kapow set /response/body' Calling route: .. code-block:: console :linenos: - $ curl -d "hello world" -X POST http://localhost:8080/echo - hello world% + $ curl -d "hello world" -X POST http://localhost:8080/echo + hello world% **Adding URL params** @@ -98,15 +96,15 @@ Defining route: .. code-block:: console :linenos: - $ kapow route add '/echo/{message}' -c 'kapow get /request/matches/message | kapow set /response/body' + $ kapow route add '/echo/{message}' -c '"$(kapow get /request/matches/message)" | kapow set /response/body' Calling route: .. code-block:: console :linenos: - $ curl http://localhost:8080/echo/hello%20world - hello world% + $ curl http://localhost:8080/echo/hello%20world + hello world% Listing routes @@ -114,28 +112,30 @@ Listing routes You can list active route in kapow! server. -.. code-block:: console - :linenos: - - $ kapow route list - [{"id":"20c98328-0b82-11ea-90a8-784f434dfbe2","method":"GET","url_pattern":"/echo/{message}","entrypoint":"/bin/sh -c","command":"kapow get /request/matches/message | kapow set /response/body","index":0}] - -Or, for pretty output, you can use samp:`jq`: +.. _examples_listing_routes: .. code-block:: console :linenos: - $ kapow route list | jq - [ - { - "id": "20c98328-0b82-11ea-90a8-784f434dfbe2", - "method": "GET", - "url_pattern": "/echo/{message}", - "entrypoint": "/bin/sh -c", - "command": "kapow get /request/matches/message | kapow set /response/body", - "index": 0 - } - ] + $ kapow route list + [{"id":"20c98328-0b82-11ea-90a8-784f434dfbe2","method":"GET","url_pattern":"/echo/{message}","entrypoint":"/bin/sh -c","command":"echo \"$(kapow get /request/matches/message)\" | kapow set /response/body","index":0}] + +Or, for pretty output, you can use :samp:`jq`: + +.. code-block:: console + :linenos: + + $ kapow route list | jq + [ + { + "id": "20c98328-0b82-11ea-90a8-784f434dfbe2", + "method": "GET", + "url_pattern": "/echo/{message}", + "entrypoint": "/bin/sh -c", + "command": "\"$(kapow get /request/matches/message)\" | kapow set /response/body", + "index": 0 + } + ] .. note:: @@ -146,12 +146,12 @@ Or, for pretty output, you can use samp:`jq`: Deleting routes +++++++++++++++ -If we want to delete a route you need their ID. Using de above example, you can delete the route by typing: +If we want to delete a route you need their ID. Using de :ref:`listing routes example `, you can delete the route by typing: .. code-block:: console :linenos: - $ kapow route remove 20c98328-0b82-11ea-90a8-784f434dfbe2 + $ kapow route remove 20c98328-0b82-11ea-90a8-784f434dfbe2 Writing multiline .pow files ++++++++++++++++++++++++++++ @@ -161,16 +161,17 @@ Some time you need to write more complex actions. So you can write multiline com .. code-block:: console :linenos: - kapow route add /log_and_stuff - <<-'EOF' - echo this is a quite long sentence and other stuff | tee log.txt | kapow set /response/body - cat log.txt | kapow set /response/body - EOF + $ cat multiline.pow + kapow route add /log_and_stuff - <<-'EOF' + echo this is a quite long sentence and other stuff | tee log.txt | kapow set /response/body + cat log.txt | kapow set /response/body + EOF -.. note:: +.. warning:: - Be aware with the **"-"** at the end of Kapow! command. It allows to read commands from the samp:`stdin`. + Be aware with the **"-"** at the end of Kapow! command. It allows to read commands from the :samp:`stdin`. -.. note:: +.. warning:: Multiline depends of the shell you're using (Bash by default). If you want to learn more of multiline see: `Here Doc `_ @@ -185,37 +186,37 @@ In this example we'll adding the security header "nosniff" in a sniff.pow: .. code-block:: console :linenos: - $ cat sniff.pow - kapow route add /sec-hello-world - <<-'EOF' - kapow set /response/headers/X-Content-Type-Options "nosniff" + $ cat sniff.pow + kapow route add /sec-hello-world - <<-'EOF' + kapow set /response/headers/X-Content-Type-Options "nosniff" - echo "more secure hello world" | kapow set /response/body - EOF + echo "more secure hello world" | kapow set /response/body + EOF - $ kapow server nosniff.pow + $ kapow server nosniff.pow -Test with curl: +Testing with curl: .. code-block:: console :emphasize-lines: 11 :linenos: - $ curl -v http://localhost:8080/sec-hello-world - * Trying ::1... - * TCP_NODELAY set - * Connected to localhost (::1) port 8080 (#0) - > GET /sec-hello-word HTTP/1.1 - > Host: localhost:8080 - > User-Agent: curl/7.54.0 - > Accept: */* - > - < HTTP/1.1 200 OK - < X-Content-Type-Options: nosniff - < Date: Wed, 20 Nov 2019 10:56:46 GMT - < Content-Length: 24 - < Content-Type: text/plain; charset=utf-8 - < - more secure hello world + $ curl -v http://localhost:8080/sec-hello-world + * Trying ::1... + * TCP_NODELAY set + * Connected to localhost (::1) port 8080 (#0) + > GET /sec-hello-word HTTP/1.1 + > Host: localhost:8080 + > User-Agent: curl/7.54.0 + > Accept: */* + > + < HTTP/1.1 200 OK + < X-Content-Type-Options: nosniff + < Date: Wed, 20 Nov 2019 10:56:46 GMT + < Content-Length: 24 + < Content-Type: text/plain; charset=utf-8 + < + more secure hello world .. note:: @@ -229,18 +230,21 @@ In this example our Kapow! service will receive a JSON value with an incorrect d .. code-block:: console :linenos: - $ cat fix_date.pow - kapow route add -X POST '/fix-date' - <<-'EOF' - kapow set /response/headers/Content-Type "application/json" - kapow get /request/body | jq --arg newdate $(date +"%Y-%m-%d_%H-%M-%S") '.incorrectDate=$newdate' | kapow set /response/body - EOF + $ cat fix_date.pow + kapow route add -X POST '/fix-date' - <<-'EOF' + kapow set /response/headers/Content-Type "application/json" + echo "$(kapow get /request/body)" | jq --arg newdate $(date +"%Y-%m-%d_%H-%M-%S") '.incorrectDate=$newdate' | kapow set /response/body + EOF Call service with curl: .. code-block:: console :linenos: - $ curl -X POST http://localhost:8080/fix-date -H "Content-Type: application/json" -d '{"incorrectDate": "no way"}' + $ curl -X POST http://localhost:8080/fix-date -H "Content-Type: application/json" -d '{"incorrectDate": "no way"}' + { + "incorrectDate": "2019-11-22_10-42-06" + } Upload files ++++++++++++ @@ -250,18 +254,18 @@ Upload a file using Kapow! is very simple: .. code-block:: console :linenos: - $ cat upload.pow - kapow route add -X POST '/upload-file' - <<-'EOF' - kapow get /request/files/data/content | kapow set /response/body - EOF + $ cat upload.pow + kapow route add -X POST '/upload-file' - <<-'EOF' + echo "$(kapow get /request/files/data/content) | kapow set /response/body + EOF .. code-block:: console :linenos: - $ cat results.json - {"hello": "world"} - $ curl -X POST -H "Content-Type: multipart/form-data" -F "data=@results.json" http://localhost:8080/upload-file - {"hello": "world"} + $ cat results.json + {"hello": "world"} + $ curl -X POST -H "Content-Type: multipart/form-data" -F "data=@results.json" http://localhost:8080/upload-file + {"hello": "world"} Protecting again Command Injection Attacks ++++++++++++++++++++++++++++++++++++++++++ @@ -275,10 +279,10 @@ In this example, an attacker can execute arbitrary command. .. code-block:: console :linenos: - $ cat command-injection.pow - kapow route add '/vulnerable/{value}' - <<-'EOF' - ls $(kapow get /request/matches/value) | kapow set /response/body - EOF + $ cat command-injection.pow + kapow route add '/vulnerable/{value}' - <<-'EOF' + ls "$(kapow get /request/matches/value)" | kapow set /response/body + EOF Exploding using curl: @@ -294,10 +298,10 @@ Be aware of we add double quotes when we recover *value* data from url: .. code-block:: console :linenos: - $ cat command-injection.pow - kapow route add '/vulnerable/{value}' - <<-'EOF' - ls "$(kapow get /request/matches/value)" | kapow set /response/body - EOF + $ cat command-injection.pow + kapow route add '/vulnerable/{value}' - <<-'EOF' + ls "$(kapow get /request/matches/value)" | kapow set /response/body + EOF .. note:: @@ -311,16 +315,16 @@ You can specify custom status code for HTTP response: .. code-block:: console :linenos: - $ cat error.pow - kapow route add '/error' - <<-'EOF' - kapow set /response/status 401 - echo "401 error" | kapow set /response/body - EOF + $ cat error.pow + kapow route add '/error' - <<-'EOF' + kapow set /response/status 401 + echo "401 error" | kapow set /response/body + EOF Testing with curl: .. code-block:: console - :emphasize-lines: 8 + :emphasize-lines: 10 :linenos: $ curl -v http://localhost:8080/error @@ -347,47 +351,47 @@ In this example we'll redirect our users to Google: .. code-block:: console :linenos: - $ cat redirect.pow - kapow route add '/redirect' - <<-'EOF' - kapow set /response/headers/Location 'http://google.com' - kapow set /response/status 301 - EOF + $ cat redirect.pow + kapow route add '/redirect' - <<-'EOF' + kapow set /response/headers/Location 'http://google.com' + kapow set /response/status 301 + EOF .. code-block:: console :emphasize-lines: 10-11 :linenos: - $ curl -v http://localhost:8080/redirect - * Trying ::1... - * TCP_NODELAY set - * Connected to localhost (::1) port 8080 (#0) - > GET /redirect HTTP/1.1 - > Host: localhost:8080 - > User-Agent: curl/7.54.0 - > Accept: */* - > - < HTTP/1.1 301 Moved Permanently - < Location: http://google.com - < Date: Wed, 20 Nov 2019 11:39:24 GMT - < Content-Length: 0 - < - * Connection #0 to host localhost left intact + $ curl -v http://localhost:8080/redirect + * Trying ::1... + * TCP_NODELAY set + * Connected to localhost (::1) port 8080 (#0) + > GET /redirect HTTP/1.1 + > Host: localhost:8080 + > User-Agent: curl/7.54.0 + > Accept: */* + > + < HTTP/1.1 301 Moved Permanently + < Location: http://google.com + < Date: Wed, 20 Nov 2019 11:39:24 GMT + < Content-Length: 0 + < + * Connection #0 to host localhost left intact How to execute two processes parallel +++++++++++++++++++++++++++++++++++++ -We want to samp:`ping` two machines parallel. Kapow! get IPs from query params: +We want to :samp:`ping` two machines parallel. Kapow! get IPs from query params: .. code-block:: console :linenos: - $ cat parallel.pow - kapow route add /parallel/{ip1}/{ip2} - <<-'EOF' - ping -c 1 $(kapow get /request/matches/ip1) | kapow set /response/body & - ping -c 1 $(kapow get /request/matches/ip2) | kapow set /response/body & - wait - EOF + $ cat parallel.pow + kapow route add /parallel/{ip1}/{ip2} - <<-'EOF' + ping -c 1 "$(kapow get /request/matches/ip1)" | kapow set /response/body & + ping -c 1 "$(kapow get /request/matches/ip2)" | kapow set /response/body & + wait + EOF Calling with curl: @@ -399,3 +403,49 @@ Calling with curl: Manage cookies ++++++++++++++ +Sometimes you need track down some user state. Kapow! allows you manage Request/Response Cookies. + +Next example we'll set a cookie: + +.. code-block:: console + :linenos: + + $ cat cookie.pow + kapow route add /setcookie - <<-'EOF' + CURRENT_STATUS="$(kapow get /request/cookies/kapow-status)" + + if [ -z "$CURRENT_SATUS" ]; then + kapow set /response/cookies/Kapow-Status "Kapow Cookie Set" + fi + + echo "Ok" | kapow set /response/body + EOF + +Calling with curl: + +.. code-block:: console + :linenos: + :emphasize-lines: 11 + + $ curl -v http://localhost:8080/set-cookie + * Trying ::1... + * TCP_NODELAY set + * Connected to localhost (::1) port 8080 (#0) + > GET /setcookie HTTP/1.1 + > Host: localhost:8080 + > User-Agent: curl/7.54.0 + > Accept: */* + > + < HTTP/1.1 200 OK + < Set-Cookie: Kapow-Status="Kapow Cookie Set" + < Date: Fri, 22 Nov 2019 10:44:42 GMT + < Content-Length: 3 + < Content-Type: text/plain; charset=utf-8 + < + Ok + * Connection #0 to host localhost left intact + +TODO: ++ QUITAR LOS COMMAND IJECTIONS ++ corregir los :samp: +- negritas