Jump to content

File upload problems, is FTP needed?


greenace92

Recommended Posts

I pretty much used PHP.net's file upload script verbatim, and I edited PHP.ini to increase max file size/post size.

 

I get error 2 which says file size problem.

 

I called my server provider and they told me to use FTP, I'm not sure if they misunderstood what I was asking. I didn't mean for users on the Linux system. I meant simple HTML <input type=file" /> sort of deal.

 

I could be wrong myself, I don't know, I started to install an FTP server which apparentlt would open port 21. Again unsure if not needed.

 

Nine of the data from $_FILES['fileToUpload']['name'] would show up aside from name.

 

The b- function that removes the ".mp3" from the file name wasn't working. I couldn't get the entire url with the file at the end only the location.

 

Not sure if that makes sense because it hasn't been uploaded yet. Can't get file type either or size.

 

Any help would be appreciated.

Link to comment
Share on other sites

This is what I've got,

 

https://www.cunninghamwebdd.com/brian-music/upload.html

 

This is the error output

AWOLNATION - Woman Woman (Audio)array(5) { ["name"]=> string(32) "AWOLNATION - Woman Woman (Audio)" ["type"]=> string(0) "" ["tmp_name"]=> string(0) "" ["error"]=> int(2) ["size"]=> int(0) } /uploads/music/AWOLNATION - Woman Woman (Audio)

Possible file upload attack!

Here is some more debugging info:Array

(

[fileToUpload] => Array

(

[name] => AWOLNATION - Woman Woman (Audio)

[type] =>

[tmp_name] =>

[error] => 2

=> 0

)

 

)

AWOLNATION - Woman Woman (Audio)

 

0

 

 

 

2

 

 

 

errosint(2)

Choose File upload

Link to comment
Share on other sites

The issue is in the move_uploaded_file is failing, but only because of the / at the beginning of your $uploadfile.

Should be this instead.

$uploaddir = 'uploads/music'; // Notice the removal of the / in front of uploads/music
$uploadfile = $uploaddir.'/' . basename($_FILES['fileToUpload']['name']);

Also, I hope this is just testing code and not actually going to be used on a live website.  There is absolutely zero security in this code, so anyone could literally upload an malicious file they wanted.

Link to comment
Share on other sites

Yes. I haven't implemented the file filter yet. Although I should take if down right away after figuring it out what is wrong. Let me try your solution, thanks for your time and concern.

 

Bad news, still getting the error

 

Out of curiosity what is the absolute worst that can happen with this setup?

 

I'm wondering how else I could test this, local server I suppose.

 

At the same time this is a "throw-away" server in a way.

 

But I'm definitely working on being more secure, and I'm looking to implement the file type, size, name, mime verification on the server side.

Edited by greenace92
Link to comment
Share on other sites

if you read the documentation for that error number, you will find what setting affects it.

 

this will also let you decided if you even want this check to be used, since it was just php doing it's own thing that's not in any way secure from tampering and therefore is pretty meaningless to use.

 

if you don't want to use this particular php feature, just remove the line from the form markup.

Link to comment
Share on other sites

Just remove the max file size input in the html form, it's not needed anyway once you get a proper php security code built.  Are you interested in learning php security for this project or are you simply trying to get a working upload function on your website?  If you just need it wot work, you can pm me and I can give you a good upload class I built that makes it super easy to upload things with proper security.

Link to comment
Share on other sites

Just remove the max file size input in the html form, it's not needed anyway once you get a proper php security code built.  Are you interested in learning php security for this project or are you simply trying to get a working upload function on your website?  If you just need it wot work, you can pm me and I can give you a good upload class I built that makes it super easy to upload things with proper security.

 

I'm trying to learn, there's a lot to know. But it's good, piece by piece. I'm supposed to end up being a "freelance web developer" hahaha

 

I will try to remove, I will laugh so hard if that was the cause of the problem...

 

I dumped the error.log as a person suggested from reddit

 

There were multiple lines of this error, which I've "subdued" by turning off error reports, this was a solution, I can still insert/query databases.

 

[sun Feb 28 06:42:53.485227 2016] [:error] [pid 2965] [client 71.15.4.51:56128] PHP Notice:  Undefined index: fileToUpload in /var/www/html/brian-music/upload/index.php on line 43, referer: https://www.cunninghamwebdd.com/brian-music/upload/

 

Then there was this error which I don't understand, I set the max/post to use Megabytes, and also I read that one is multiplied by the number of total files supported so I've got it set as 15/300MB at the moment for 20 files, which is insane... but what I want is to hit an add button and this gives me a new input, can do with javascript, the problem would be the unique id's but that'll be later.

 

[sun Feb 28 06:26:27.969938 2016] [:error] [pid 2764] [client 71.15.4.51:55769] PHP Warning:  POST Content-Length of 4033831 bytes exceeds the limit of 15 bytes in Unknown on line 0, referer: https://www.cunninghamwebdd.com/brian-music/upload/

 

I get a null when doing var_dump($_POST['fileToUpload']);

Edited by greenace92
Link to comment
Share on other sites

Something did change though... now I'm getting output... most of the lines were blank before

 

I guess this means it went through but I can't find the file, let me try and find it by filetype

NULL Chocolate Puma & Junior Sanchez - Lost your Groove (Clobber Remix).mp3array(5) { ["name"]=> string(70) "Chocolate Puma & Junior Sanchez - Lost your Groove (Clobber Remix).mp3" ["type"]=> string(9) "audio/mp3" ["tmp_name"]=> string(14) "/tmp/php1EJzTo" ["error"]=> int(0) ["size"]=> int(4033462) } uploads/music/Chocolate Puma & Junior Sanchez - Lost your Groove (Clobber Remix).mp3
Possible file upload attack!
Here is some more debugging info:Array
(
    [fileToUpload] => Array
        (
            [name] => Chocolate Puma & Junior Sanchez - Lost your Groove (Clobber Remix).mp3
            [type] => audio/mp3
            [tmp_name] => /tmp/php1EJzTo
            [error] => 0
            [size] => 4033462
        )

)
Chocolate Puma & Junior Sanchez - Lost your Groove (Clobber Remix).mp3

4033462

audio/mp3

0

/tmp/php1EJzTo

errosint(0)
Edited by greenace92
Link to comment
Share on other sites

I don't understand what changed.

 

Was I hacked and then someone fixed it backend?  ::) hahaha

 

Oh man this is great. 

 

Now I gotta take this all down and work on the filtering...

 

I think as far as I have it figured,

 

I check for if it's empty, file type, check if it's a true image, there's a link I've bookmarked on stack overflow regarding potential security problems.

Size for the convenience of the client.

 

I didn't post in /tmp because of the executable shells risk if I understood that correctly, someone mentioned that as well.

 

Thanks for the help to everyone

Link to comment
Share on other sites

post your current code.

 

This is what I've got, I have since taken it down but I've posted two files, a 6 and a 4 MB .mp3 files.

 

Now I have to figure out how to proxy and serve links that can't be accessed at the restricted directory or something like that.

<?php
session_start();

$user = $_SESSION['user'];

if(empty($user)){
    header("Location: https://www.cunninghamwebdd.com/brian-music");
}

// standard error reporting
mysqli_report(MYSQLI_REPORT_ALL);
error_reporting(E_ALL);
error_reporting(1);
ini_set('display_errors',true);
// redirects if session value is empty

// test the file

if($_SERVER['REQUEST_METHOD']=='POST'){

var_dump($_POST['fileToUpload']);

echo basename($_FILES['fileToUpload']['name']);

var_dump($_FILES['fileToUpload']);

$uploaddir = '/uploads/music';
$uploadfile = $uploaddir . '/' . basename($_FILES['fileToUpload']['name']);

echo $uploadfile;

echo '<pre>';
if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}

echo 'Here is some more debugging info:';
print_r($_FILES);

print "</pre>";

echo $_FILES['fileToUpload']['name'].'<br>'.'<br>';
echo $_FILES['fileToUpload']['size'].'<br>'.'<br>';
echo $_FILES['fileToUpload']['type'].'<br>'.'<br>';
echo $_FILES['fileToUpload']['error'].'<br>'.'<br>';
echo $_FILES['fileToUpload']['tmp_name'];
echo '<br>'.'<br>'."erros";
var_dump($_FILES['fileToUpload']['error']);
}

?>

The output from last upload

NULL Chocolate Puma & Junior Sanchez - Lost your Groove (Clobber Remix).mp3array(5) { ["name"]=> string(70) "Chocolate Puma & Junior Sanchez - Lost your Groove (Clobber Remix).mp3" ["type"]=> string(9) "audio/mp3" ["tmp_name"]=> string(14) "/tmp/phpHK71lk" ["error"]=> int(0) ["size"]=> int(4033462) } /uploads/music/Chocolate Puma & Junior Sanchez - Lost your Groove (Clobber Remix).mp3
File is valid, and was successfully uploaded.
Here is some more debugging info:Array
(
    [fileToUpload] => Array
        (
            [name] => Chocolate Puma & Junior Sanchez - Lost your Groove (Clobber Remix).mp3
            [type] => audio/mp3
            [tmp_name] => /tmp/phpHK71lk
            [error] => 0
            [size] => 4033462
        )

)
Chocolate Puma & Junior Sanchez - Lost your Groove (Clobber Remix).mp3

4033462

audio/mp3

0

/tmp/phpHK71lk

errosint(0)
Link to comment
Share on other sites

Great!

When it comes to upload security, there is a crap ton of bad tutorials and bad advice on the web.  There are a number of ways to check an image when uploading, but other files types are a lot more tricky generally.  There might be some mp3 specific classes someone has built that may help in ensuring the file is a mp3 and doesn't contain other malicious stuff.  Honestly I know nothing about mp3 files other than they are music, so I have no idea if malicious code can even be embedded within the file itself like it can in an image file.

 

In the end, don't rely on one tutorial.  You need to research many many of them and take the best notes from them to understand how to protect your site based on what you are doing.

Link to comment
Share on other sites

Great!

When it comes to upload security, there is a crap ton of bad tutorials and bad advice on the web.  There are a number of ways to check an image when uploading, but other files types are a lot more tricky generally.  There might be some mp3 specific classes someone has built that may help in ensuring the file is a mp3 and doesn't contain other malicious stuff.  Honestly I know nothing about mp3 files other than they are music, so I have no idea if malicious code can even be embedded within the file itself like it can in an image file.

 

In the end, don't rely on one tutorial.  You need to research many many of them and take the best notes from them to understand how to protect your site based on what you are doing.

 

Yeah I thought I saw somewhere that a .mp3 file can't have files inside it (or it won't play) other than the music... but I don't know, I'm not sure either.

 

I will definitely read a lot of sources, I'm really trying to be trustworthy/responsible. My worst nightmare would be one of those companies that end up on the news, "simple logic insert, dumps all table rows" or something haha.

 

thanks for your help and everyone else's.

Link to comment
Share on other sites

Trying to “sanitize” MP3 files (or any other file type) is pointless, because the meaning of data depends on the context, and there are infinitely many possible contexts.

 

For example, the exact same PNG file can both be a perfectly valid image and a dangerous PHP. The “<?php” tag is eventually just a sequence of bytes (3c 3f 70 68 70), and those bytes may very well appear in a legitimate PNG file, be it in the metadata or the actual payload. If you remove those bytes, you'll damage the image, and you still haven't done anything about other contexts. What about the other scripting languages on your server? What about client-side scripts? Also note that some browsers like IE will actively work against you and switch contexts through all kinds of weird heuristics.

 

The only chance is a defense-in-depth approach:

  • Check the file extension with a whitelist (you'll probably only want “.mp3”), then generate a random filename and append this extension. Store the original filename in the database.
  • Store the uploaded files outside of the document root and make them available through a proxy script. This script may either do a simple readfile() or use advanced techniques like X-Sendfile.
  • Make sure the files are served with the correct Content-Type header.
  • Use a separate (sub)domain for the proxy script, e. g. tainted.yoursite.com. The same-origin policy will isolate this domain from your main domain, which greatly limits the effects of many attacks against your users.
  • Use Content Security Policy to tell the browser that script execution, form submissions etc. should be disabled for tainted.yoursite.com. Note that this only works in modern browsers, and IE needs special treatment.

Those are just the most basic steps. When you're more experienced, I strongly recommend you also look into more advanced security topics like SELinux or virtualization.

Link to comment
Share on other sites

  • 2 weeks later...

Trying to “sanitize” MP3 files (or any other file type) is pointless, because the meaning of data depends on the context, and there are infinitely many possible contexts.

 

For example, the exact same PNG file can both be a perfectly valid image and a dangerous PHP. The “<?php” tag is eventually just a sequence of bytes (3c 3f 70 68 70), and those bytes may very well appear in a legitimate PNG file, be it in the metadata or the actual payload. If you remove those bytes, you'll damage the image, and you still haven't done anything about other contexts. What about the other scripting languages on your server? What about client-side scripts? Also note that some browsers like IE will actively work against you and switch contexts through all kinds of weird heuristics.

 

The only chance is a defense-in-depth approach:

  • Check the file extension with a whitelist (you'll probably only want “.mp3”), then generate a random filename and append this extension. Store the original filename in the database.
  • Store the uploaded files outside of the document root and make them available through a proxy script. This script may either do a simple readfile() or use advanced techniques like X-Sendfile.
  • Make sure the files are served with the correct Content-Type header.
  • Use a separate (sub)domain for the proxy script, e. g. tainted.yoursite.com. The same-origin policy will isolate this domain from your main domain, which greatly limits the effects of many attacks against your users.
  • Use Content Security Policy to tell the browser that script execution, form submissions etc. should be disabled for tainted.yoursite.com. Note that this only works in modern browsers, and IE needs special treatment.

Those are just the most basic steps. When you're more experienced, I strongly recommend you also look into more advanced security topics like SELinux or virtualization.

 

 

So I followed through your bullet points above:

 

Do I need to replace the original file name with the random-generated name when serving the file? I'm assuming this is security through obscurity? Granted when serving the file, the file initial-uploaded-filename would be reflected by a match through the database.

 

Oh man, I was hoping to make good progress today, looks like I hit a wall.

 

I'm not sure if it was apparent but I intend to have the ability to cycle through songs, (probably using glob) and play them... this is the new wall. I don't know if I'm assuming that I need this thing called "audio wrapper" and music socket or something...

 

I saw SoundManager2 which was suggested to handle playing files... I know that trying to reinvent the wheel wastes time, lowers productivity... but I want to learn how it works/how to make it from scratch... therefore I'm looking at html5 audio tags... ogg...

 

If you have any tips/suggestions from what I've written that's immediately apparent to you, I'd appreciate hearing them.

 

I'm making good progress, I set up the sub domains, I'm trying to figure out this "serve through proxy" as just simply saying below didn't work, white screen. I don't actually know what to expect, from reading the manual/comments it appears that readfile() is for downloading whereas I'm trying to stream... not sure if those are interchangeable since you are downloading to play.

<?php

$src "/uploads/music/7551248c23.mp3";
readfile($src);


?>
Edited by greenace92
Link to comment
Share on other sites

Do I need to replace the original file name with the random-generated name when serving the file? I'm assuming this is security through obscurity? Granted when serving the file, the file initial-uploaded-filename would be reflected by a match through the database.

 

The point of generating random filenames is to prevent new uploads from overwriting previous uploads. Your users won't choose globally unique names, so that's your job.

 

When the files are served, it makes sense to use the original filename.

 

 

 

I'm making good progress, I set up the sub domains, I'm trying to figure out this "serve through proxy" as just simply saying below didn't work, white screen. I don't actually know what to expect, from reading the manual/comments it appears that readfile() is for downloading whereas I'm trying to stream... not sure if those are interchangeable since you are downloading to play.

 

Use the above mentioned X-Sendfile feature so that the webserver can handle range requests for the file.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.