Bash
CGI-Skripte
Suche…
Anforderungsmethode: GET
Es ist ziemlich einfach, ein CGI-Skript über GET
aufzurufen.
Zuerst benötigen Sie die encoded url
des Skripts.
Dann fügen Sie ein Fragezeichen hinzu ?
gefolgt von Variablen.
- Jede Variable sollte zwei durch = getrennte Abschnitte haben.
Der erste Abschnitt sollte immer einen eindeutigen Namen für jede Variable haben.
während der zweite Teil nur Werte enthält - Variablen werden durch & getrennt.
- Die Gesamtlänge der Zeichenfolge sollte 255 Zeichen nicht überschreiten
- Namen und Werte müssen HTML-codiert sein (ersetzen Sie: </, /?: @ & = + $ )
Hinweis:
Bei Verwendung von HTML-Formularen kann die Anforderungsmethode selbst generiert werden.
Mit Ajax können Sie alles über encodeURI und encodeURIComponent kodieren
Beispiel:
http://www.example.com/cgi-bin/script.sh?var1=Hello%20World!&var2=This%20is%20a%20Test.&
Der Server sollte nur über Cross-Origin Resource Sharing (CORS) kommunizieren, um die Anforderung sicherer zu machen. In diesem Fall verwenden wir CORS , um den Data-Type
zu bestimmen, den wir verwenden möchten.
Es gibt viele Data-Types
, aus denen wir wählen können, die häufigsten sind ...
- Text / HTML
- text / plain
- Anwendung / Json
Beim Senden einer Anfrage erstellt der Server auch viele Umgebungsvariablen. $REQUEST_METHOD
sind die wichtigsten Umgebungsvariablen $REQUEST_METHOD
und $QUERY_STRING
.
Die Request - Methode muss sein GET
nichts anderes!
Der Query - String enthält alle html-endoded data
.
Das Skript
#!/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
Das HTML-Dokument wird so aussehen ...
<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>
Die Ausgabe der Variablen sieht so aus ...
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 Nebenwirkungen ...
- Das Kodieren und Dekodieren sieht nicht gut aus, wird aber benötigt
- Die Anfrage ist öffentlich lesbar und lässt ein Tablett zurück
- Die Größe einer Anfrage ist begrenzt
- Benötigt Schutz gegen Cross-Side-Scripting (XSS)
Anforderungsmethode: POST / w JSON
Durch die Verwendung der Anforderungsmethode POST
in Kombination mit SSL
wird der Datentransfer sicherer.
In Ergänzung...
- Die meiste Kodierung und Dekodierung wird nicht mehr benötigt
- Die URL ist für jeden sichtbar und muss url-codiert sein.
Die Daten werden separat versendet und sollten daher über SSL gesichert werden - Die Größe der Daten ist nahezu unbegrenzt
- Braucht immer noch Schutz vor Cross-Side-Scripting (XSS)
Um dieses Schaufenster einfach zu halten, möchten wir JSON-Daten erhalten
und die Kommunikation sollte über Cross-Origin Resource Sharing (CORS) erfolgen.
Das folgende Skript zeigt auch zwei verschiedene Inhaltstypen .
#!/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
Sie erhalten {"message":"Hello World!"}
Als Antwort, wenn Sie JSON-Daten per POST
an dieses Skript senden. Alles andere wird das HTML-Dokument erhalten.
Wichtig ist auch das varialbe $JSON
. Diese Variable ist frei von XSS, kann jedoch noch falsche Werte enthalten und muss zuerst überprüft werden. Bitte denkt daran.
Dieser Code funktioniert ähnlich ohne JSON.
Sie könnten auf diese Weise Daten erhalten.
Sie müssen nur den Content-Type
für Ihre Anforderungen ändern.
Beispiel:
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, vergessen Sie nicht, auf alle Anfragen zu antworten, sonst wissen Drittanbieterprogramme nicht, ob sie erfolgreich waren