I want to delete a file by using PHP. I have used the
unlink() function, but I was wondering about the security of
unlink. Is the file completely deleted from the server? I want to make sure that there is no way to get the file back and the file is completely removed from the server.
open the file in binary mode for writing, write 1’s over the entire file, close the file, and then unlink it. overwrites any data within the file so it cannot be recovered.
Personally i would say use 1’s instead of 0’s as 1’s are actual data and will always write, where as 0’s may not write, depending on several factors.
Edit: After some thought, and reading of comments, i would go with a hybrid approach, depending on “how deleted” you want the file to be, if you simply wish to make it so the data cannot be recovered, overwrite the entire files length with 1’s as this is fast, and destroys the data, the problem with this, is it leaves a set length of uniform data on the disk which infers a file USED to be there and gives away the files length, giving vital pieces of forensic information. Simply writing random data will not avoid this also, as if all the drive sectors around this file are untouched, this will also leave a forensic trace.
The best solution factoring in forensic deletion, obfuscation and plausible deniability (again, this is overkill, but im adding it for the sake of adding it), overwrite the entire length of the file with 1’s and then, for HALF the length of the file in bytes, write from
mt_rand in random length sizes, from random starting points, leaving the impression that many files of varying lengths used to be in this area, thus creating a false trail. (again, this is completely overkill and is generally only needed by serial killers and the CIA, but im adding it for the sake of doing so).
the US government used to recommend a seven step wipe, for disks.
1) all ‘1’s
2) all ‘0’s
3) the pattern ’01’
4) the pattern ’10’
5) a random pattern
6) all ‘1’
7) a random pattern,
re the code sample, using a language like PHP is wrong for this type of wipe as your relaying on the OS really wipeing the file and not doing something cleaver like only wipeing it the last time or just unlinking it, however…
$filename = "/usr/local/something.txt"; $size = filesize($filename); $pat1 = chr(0); $pat2 = chr(255); $pat3 = chr(170); $pat4 = chr(85); $mask = str_repeat($pat1, $size); file_put_contents($filename, $mask); $mask = str_repeat($pat2, $size); file_put_contents($filename, $mask); $mask = str_repeat($pat3, $size); file_put_contents($filename, $mask); $mask = str_repeat($pat4, $size); file_put_contents($filename, $mask);
This might not answer HOW to perfectly delete a file “with PHP”, but it answers your question: “Is the file completely deleted from the server ?”
In some cases, No! (on UNIX/POSIX OS).
According to the highest voted comment on the offical PHP unlink() manual page, the unlink function does not really delete the file, it’s deleting the system link to the file’s content ! As files can have several files names (!) [symlinks?] the file will only be deleted when ALL file names are unlinked. So, if your file has 2 names, then unlink() will not really delete the file unless you unlink() both file names. Dear linux guys, please correct me here if necessary.
This might be why the function is called unLINK() and not delete() !!!
Here a full quote of the excellent comment:
Deleted a large file but seeing no increase in free space or decrease of disk usage? Using UNIX or other POSIX OS? The unlink() is not about removing file, it’s about removing a file name. The manpage says:
`unlink - delete a name and possibly the file it refers to''. Most of the time a file has just one name -- removing it will also remove (free, deallocate) thebody’ of file (with one caveat, see below). That’s the simple, usual case.
However, it’s perfectly fine for a file to have several names (see the link() function), in the same or different directories. All the names will refer to the file body and
keep it alive', so to say. Only when all the names are removed, the body of file actually is freed. The caveat: A file's body may *also* bekept alive’ (still using diskspace) by a process holding the file open. The body will not be deallocated (will not free disk space) as long as the process holds it open. In fact, there’s a fancy way of resurrecting a file removed by a mistake but still held open by a process…
Have a look on
unlink()‘s sister function
The (imo) best way to delete a file via PHP:
The way to go to really delete a file with PHP (in linux) is to use the
exec() function, which executes real bash commands (doing things with linux bash feel correct btw). In this case, the file
test.jpg would be deleted by doing:
More info on how to use
rm (remove) correctly can be found for example here. Please note: PHP needs the right to delete the file!
UPDATE: Unfortunatly, the linux
rm command ALSO does not really delete the file if it has two names/links. Look here for more info.
I’ll have a deeper research on that and give feedback…
It is possible that because of some fragmentation on the disk some parts of file will stay, even if the file is totally overwritten.
The other way is to run (by
shell_exec()) external program, that is system specific. Here is an example (for Windows), however I have not tested it.
You should do multiple passes of overwriting to deminish traces. For instance using the US DoD 5220-22.M : “Overwrite all addressable locations with a character, its complement, then a random character and verify” (from killdisk site)
Here’s what the EFF recommends to permanently remove a file http://ssd.eff.org/tech/deletion.
In my embedded Ubuntu device, I use:
echo exec('rm /usr/share/subdirectory/subdirectory/filename'); This works for me.
if you use
rm -f (–force) then linux will
ignore nonexistent files and arguments, never prompt
rm -d will
remove empty directories
If you enter
rm --help at the prompt you get the help screen. The last lines read:
Note that if you use rm to remove a file, it might be possible to recover some of its contents, given sufficient expertise and/or time. For greater assurance that the contents are truly unrecoverable, consider using shred.
Since my system is a “closed” system then I’m not concerned about violating security issues. My logic being that one must have the system password to SSH into the OS and the only user interface is via web pages.
@Sliq’s comments are still true to date. You need to decide for your case.