Request Method GET
suggest changeIt is quite easy to call a CGI-Script via GET
. First you will need the encoded url
of the script.
Then you add a question mark ?
followed by variables.
- Every variable should have two sections seperated by =. First section should be always a unique name for each variable, while the second part has values in it only
- Variables are seperated by &
- Total length of the string should not rise above 255 characters
- Names and values needs to be html-encoded (replace: </ , / ? : @ & = + $ ) Hint: When using html-forms the request method can be generated by it self. With Ajax you can encode all via encodeURI and encodeURIComponent
Example:
http://www.example.com/cgi-bin/script.sh?var1=Hello%20World!&var2=This%20is%20a%20Test.&
The server should communicate via Cross-Origin Resource Sharing (CORS) only, to make request more secure. In this showcase we use CORS to determine the Data-Type
we want to use.
There are many Data-Types
we can choose from, the most common are…
- text/html
- text/plain
- application/json
When sending a request, the server will also create many environment variables. For now the most important environment variables are $REQUEST_METHOD
and $QUERY_STRING
.
The Request Method has to be GET
nothing else! The Query String includes all the html-endoded data
.
The Script
#!/bin/bash # CORS is the way to communicate, so lets response to the server first echo "Content-type: text/html" # set the data-type we want to use echo "" # we dont need more rules, the empty line initiate this. # CORS are set in stone and any communication from now on will be like reading a html-document. # Therefor we need to create any stdout in html format! # create html scructure and send it to stdout echo "<!DOCTYPE html>" echo "<html><head>" # The content will be created depending on the Request Method if [ "$REQUEST_METHOD" = "GET" ]; then # Note that the environment variables $REQUEST_METHOD and $QUERY_STRING can be processed by the shell directly. # One must filter the input to avoid cross site scripting. Var1=$(echo "$QUERY_STRING" | sed -n 's/^.*var1=\([^&]*\).*$/\1/p') # read value of "var1" Var1_Dec=$(echo -e $(echo "$Var1" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;')) # html decode Var2=$(echo "$QUERY_STRING" | sed -n 's/^.*var2=\([^&]*\).*$/\1/p') Var2_Dec=$(echo -e $(echo "$Var2" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;')) # create content for stdout echo "<title>Bash-CGI Example 1</title>" echo "</head><body>" echo "<h1>Bash-CGI Example 1</h1>" echo "<p>QUERY_STRING: ${QUERY_STRING}<br>var1=${Var1_Dec}<br>var2=${Var2_Dec}</p>" # print the values to stdout else echo "<title>456 Wrong Request Method</title>" echo "</head><body>" echo "<h1>456</h1>" echo "<p>Requesting data went wrong.<br>The Request method has to be \"GET\" only!</p>" fi echo "<hr>" echo "$SERVER_SIGNATURE" # an other environment variable echo "</body></html>" # close html exit 0
The html-document will look like this …
<html><head> <title>Bash-CGI Example 1</title> </head><body> <h1>Bash-CGI Example 1</h1> <p>QUERY_STRING: var1=Hello%20World!&var2=This%20is%20a%20Test.&<br>var1=Hello World!<br>var2=This is a Test.</p> <hr> <address>Apache/2.4.10 (Debian) Server at example.com Port 80</address> </body></html>
The output of the variables will look like this …
var1=Hello%20World!&var2=This%20is%20a%20Test.& Hello World! This is a Test. Apache/2.4.10 (Debian) Server at example.com Port 80
Negative side effects…
- All the encoding and decoding dont look nice, but is needed
- The Request will be public readable and leave a tray behind
- The size of a request is limited
- Needs protection against Cross-Side-Scripting (XSS)