Bash
CGI-scripts
Zoeken…
Verzoekmethode: GET
Het is vrij eenvoudig om een CGI-Script via GET
aan te roepen.
Eerst hebt u de encoded url
van het script nodig.
Dan voeg je een vraagteken toe ?
gevolgd door variabelen.
- Elke variabele moet twee secties hebben, gescheiden door = .
Eerste sectie moet altijd een unieke naam zijn voor elke variabele,
terwijl het tweede deel alleen waarden bevat - Variabelen worden gescheiden door &
- De totale lengte van de tekenreeks mag niet hoger zijn dan 255 tekens
- Namen en waarden moeten html-gecodeerd zijn (vervangen: </, /?: @ & = + $ )
Tip:
Bij gebruik van html-formulieren kan de aanvraagmethode zelf worden gegenereerd.
Met Ajax kunt u alles coderen via encodeURI en encodeURIComponent
Voorbeeld:
http://www.example.com/cgi-bin/script.sh?var1=Hello%20World!&var2=This%20is%20a%20Test.&
De server mag alleen communiceren via Cross-Origin Resource Sharing (CORS) om het verzoek veiliger te maken. In deze showcase gebruiken we CORS om het Data-Type
te bepalen dat we willen gebruiken.
Er zijn veel Data-Types
we kunnen kiezen, de meest voorkomende zijn ...
- text / html
- text / plain
- application / json
Bij het verzenden van een aanvraag maakt de server ook veel omgevingsvariabelen. Voor nu zijn de belangrijkste omgevingsvariabelen $REQUEST_METHOD
en $QUERY_STRING
.
De aanvraagmethode moet niets anders GET
!
De Query String bevat alle html-endoded data
.
Het 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
Het html-document ziet er zo uit ...
<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>
De uitvoer van de variabelen ziet er zo uit ...
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
Negatieve bijwerkingen ...
- Alle codering en decodering zien er niet mooi uit, maar zijn wel nodig
- Het verzoek is openbaar leesbaar en laat een dienblad achter
- De grootte van een verzoek is beperkt
- Heeft bescherming nodig tegen Cross-Side-Scripting (XSS)
Verzoekmethode: POST / w JSON
Het gebruik van de aanvraagmethode POST
in combinatie met SSL
maakt gegevensoverdracht veiliger.
Daarnaast...
- De meeste codering en decodering is niet meer nodig
- De URL is zichtbaar voor iedereen en moet URL-gecodeerd zijn.
De gegevens worden afzonderlijk verzonden en moeten daarom worden beveiligd via SSL - De grootte van de gegevens is vrijwel onbetwist
- Heeft nog steeds bescherming nodig tegen Cross-Side-Scripting (XSS)
Om deze showcase eenvoudig te houden, willen we JSON Data ontvangen
en communicatie moet via Cross-Origin Resource Sharing (CORS) plaatsvinden.
Het volgende script zal ook twee verschillende inhoudstypen demonstreren.
#!/bin/bash
exec 2>/dev/null # We dont want any error messages be printed to stdout
trap "response_with_html && exit 0" ERR # response with an html message when an error occurred and close the script
function response_with_html(){
echo "Content-type: text/html"
echo ""
echo "<!DOCTYPE html>"
echo "<html><head>"
echo "<title>456</title>"
echo "</head><body>"
echo "<h1>456</h1>"
echo "<p>Attempt to communicate with the server went wrong.</p>"
echo "<hr>"
echo "$SERVER_SIGNATURE"
echo "</body></html>"
}
function response_with_json(){
echo "Content-type: application/json"
echo ""
echo "{\"message\": \"Hello World!\"}"
}
if [ "$REQUEST_METHOD" = "POST" ]; then
# The environment variabe $CONTENT_TYPE describes the data-type received
case "$CONTENT_TYPE" in
application/json)
# The environment variabe $CONTENT_LENGTH describes the size of the data
read -n "$CONTENT_LENGTH" QUERY_STRING_POST # read datastream
# The following lines will prevent XSS and check for valide JSON-Data.
# But these Symbols need to be encoded somehow before sending to this script
QUERY_STRING_POST=$(echo "$QUERY_STRING_POST" | sed "s/'//g" | sed 's/\$//g;s/`//g;s/\*//g;s/\\//g' ) # removes some symbols (like \ * ` $ ') to prevent XSS with Bash and SQL.
QUERY_STRING_POST=$(echo "$QUERY_STRING_POST" | sed -e :a -e 's/<[^>]*>//g;/</N;//ba') # removes most html declarations to prevent XSS within documents
JSON=$(echo "$QUERY_STRING_POST" | jq .) # json encode - This is a pretty save way to check for valide json code
;;
*)
response_with_html
exit 0
;;
esac
else
response_with_html
exit 0
fi
# Some Commands ...
response_with_json
exit 0
U krijgt {"message":"Hello World!"}
Als antwoord wanneer u JSON-Data via POST
naar dit Script verzendt. Al het andere ontvangt het html-document.
Belangrijk is ook de varialbe $JSON
. Deze variabele is XSS-vrij, maar kan nog steeds verkeerde waarden bevatten en moet eerst worden geverifieerd. Houd daar alstublieft rekening mee.
Deze code werkt vergelijkbaar zonder JSON.
U kunt op deze manier gegevens ophalen.
U hoeft alleen het Content-Type
aan uw behoeften aan te passen.
Voorbeeld:
if [ "$REQUEST_METHOD" = "POST" ]; then
case "$CONTENT_TYPE" in
application/x-www-form-urlencoded)
read -n "$CONTENT_LENGTH" QUERY_STRING_POST
text/plain)
read -n "$CONTENT_LENGTH" QUERY_STRING_POST
;;
esac
fi
Last but not least, vergeet niet op alle verzoeken te reageren, anders zullen programma's van derden niet weten of ze zijn geslaagd