3

I'm currently trying to use the cURL executable to upload mp4 Files to a php script using the POST method. In the PHP file I'm checking the File format and all that kind of stuff. Here's the PHP file:

<?php $allowedExts = array("jpg", "jpeg", "gif", "png", "mp3", "mp4", "wma"); $extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION); if (($_FILES["file"]["type"] == "video/mp4") && ($_FILES["file"]["size"] < 2000000) && in_array($extension, $allowedExts)) { if ($_FILES["file"]["error"] > 0) { echo "Return Code: " . $_FILES["file"]["error"] . "<br />"; } else { echo "Upload: " . $_FILES["file"]["name"] . "<br />"; echo "Type: " . $_FILES["file"]["type"] . "<br />"; echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />"; echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />"; if (file_exists("upload/" . $_FILES["file"]["name"])) { echo $_FILES["file"]["name"] . " already exists. "; } else { move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]); echo "Stored in: " . "upload/" . $_FILES["file"]["name"]; } } } else { echo "Invalid file"; } ?> 

When I upload files using a normal HTML form it works properly. This is the HTML form i used:

<!DOCTYPE html> <head> <title></title> </head> <body> <form action="upload_file.php" method="post" enctype="multipart/form-data" name="uploadedfile"> <label for="file"><span>Filename:</span></label> <input type="file" name="file" id="file" /> <br /> <input type="submit" name="submit" value="Submit" /> </form> </body> </html> 

But when I now try it using the cURL Client using this command:

"curl -F [email protected] http://localhost:1337/upload_file.php"

It displays me "Invalid File" in the console, which is normally shown when the file doesnt match the attributes im checking in PHP(for example not fitting the file type).

I hope you guys understand my problem and can help me! :)

Greets Steven

2
  • 1
    So ... have you done any debugging? Which of the conditions in if (($_FILES["file"]["type"] == "video/mp4") && ($_FILES["file"]["size"] < 2000000) && in_array($extension, $allowedExts)) fails? Commented Jun 25, 2016 at 22:39
  • Well thats the point, usually none of them should fail since when i upload the same file via the HTML form it works properly. Commented Jun 26, 2016 at 7:38

2 Answers 2

2

Your $_FILES["file"]["type"] check is failing because cURL doesn't make any guesses to the type and won't send that automatically in the POST request.

This is easily spoofed so it's not a great check anyway.

But to make your example work, try specifying the content type with the file parameter:

curl -F [email protected];type=video/mp4 http://localhost:1337/upload_file.php 
Sign up to request clarification or add additional context in comments.

3 Comments

It worked, thanks a lot! :) May I ask what you mean by "easily spoofed"? Does that mean people can still upload none MP4 Files to the Server, while using this script?
Since there is no check of the actual file content, I could put PHP in a .mp4 file, spoof the content type (like we did in the cURL request above) and get it to upload. It still might not be possible to get the file to execute as PHP code though because of the extension. curl -F [email protected];type=whatever/i-want ... = easily spoofed
I have just been doing some research and added a content check via finfo_file($finfo, $_FILES["file"]["tmp_name"]) == "video/mp4" if I understand the function right then people should only be able to upload mp4 file now, right? P.S:$finfo = finfo_open(FILEINFO_MIME_TYPE);
1

Further to what drew010 wrote (I'd write a comment but don't have the reputation yet), trusting those values passed in may actually be a security risk and has been used to hack sites in the past so be careful.

5 Comments

Thanks for the tip, but what do you mean by that? Does it mean people can still upload none mp4 files to the server?
Well, you check the extension which helps as well but it all depends on how the OS or other software handles the files also. I believe on I heard of was uploading php as image/png (where image/* was allowed) and the server was also configured such that the image upload directory could have PHP scripts (not uncommon).
But to answer your question, yes, people will be able to upload non-mp4 files to the server so you'll want to assess the risk of that.
I have just been doing some research and added a content check via finfo_file($finfo, $_FILES["file"]["tmp_name"]) == "video/mp4" if I understand the function right then people should only be able to upload mp4 file now, right? P.S: $finfo = finfo_open(FILEINFO_MIME_TYPE);
I would be comfortable relying on that. Though attackers are always coming up with new exploits. The ultimate would be to transcode the video but that might not be appropriate.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.