Dateidownload

Fragen zu PHP.
Fragen zu we:Tags bitte im Forum webEdition Templates erstellen (we:Tags) posten.
p.hintermayer
Junior Member
Beiträge: 3
Registriert: Di 19. Mär 2013, 10:29
Wohnort: Karlsruhe

Dateidownload

Beitragvon p.hintermayer » Di 19. Mär 2013, 10:39

Da ich für einen unseren Kunden ein kleinen Dateidownload für webEdition realisiert habe, teile ich mein Snippet mit anderen - vielleicht benötigt es ja der ein oder andere.

Funktion: Anhand der File ID holt er sich die entsprechenden Informationen aus der Datenbank, setzt die Header und "fordert" den Browser zum Dateidownload auf.
Es wird überprüft, ob es eine Datei und kein Ordner ist, die Datei veröffentlicht wurde und die Datei durchsuchbar ist (Hauptkriterium zur Beschränkung).

PHP Code:

Code: Alles auswählen

/**
 * check, if passed key is a valid integer
 */

$file_id = filter_var(key($_GET), FILTER_SANITIZE_NUMBER_INT);

if(empty($file_id) === false)
{
    /**
     * get file information from database
     * Crits: Searchable, no folder, published
     */
    
    $sql = '
    SELECT
        *
    FROM
        `tblFile`
    WHERE
        `ID` = ' . $db->real_escape_string($file_id) . '
    AND
        `IsSearchable` = 1
    AND
        `IsFolder` = 0
    AND
        `Published` != 0
    LIMIT 1;';
    
    $result = $db->query($sql);
    
    
    /**
     * check, if entry exists
     */
    
    if($result->num_rows === 1)
    {
        $data = $result->fetch_assoc();
        
        $file = $_SERVER['DOCUMENT_ROOT'] . $data['Path'];
        
        /**
         * check if file exists
         */
        
        if(is_file($file))
        {
            $contentType = $data['ContentType'];

            if(substr($contentType, -1) === '*')
            {
                $contentType = substr($contentType, 0, -1) . substr($data['Extension'], 1);
            }

            /**
             * output the file
             */
            
            header('Content-Type: ' . $contentType);
            header('Content-Transfer-Encoding: binary');
            header('Content-Length:' . filesize($file));
            header('Content-Disposition: attachment; filename=' . $data['Filename']);
            
            readfile($file);
        }
        else 
        {
            echo 'file not found.';
        }
    }
    else 
    {
        echo 'file not found.';
    }
}
Beispieleinsatz: <a href="/download.php?123" title="Download">Download</a>

p.hintermayer
Junior Member
Beiträge: 3
Registriert: Di 19. Mär 2013, 10:29
Wohnort: Karlsruhe

Re: Dateidownload

Beitragvon p.hintermayer » Mi 20. Mär 2013, 11:24

Da ich den 1. Beitrag nicht editieren kann, folgt das Update nun in diesem Post.

Änderungen zum 1. Post: webEdition Seiten sind ausgenommen, SQL basierend, file key implementiert

Code: Alles auswählen

/**
 * check, if passed key or value of index file is a valid integer
 * example: download.php?123 || download.php?file=123
 */

$file_id = filter_var(key($_GET), FILTER_VALIDATE_INT) !== false 
           ? key($_GET) 
           : filter_input(INPUT_GET, 'file', FILTER_SANITIZE_NUMBER_INT);

if(empty($file_id) === false)
{
    /**
     * get file information from database
     * Crits: Searchable, no folder, published, no webEdition page
     */
    
    $sql = '
    SELECT
        IF(RIGHT(`ContentType`, 1) = "*", CONCAT(SUBSTRING_INDEX(`ContentType`, "*", 1), SUBSTR(`Extension`, 2)), `ContentType`) AS `ContentType`,
        CONCAT("' . $_SERVER['DOCUMENT_ROOT'] . '", `Path`) AS `File`,
        `Filename`
    FROM
        `tblFile`
    WHERE
        `ID` = ' . $db->real_escape_string($file_id) . '
    AND
        `ContentType` != "text/webedition"
    AND
        `IsSearchable` = 1
    AND
        `IsFolder` = 0
    AND
        `Published` != 0
    LIMIT 1;';

    $result = $db->query($sql);
    
    
    /**
     * check, if entry exists
     */
    
    if($result->num_rows === 1)
    {
        $data = $result->fetch_assoc();

        /**
         * check, if file exists
         */
        
        if(is_file($data['File']))
        {
            header('Content-Description: File Transfer'); 
            header('Content-Type: ' . $data['ContentType']);
            header('Content-Transfer-Encoding: binary');
            header('Content-Length:' . filesize($data['File']));
            header('Content-Disposition: attachment; filename=' . $data['Filename']);
            
            readfile($data['File']);
        }
        else 
        {
            echo 'file not found.';
        }
    }
    else 
    {
        echo 'file not found.';
    }
}

mokraemer
Senior Member
Beiträge: 3619
Registriert: So 8. Aug 2010, 01:23
Wohnort: Mainz

Re: Dateidownload

Beitragvon mokraemer » Mi 20. Mär 2013, 21:58

kleine Anmerkung:
wenn du $db->real_escape_string durch intval() ersetzt, sparst du dir die DB connection
In der Vorlage kannst du getHash('SELECT..',$GLOBALS['DB_WE']); nutzen, dann hast du auch gleich noch die WE Fehlerbehandlung etc. drin.
webEdition-Kern-Entwickler

p.hintermayer
Junior Member
Beiträge: 3
Registriert: Di 19. Mär 2013, 10:29
Wohnort: Karlsruhe

Re: Dateidownload

Beitragvon p.hintermayer » Do 21. Mär 2013, 11:20

wenn du $db->real_escape_string durch intval() ersetzt, sparst du dir die DB connection
Nein, das wäre eine Sicherheitslücke, da dadurch Hex Injections möglich wären.

WBTMagnum
webEdition Partner
webEdition Partner
Beiträge: 1825
Registriert: Di 7. Mär 2006, 16:50
Wohnort: Wien
Kontaktdaten:

Re: Dateidownload

Beitragvon WBTMagnum » Do 21. Mär 2013, 16:41

p.hintermayer hat geschrieben:Nein, das wäre eine Sicherheitslücke, da dadurch Hex Injections möglich wären.
Bist du dir da sicher? Dazu habe ich jetzt nichts gefunden. Auf stackoverflow sehen sie hier auch kein Problem: http://stackoverflow.com/questions/3208 ... base-input

LG,
Sascha

mokraemer
Senior Member
Beiträge: 3619
Registriert: So 8. Aug 2010, 01:23
Wohnort: Mainz

Re: Dateidownload

Beitragvon mokraemer » Do 21. Mär 2013, 20:03

glaube ich auch nicht - und was bitte sollen "Hex Injections" sein?
Ich kann bei dir beliebige Zahlen übergeben - ob ich die nun als Hex-Wert oder Zahl übergebe ist dann egal. Für die Query steht dann da eine Zahl - sprich dort kommt das gleiche raus und du brichst nicht aus dem SQL aus.
webEdition-Kern-Entwickler


Zurück zu „PHP“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste