0

i have a php file that is called from a javascript with the purpose of uploading files to my server.

Clarification that what im doing is calling this php file with ajax, so as i understand it it's not run in the traditional sence, which is why i am not using $_FILE and $_POST as the whole point of this project is to handle fileupload / collection of user data is done without a page reload.

obviously we want some sort of serverside file validation, which i have set up in an if statement.

however the code succeeds and proceeds with the upload no matter what file type i select.

can someone tell me what is wrong / or guide me in the right direction ?

<?php
session_start();

$name = $_SESSION['name'];
$email = $_SESSION['email'];
$phone = $_SESSION['phone'];

$date = date('Y-m-d');

$mypath = $name . '-' . $phone . '-' . $date;

$ext = $_SERVER['HTTP_X_FILE_TYPE'];
$allow = array('psd', 'ai', 'eps', 'svg', 'jpg', 'png', 'docx', 'doc', 'pptx', 'ppt');

if(!in_array($ext,$allow)){
    if(!file_exists($mypath)) {
    mkdir($mypath,0777,TRUE);
    }
    $str = file_get_contents('php://input');

    $title = $_SERVER['HTTP_X_FILE_NAME'];

    $path = "$mypath/".$title;
    file_put_contents($path,$str);
}else{
    return false;
}
?>  

much apreciated - Mr B

MrB
  • 107
  • 8
  • Possible duplicate of [How can I only allow certain filetypes on upload in php?](https://stackoverflow.com/questions/2486329/how-can-i-only-allow-certain-filetypes-on-upload-in-php) – Cemal Mar 09 '18 at 12:58
  • How do you set `$_SERVER['HTTP_X_FILE_TYPE']` ? – Dormilich Mar 09 '18 at 12:58
  • 3
    Shouldn't it be `if(in_array($ext,$allow)){` instead of `if(!in_array($ext,$allow)){` ? – kscherrer Mar 09 '18 at 12:59
  • @Cemal Your duplicate does not add any information that the author did not already consider – Philipp Maurer Mar 09 '18 at 13:00
  • @ Dormilich i am setting the FILE_TYPE in a javascript that is handeling drag and drop events for the fileupload. @Cashbee unfortunately that did not fix the issue, although the code runs, no file is sent to the server, does not matter what type, so sortof the oposite. @ Cemal i will add more information if this helps my cause but i do not see how my code is "completely wrong" when it is functional on my end. – MrB Mar 09 '18 at 13:56
  • @Dormilich i am setting the FILE_TYPE in a javascript that is handeling drag and drop events for the fileupload. – MrB Mar 09 '18 at 14:21
  • @Cemal i will add more information if this helps my cause but i do not see how my code is "completely wrong" when it is functional on my end. – MrB Mar 09 '18 at 14:21
  • 1
    if it is functional and working properly as it is intended, what is your question? – Cemal Mar 09 '18 at 15:10
  • it uploads but it does not check the file extension as i have said in the original post @Cemal – MrB Mar 11 '18 at 15:27
  • As @Cashbee said, it should be `if(!n_array($ext,$allow))` not `if(!in_array($ext,$allow))`. Also unless this is wrapped in a function, using `return` in global scope, though it's usage is not wrong in php syntax, it is wrong in semantical approach. `exit` is more favorable to be used. – Cemal Mar 12 '18 at 20:22

1 Answers1

2

The problem with the code is (Like @Cashbee mentioned in the comments), is with if(!in_array($ext,$allow)) portion of the code. This part allows the file to be uploaded if the file extension is not in $allow array. The correct code should be as below.

<?php
session_start();

$name = $_SESSION['name'];
$email = $_SESSION['email'];
$phone = $_SESSION['phone'];

$date = date('Y-m-d');

$mypath = $name . '-' . $phone . '-' . $date;

$ext = $_SERVER['HTTP_X_FILE_TYPE'];
$allow = array('psd', 'ai', 'eps', 'svg', 'jpg', 'png', 'docx', 'doc', 'pptx', 'ppt');

if(in_array($ext,$allow)){
    if(!file_exists($mypath)) {
    mkdir($mypath,0777,TRUE);
    }
    $str = file_get_contents('php://input');

    $title = $_SERVER['HTTP_X_FILE_NAME'];

    $path = "$mypath/".$title;
    file_put_contents($path,$str);
}else{
    exit;
}
?>

Important Note : Please keep in mind that, trusting an extension based on a header set by a javascript command from browser has a high risk and shouldn't be trusted. If this is required, you must store those files in a folder either inaccessible/restricted from the web and serve them raw with the correct mime header upon request or check more than file extension on upload.

Cemal
  • 1,469
  • 1
  • 12
  • 19
  • wont be able to test this before the weekend, but i still have some questions when you say header, are you refering to the HTTP_X_FILE_TYPE ?, and what else would you recomend is used for verification on upload ? – MrB Mar 15 '18 at 07:50
  • yes I'm referring to `HTTP_X_FILE_TYPE` as point of problems. In an ideal world this may be right, but in real world, it's highly insecure. I can suggest you to either verify the files that they are indeed the type of files that the extension says. (You can check most image files by opening them with [Imagick](http://php.net/manual/en/book.imagick.php). If they can be parsed by imagick, you can save them on your server, if not simply delete them.) or you can store them in a folder where it's not accesible by web server – Cemal Mar 15 '18 at 07:55
  • i have tried the code now, without success, i get no error code so obviously the syntax is correct, however no file arrives on the server – MrB Mar 19 '18 at 15:25
  • Have you checked and verified that you have write permissions on the folder that you are uploading? – Cemal Mar 19 '18 at 16:33
  • without if statement, the files upload straight away without issue @Cemal – MrB Mar 21 '18 at 14:55
  • Well if the `if` statement is not working then the problem is with `$ext = $_SERVER['HTTP_X_FILE_TYPE']` . Can you please do `die(print_r($_SERVER));` and check the value of `HTTP_X_FILE_TYPE` if it is not set or empty, the if will not let it upload. – Cemal Mar 21 '18 at 14:59
  • there seem to be other issues at hand here as well ill give you the answer as the above code is correct but the issue seems to be that the page isnt "run" if that makes sence. – MrB Mar 23 '18 at 12:02