Alexander (HH): Hochgeladene Dateien im ASCII-Format in einer DB speichern

Beitrag lesen

Moin Moin!

Die Dateien werden im ASCII-Zeichensatz (Base64_encode, _decode) in ein Textfeld geschrieben. Damit bin ich unabhängig vom verwendeteten Zeichensatz, den die RDMS spricht (in meinem Fall mySQL).

Und Du hast 33% Overhead.

Das kann ich nicht nachvollziehen. Die ASCII-Datei ist exact genauso groß wie die binary-Datei.

Dann ist Dein Base64-Encoder eine Attrappe. Base64 erzeugt per Definition aus drei Eingangsbytes vier Ausgangsbytes, das sind 33% Overhead.

  • Content-Type liefert der User-Agent,

Und dem glaubst und vertraust Du? Was hältst Du davon, dass Dir mein User-Agent ein nettes Binary mit C-T=text/plain liefert? Anschließend lädt es ein Internet Explorer herunter, schaltet dank Microsofts "Wir wissen alles besser"-Mentalität auf Heuristik um und meint, das Binary sei ein Executable, dass jetzt unbedingt ausgeführt werden muß.

  • Dateigröße ist nach base64_encode genauso groß.

sub upload{
my $fqd_filename = $q->param('file') or cgiError("Keine Datei","Backbutton...");
fileparse_set_fstype("MSDOS");
my ($ori_filename, $local_path) = fileparse $fqd_filename;
my $mime_type = $q->uploadInfo($fqd_filename)->{'Content-Type'};
my ($str,$buffer,$sum,$bytesread);
while ( $bytesread = read($fqd_filename,$buffer,1024)) {
   $str .= $buffer;
   $sum += $bytesread;

cgiError("Datei zu dick") if $sum > $maxsize;
}
$sum or cgiError("0 Bytes, Abbruch","Backbutton...");
$str = encode_base64($str);

  
An dieser Stelle muß length($str) etwa 1.3\*$sum sein, sonst ist encode\_base64() kaputt.  
  

> ~~~perl
  

>  $description = $dbh->quote($description);  
>   
>  $dbh->do("INSERT INTO filebase VALUES('', '$ori_filename', $description, '$sum', '$mime_type', '$str')") or cgiError($dbh->errstr);  
> 

NEIN, NEIN, NEIN!

Du baust hier ein riesiges Sicherheitsloch. Vergiß, dass es so etwas wie $dbh->quote() überhaupt gibt. Benutze Platzhalter. Die sind sicherer und schneller.

  
$dbh->do(  
  'insert into filebase values(?,?,?,?,?,?)',  
  undef, # DBI-Altlast  
  '',$ori_filename,$description,$sum,$mime_type,$str  
) or cgiError($dbh->errstr);  

Angriffsvektoren für SQL Injection in dem bißchen Code, das Du gepostet hast: $ori_filename und $mime_type. Beide kommen direkt ungefiltert vom Client.

Den Taint-Modus, der die gröbsten Sicherheitsprobleme unterbindet, hast Du vermutlich nicht angeschaltet. Und strict und warnings vermutlich auch nicht.

(Die Intranet-Ausrede zählt nicht: 75 bis 90 Prozent aller Angriffe kommen von innen.)

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".