Completed
Pull Request — master (#137)
by Philipp
04:15
created

download.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
// Copyright (C) 2014-2016 Universitätsbibliothek Mannheim
3
// See file LICENSE for license details.
4
5
// This action requires an authorized user.
6
require_once('auth.php');
7
8
// a valid request has to contain a file to be downloaded
9
if (!isset($_GET['file']) || empty($_GET['file'])) {
10
    header('Bad Request', true, 400);
11
    exit();
12
}
13
14
// avoid directory traversal vulnerability
15
$filename = basename($_GET['file']);
16
17
// Connect to database and get configuration constants.
18
require_once('DBConnector.class.php');
19
20
$filepath = CONFIG_UPLOAD_DIR . '/' . $filename;
21
22
if (file_exists($filepath)) {
23
    // file exists: return file for download
24
    header('Content-Type: application/octet-stream');
25
    header('Content-Disposition: attachment; filename="' .
0 ignored issues
show
Security Response Splitting introduced by
'Content-Disposition: at...lashes($filename) . '"' can contain request data and is used in response header context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_GET, and $_GET['file'] is escaped by basename() for file context(s), and $filename is assigned
    in download.php on line 15
  2. $filename is escaped by addslashes() for sql, xpath context(s)
    in download.php on line 26

Response Splitting Attacks

Allowing an attacker to set a response header, opens your application to response splitting attacks; effectively allowing an attacker to send any response, he would like.

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
26
           addslashes($filename) . '"');
27
    readfile($filepath);
28
} else {
29
    // file does not exist: 404 Not Found
30
    header('Not Found', true, 404);
31
    exit();
32
}
33