Το πρόγραμμα CGI δέχεται από τον εξυπηρετητή τις παραμέτρους που καθόρισε ο χρήστης μέσω μεταβλητών του περιβάλλοντος (environment variables). Τυπικό δείγμα των μεταβλητών που μεταφέρονται στο πρόγραμμα CGI είναι το παρακάτω:
SERVER_SOFTWARE=Apache/1.2.5 GATEWAY_INTERFACE=CGI/1.1 DOCUMENT_ROOT=/home/www/htdocs REMOTE_ADDR=192.168.135.5 SERVER_PROTOCOL=HTTP/1.0 REQUEST_METHOD=GET REMOTE_HOST=staffpc15.aegean.gr QUERY_STRING= HTTP_USER_AGENT=Mozilla/3.01 (Win95; I) PATH=/bin:/usr/bin: HTTP_CONNECTION=Keep-Alive HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* REMOTE_PORT=1124 SCRIPT_NAME=/cgi-bin/pe SCRIPT_FILENAME=/home/www//cgi-bin/pe SERVER_NAME=www.aegean.gr REQUEST_URI=/cgi-bin/pe SERVER_PORT=80 HTTP_HOST=www.aegean.gr SERVER_ADMIN=webmaster@aegean.grΑφού το πρόγραμμα επεξεργαστεί τις παραμέτρους που όρισε ο χρήστης στη φόρμα (που περιέχονται κωδικοποιημένες στη μεταβλητή QUERY_STRING) δημιουργεί μια πλήρη απάντηση σύμφωνα με το πρωτόκολλο HTTP (επικεφαλίδα και δεδομένα). Για παράδειγμα, η εκτύπωση των πιο πάνω μεταβλητών έγινε από το εξής πρόγραμμα σε Perl:
#!/usr/bin/perl print "Content-Type: text/plain\n\n"; for $key (keys %ENV) { print "$key=$ENV{$key}\n"; }Σχετιζόμενα προβλήματα ασφάλειας είναι τα παρακάτω:
#!/usr/bin/perl $query = $ENV{'QUERY_STRING'}; @pairs = split(/\&/, $query); for (@pairs) { ($field, $val) = split(/=/); $field =~ s/\+/ /g; $field =~ s/\%(\w\w)/sprintf("%c", hex($1))/eg; $val =~ s/\+/ /g; $val =~ s/\%(\w\w)/sprintf("%c", hex($1))/eg; $field{$field} = $val; } $|=1; print "Content-Type: text/plain\n\n"; system "finger $field{USER}\n";Αν το εκτελέσουμε με την παράμετρο USER να έχει την τιμή dds
http://www.senanet.com/cgi-bin/pe?USER=ddsθα εμφανιστεί το παρακάτω αποτέλεσμα:
Login: dds Name: Diomidis Spinellis Directory: /home/dds Shell: /bin/bash On since Wed Jun 30 12:18 (EET) on ttyp0 5 minutes 49 seconds idleΑν όμως προσθέσουμε στο τέλος του URI ένα ερωτηματικό (που διαχωρίζει τις εντολές στο φλοιό του Unix) και την εντολή cat /etc/passwd
http://www.senanet.com/cgi-bin/pe?USER=dds;cat%20/etc/passwdθα λάβουμε και το περιεχόμενο του αρχείου passwd (περιέχει τους κωδικοποιημένους κωδικούς χρηστών σε ορισμένες εκδόσεις του Unix) στο τέλος της απάντησης:
Login: dds Name: Diomidis Spinellis Directory: /home/dds Shell: /bin/bash On since Wed Jun 30 12:18 (EET) on ttyp0 5 minutes 49 seconds idle root:XXXXXXXXXXXXX:0:0:Charlie Root:/root:/bin/bash bin:*:1:1:bin:/bin: daemon:*:2:2:The Devil Himself:/sbin: adm:*:3:4:adm:/var/adm: lp:*:4:7:lp:/var/spool/lpd: ...Για να αποφεύγουμε τέτοια προβλήματα πρέπει: