Certain mp3 files create zip error - php

I've been trying to make a zip archive for some mp3s. The problem I have is that some of the mp3s just break the zipping process, in bizarre ways. If I don't include one of these files everything is fine; if I put one of them in then it goes pear-shaped.
Ultimately, I want to put the zip file on my server for people to download, and I would like to make it on the fly using php. If I don't include any of my problematic files in the archive, it works fine. If I do, then I get a '500 internal server error', but nothing in the server error log. By creating my own error log for every step of the process, it's at the point I try and do zip->close that it seems to be failing.
I tried taking a step back, and making the zip archive locally using 7zip. If I include a problem file I can do this, but if I upload this zip archive to the server and then download it, the download is corrupt. If I don't include a problem file, it's fine. The same happens with winzip.
In total I have about 100 mp3s, of which about 6 cause this behaviour. They all have the same permissions, they all exist, they're all in the same directory, they're all roughly th same size. I even tried making the mp3 again from the source .wav file - the same thing happened with the new version.
I'm completely stumped. I've searched all over, and can't find any clues whatsoever. Help!!

Several reasons are possible (and they can happen together): (a) buggy code in PHP zip creation - either in your code or in code that does actual compression , (b) text mode used in uploading or downloading the files.
As you see yourself, using 7zip solves the problem with PHP zip, so there must be some error in compression code. Now if you put created ZIPs and they are downloaded as broken, this can mean that the file is provided using text mode.
One of the non-obvious reasons is enabled mbcs functions overloads in PHP. With overloads enabled, strlen and similar functions, when binary data is passed to them, start to produce unexpected results (this is because they treat input as UTF8 strings).

Related

php - What will happen if I overwrite the file itself when it is executing (using ZipArchive)

So as described in question itself, I want to replace the file from which a zip archive is opened and then which is overwriting files with new version.
If still my question is not clear then the thing I want to do is I want to get a zip file from a server and then unzip using CLASS "ZipArchive" and then over write everyfile which is in Zip to destination location, the problem will be the php file by which this thing is happening will gonna be overwritten.
So will the php generate the error or the process will go whatever we want?
On Linux files are not usually locked (see https://unix.stackexchange.com/questions/147392/what-is-advisory-locking-on-files-that-unix-systems-typically-employs) so you can do whatever you want with that file. PHP works with that file in memory so you can overwrite it during it's execution.
But if you will run the script multiple times while the first one is in progress it might load incomplete version and then it will throw some error so it might be wise to make sure that won't happen (using locks) or try to do some more atomic approach.
Windows locks files so I assume you won't be able to extract files the same way there.

Can't open files generated by PHP app on windows

I'm having a problem when I try to open files that were generated by my CMS on my windows machine. It has an upload function that saves the file on a given location (it is on my user folder, where I'm supposed to have all the write and read permissions).
All I can see in that folder is a generic thumbnail, the ones generated by windows for each image type, PNGs and JPEGs in this case. I tried to change de image permissions and set it to the current computer user but it doesn't work. And I'm unable to move these files to another location (upload them to the server via FTP).
I wonder if there is a way to change this behavior.
One thing I noticed is that if I copy and paste those files, I can see its contents normally. I know I can do that to each of them and rename, but there are dozens of images in that folder... don't wanna do the same thing everytime I upload a new image.
Update
This is happening only to the images that were moved (I'm using php's move_uploaded_file function, btw), not to the ones that where generated (croped, resized and so on).
It`s happening because Windows keep file permissions of TEMP folder (usually c:/windows/temp) when moving a file.
To prevent it you need to change "upload_tmp_dir" in "php.ini" to your server directory or set wide permissions to your windows temp folder.
You probably have an error in some php file which is preventing the image from being displayed correctly.
What i would do in order to detect the problem is to comment out the header() calls in the php file responsible for displaying the image and see if there is any output other than the image data.
Inspect the whole output, it only takes a character to break everything, so check if there are no blank lines at the top or bottom of the output. And in case you have an error log, consult that, it will help you trace the problem quickly.
When i have this problem, it's usually a notice or a warning showing up during the process of the image generation, and if you haven't disabled errors from being output to the screen, the notice text will be considered as part of the image data which makes the browser unable to interpret your image.
If you'd like i can take a look closely for you but i would need to see what you are doing in that php file to be able to tell you for sure.

ZIP generated from PHP works with winrar but not others?

I have some PHP code which allows users to submit files.
I then can download the ZIP file. If I use windows with Winrar, it unzips fine, I can open my files and that's all good. I have tested this on multiple computers.
If I don't have winrar and I use the default unzipper in Windows 8 or Windows 7 (or OSX), I get a message which says that the zip file is invalid.
Are there any known issues that I have been unable to find? Does anyone know what could cause this behaviour?
Thanks,
Here is a link to the output zip.
https://www.dropbox.com/s/imvzixl3y3l12l1/TestAreaForMax-aa-57.zip
Without seeing your code and ZIP file nobody will tell for sure, but I recall having similar issue and it appeared my script was throwing some error messages which ended up in produced ZIP archive. Some unzip managed to recover from this, others did not, so I suggest to open your ZIP file in any text editor and see if you got nothing like PHP Warning message in the beginning of the file.
EDIT
Regular zip file starts with "PK". Your file starts with " PK" so unless you are not really need that, remove ?> from PHP script that produces your zip file (and I'd suggest removing this from all scripts) as there's one space somewhere which does what I described above, and most likely it lurks after ?>
If you are in PHP code block, then white space does nothing. But by placing ?> you tell PHP when your scripts ends. And outside PHP code block, white space is just being sent to the client. So if you keep ?> and the space is after it then it will be sent. And if output of your script is something downloadable, said space will "join" the byte stream user saves. By removing ?> you are not telling explicitly PHP where your code ends, and in that case it will automatically end with end of source file. And white space is a bitch to track as usually it is "invisible" due to editor settings (and for that reason I set my syntax highlighting to show spaces in different color than background color is)
In general, for reason above, it is always good NOT use ?> if you do not mix PHP code with anything (i.e. HTML). It always help to configure your editor to auto-trim trailing whitespaces on save

php code turned gibberish?

I went to edit this PHP file - it's supposed to generate those captcha security images on contact forms - the images werent working, so I was going to see if there was a broken path or something i could fix simply.
But when I opened the file it looked like this:
http://mydomainsample.com/explosion/screenshots/Screen%20Shot%202012-05-17%20at%209.34.14%20AM.png
complete gibberish.
Is it possible this happened somehow while downloading the file from the server? I did not have ftp access to the site originally - we got control of the domain and transferred it from one host to another.
I used site sucker to backup the site before transferring, but it downloads php files as html files. you end up with filename.php.html.
in the past this has never turned the php into incomprehensible gibberish, so i dont understand why it did now.
The problem is, you cannot use programs like "site sucker" to get PHP files. This is because when you get a PHP file from a URL, the file is executed, and you're getting the output of the script. That's why you get .php.html.
It doesn't "turn the php into incomprehensible gibberish", the server runs the script and you're getting the output. Most of the time the output is HTML, which you can open as text. In this case, the script's output is a PNG file, thus why you see "gibberish". Rename the file to .png, then you'll see the image.
You need to get FTP access in order to get the PHP source.
That's a PNG image, not PHP source code.
The file actually looks like a PNG image, maybe you just downloaded output the PHP script has generated?

Stop people uploading malicious PHP files via forms

I have an upload form created in php on my website where people are able to upload a zip file. The zip file is then extracted and all file locations are added to a database. The upload form is for people to upload pictures only, obviously, with the files being inside the zip folder I cant check what files are being uploaded until the file has been extracted. I need a piece of code which will delete all the files which aren't image formats (.png, .jpeg, etc). I'm really worried about people being able to upload malicious php files, big security risk! I also need to be aware of people changing the extensions of php files trying to get around this security feature.
This is the original script I used http://net.tutsplus.com/videos/screencasts/how-to-open-zip-files-with-php/
This is the code which actually extracts the .zip file:
function openZip($file_to_open) {
global $target;
$zip = new ZipArchive();
$x = $zip->open($file_to_open);
if($x === true) {
$zip->extractTo($target);
$zip->close();
unlink($file_to_open);
} else {
die("There was a problem. Please try again!");
}
}
Thanks, Ben.
Im really worried about people being able to upload malicious php files, big security risk!
Tip of the iceberg!
i also need to be aware of people changing the extensions of php files trying to get around this security feature.
Generally changing the extensions will stop PHP from interpreting those files as scripts. But that's not the only problem. There are more things than ‘...php’ that can damage the server-side; ‘.htaccess’ and files with the X bit set are the obvious ones, but by no means all you have to worry about. Even ignoring the server-side stuff, there's a huge client-side problem.
For example if someone can upload an ‘.html’ file, they can include a <script> tag in it that hijacks a third-party user's session, and deletes all their uploaded files or changes their password or something. This is a classic cross-site-scripting (XSS) attack.
Plus, thanks to the ‘content-sniffing’ behaviours of some browsers (primarily IE), a file that is uploaded as ‘.gif’ can actually contain malicious HTML such as this. If IE sees telltales like (but not limited to) ‘<html>’ near the start of the file it can ignore the served ‘Content-Type’ and display as HTML, resulting in XSS.
Plus, it's possible to craft a file that is both a valid image your image parser will accept, and contains embedded HTML. There are various possible outcomes depending on the exact version of the user's browser and the exact format of the image file (JPEGs in particular have a very variable set of possible header formats). There are mitigations coming in IE8, but that's no use for now, and you have to wonder why they can't simply stop doing content-sniffing, you idiots MS instead of burdening us with shonky non-standard extensions to HTTP headers that should have Just Worked in the first place.
I'm falling into a rant again. I'll stop. Tactics for serving user-supplied images securely:
1: Never store a file on your server's filesystem using a filename taken from user input. This prevents bugs as well as attacks: different filesystems have different rules about what characters are allowable where in a filename, and it's much more difficult than you might think to ‘sanitise’ filenames.
Even if you took something very restrictive like “only ASCII letters”, you still have to worry about too-long, too-short, and reserved names: try to save a file with as innocuous a name as “com.txt” on a Windows server and watch your app go down. Think you know all the weird foibles of path names of every filesystem on which your app might run? Confident?
Instead, store file details (such as name and media-type) in the database, and use the primary key as a name in your filestore (eg. “74293.dat”). You then need a way to serve them with different apparent filenames, such as a downloader script spitting the file out, a downloader script doing a web server internal redirect, or URL rewriting.
2: Be very, very careful using ZipArchive. There have been traversal vulnerabilities in extractTo of the same sort that have affected most naive path-based ZIP extractors. In addition, you lay yourself open to attack from ZIP bombs. Best to avoid any danger of bad filenames, by stepping through each file entry in the archive (eg. using zip_read/zip_entry_*) and checking its details before manually unpacking its stream to a file with known-good name and mode flags, that you generated without the archive's help. Ignore the folder paths inside the ZIP.
3: If you can load an image file and save it back out again, especially if you process it in some way in between (such as to resize/thumbnail it, or add a watermark) you can be reasonably certain that the results will be clean. Theoretically it might be possible to make an image that targeted a particular image compressor, so that when it was compressed the results would also look like HTML, but that seems like a very difficult attack to me.
4: If you can get away with serving all your images as downloads (ie. using ‘Content-Disposition: attachment’ in a downloader script), you're probably safe. But that might be too much of an inconvenience for users. This can work in tandem with (3), though, serving smaller, processed images inline and having the original higher-quality images available as a download only.
5: If you must serve unaltered images inline, you can remove the cross-site-scripting risk by serving them from a different domain. For example use ‘images.example.com’ for untrusted images and ‘www.example.com’ for the main site that holds all the logic. Make sure that cookies are limited to only the correct virtual host, and that the virtual hosts are set up so they cannot respond on anything but their proper names (see also: DNS rebinding attacks). This is what many webmail services do.
In summary, user-submitted media content is a problem.
In summary of the summary, AAAARRRRRRRGGGGHHH.
ETA re comment:
at the top you mentioned about 'files with the X bit set', what do you mean by that?
I can't speak for ZipArchive.extractTo() as I haven't tested it, but many extractors, when asked to dump files out of an archive, will recreate [some of] the Unix file mode flags associated with each file (if the archive was created on a Unix and so actually has mode flags). This can cause you permissions problems if, say, owner read permission is missing. But it can also be a security problem if your server is CGI-enabled: an X bit can allow the file to be interpreted as a script and passed to any script interpreter listed in the hashbang on the first line.
i thought .htaccess had to be in the main root directory, is this not the case?
Depends how Apache is set up, in particular the AllowOverride directive. It is common for general-purpose hosts to AllowOverride on any directory.
what would happen if someone still uploaded a file like ../var/www/wr_dir/evil.php?
I would expect the leading ‘..’ would be discarded, that's what other tools that have suffered the same vulnerability have done.
But I still wouldn't trust extractTo() against hostile input, there are too many weird little filename/directory-tree things that can go wrong — especially if you're expecting ever to run on Windows servers. zip_read() gives you much greater control over the dearchiving process, and hence the attacker much less.
First you should forbid every file that doesn’t have a proper image file extension. And after that, you could use the getimagesize function to check whether the files are regular image files.
But furthermore you should be aware that some image formats allow comments and other meta information. This could be used for malicious code such as JavaScript that some browsers will execute under certain circumstances (see Risky MIME sniffing in Internet Explorer).
You should probably not rely just on the filename extension, then. Try passing each file through an image library to validate that its really an image, also.
I don't see the risk in having renamed php files in your DB...
As long as you're not evaluating them as PHP files (or at all, for that matter), they can't do too much harm, and since there's no .php extension the php engine won't touch them.
I guess you could also search the files for <?php...
Also: assume the worst about the files uploaded to your machine. Renamed the folder into which you're saving them "viruses" and treat it accordingly. Don't make it public, don't give any file launch permissions (especially the php user), etc.
You might also want to consider doing mime type detection with the following library:
http://ca.php.net/manual/en/ref.fileinfo.php
Now you are relying on your harddrive space for extracting. You can check fileheaders to determine what kind of files they are. there probably libraries for that.
offtopic: isnt it better to let the user select couple of images instead of uploading a zip file. Better for people that don't know what zip is (yes they exist)
If you set php to only parse files ending with .php, then you can just rename a file from somename.php to somename.php.jpeg and you are safe.
If you really want to delete the files, there is a zip library available to php. You could use it to check the names and extensions of all the files inside the zip archive uploaded, and if it contains a php file, give the user an error message.
Personally, I'd add something to the Apache config to make sure that it served PHP files as text from the location the files are uploaded to, so you're safe, and can allow other file types to be uploaded in the future.
Beaware of this Passing Malicious PHP Through getimagesize()
inject PHP through image functions that attempt to insure that images
are safe by using the getimagesize() function
read more here http://ha.ckers.org/blog/20070604/passing-malicious-php-through-getimagesize/
Better for your user logo use gravatar like here used by Stackoverflow ;)
Use getimagesize function.
Full procedure:-
1.) Extract extension of image/uploaded file and then compare extension with allowed extension.
2.) Now create a random string for renaming uploaded file. best idea is md5(session_id().microtime()).It can not be duplicated and if your server is very fast and can process less than a microsecond than use incremented variable and add them with string.
now move that file.
A tip
Disable PHP file processing in upload directory, it will always prevent you from any server side attack and if possible add your htaccess in root directory or in httpd config file and disable htaccess files from there now it solve your maximum problems

Categories