I'm trying to replace the contents of a file in a different folder than my php file folder, and I'm getting an error: "Failed to open stream, Permission Denied"
I'm using the put_file_contents function to change the file contents. I searched online for a solution to this problem and found that the file directory is allowed to be written only by the owner/user. I checked directory properties in filezilla (ftp), and found that the directory was not writable by group or public.
In filezilla, I tried allowing the directory to be written by public, and the php file was able to write to the folder's file.
Therefore, I think I can easily set the permissions to the file only, and not the directory, and easily replace it's content by setting the permission as writable by public. Although I don't understand what owner/group/public options mean? Cause this is supposed to be a website's webserver hosted on a paid domain host, and I'm not sure if the public write option is safe or not, or why would there be user groups for a webserver hosting only a single website?
Since only a php file can change the contents on a webserver, why is a public option provided for a webserver? If it's for uploads, then that too means the upload page resides on the server! I cannot access the terminal on ftp or cpanel therefore I cannot execute chmod etc...
Please could someone provide more detail regarding security risks to files with public write permissions?
A server is still a computer, like any of them. This means that you can create several users, and that a lot of things can happen.
Your server might not necessarily stay only a web server. Obviously it is also an FTP server, and you probably also can access it using ssh. In the future you might want to use it for another purpose.
In any case, even if you use it just as a web server, setting a folder's permission as writable to the every user is dangerous, because of the security risks that your code most inevitably will have. It can act as a safeguard : even if you write something dangerous in the future, it contains the damage.
That is the reason why on some systems, the software responsible for serving http requests (typically Apache) runs as a specific user httpd.
User groups is just what it says it is : defined groups of users. You can read about it easily online.
Related
On of my client approached me to check and fix the hacked site. Site was developed by another developer , Very inexperienced developer not even basic security taken care of.
Well the problem was somehow PHP files were written to the images folder. Hackers also wrote an index.html which displays site is hacked. When I check images folder has 777 permissions. So I came to rough conclusion that its because of folder permissions. Hosting support guy says that some PHP file has poorly written scripts which allowed any extension file to upload to server, and then hackers executed files to gain access or do whatever they want.
I have few questions:
Is it only through upload functionality can we upload other PHP files ?
Is it not possible other way to write files from remote as folder permissions are 777?
Sit has some fckeditors editors and couple of upload functionalities. I checked them, there are enough validations , so when extensions other then images or PDF are tried to upload they just return false .
Does'nt setting folder permissions to lower level fix the issue?
I asked the support guy to change folder permissions and it would solve the issue, but he says there is some PHP file through of which other PHP files were written and he wants that to be fixed otherwise site cannot go live. He says even folder permissions are changed hacker can again change them to 777 and execute whatever he wants because that poorly written PHP file.
How should be my approach to find if there is such PHP file? Any help or pointers would be much appreciated.
777 means that any user on the system (with execute access for all the parent directories, anyway) can add anything to that directory. Web users are not system users, though, and most web servers (Apache included) won't let random clients write files there right out of the box. You'd have to specifically tell the server to allow that, and i'm fairly certain that's not what happened.
If you're allowing any file uploads, though, the upload folder needs to at least be writable by the web server's user (or the site's, if you're using something like suPHP). And if the web server can write to that directory, then any PHP code can write to that directory. You can't set permissions high enough to allow uploads and low enough to keep PHP code from running, short of making the directory write-only (which makes it pretty useless for fckeditor and such).
The compromise almost certainly happened because of a vulnerability in the site itself. Chances are, either there's a file upload script that's not properly checking where it's writing to, or a script that blindly accepts a name of something to include. Since the PHP code typically runs as the web server's user, it has write access to everything the web server has write access to. (It's also possible that someone got in via FTP, in which case you'd better change your passwords. But the chances of the web server being at fault are slim at best.)
As for what to do at this point, the best option is to wipe the site and restore from backup -- as has been mentioned a couple of times, once an attacker has gotten arbitrary code to run on your server, there's not a whole lot you can trust anymore. If you can't do that, at least find any files with recent modification times and delete them. (Exploits hardly ever go through that much trouble to cover their tracks.)
Either way, then set the permissions on any non-upload, non-temp, non-session directories -- and all the existing scripts -- to disallow writes, period...particularly by the web server. If the site's code runs as the same user that owns the files, you'll want to use 555 for directories and 444 for files; otherwise, you can probably get by with 755/644. (A web server would only be able to write those if it's horribly misconfigured, and a hosting company that incompetent would be out of business very quickly.)
Frankly, though, the "support guy" has the right idea -- i certainly wouldn't let a site go live on my servers knowing that it's going to be executing arbitrary code from strangers. (Even if it can't write anything to the local filesystem, it can still be used to launch an attack on other servers.) The best option for now is to remove all ability to upload files for now. It's obvious that someone has no idea how to handle file uploads securely, and now that someone out there knows you're vulnerable, chances are you'd keep getting hacked anyway til you find the hole and plug it.
As for what to look for...unfortunately, it's semi vague, as we're talking about concepts above the single-statement level. Look for any PHP scripts that either include, require, or write to file names derived in any way from $_GET, $_POST, or $_COOKIE.
Changing folder permissions won’t solve the issue unless you’re using CGI, since PHP probably needs to be able to write to an upload folder, and your web server probably needs to be able to read from it. Check the extension of any uploaded files!
(So no, 0777 permissions don’t mean that anyone can upload anything.)
As cryptic mentioned, once a hacker can run code on your server then you have to assume that all files are potentially dangerous. You should not try to fix this yourself - restoring from a backup (either from the client or the original developer) is the only safe way around this.
Once you have the backup files ready, delete everything on your your site and upload the backup - if it is a shared host you should contact them as well in case other files are compromised [rarely happens though].
You've identified 2 issues: the permissions and the lack of extension checking however have you any evidence that these were the means by which the system was compromised? You've not provided anything to support this assertion.
Changing the permissions to something more restrictive would have provided NO PROTECTION against users uploading malicious PHP scripts.
Checking the extensions of files might have a made it a bit more difficult to inject PHP code into the site, it WOULD NOT PREVENT IT.
Restoring from backup might remove the vandalized content but WILL NOT FIX THE VULNERABILITIES in the code.
You don't have the skills your client (whom is probably paying you for this) needs to resolve this. And acquiring those skills is a much longer journey than reading a few answers here (although admittedly it's a start).
Is it only through upload functionality can we upload other PHP files ? Is it not possible other way to write files from remote as folder permissions are 777?
There definitely are multiple possible ways to write a file in the web server’s document root directory. Just think of HTTP’s PUT method, WebDAV, or even FTP that may be accessible anonymously.
Sit has some fckeditors editors and couple of upload functionalities. I checked them, there are enough validations , so when extensions other then images or PDF are tried to upload they just return false .
There are many things one can do wrong when validating an uploaded file. Trusting the reliability of information the client sent is one of the biggest mistakes one can do. This means, it doesn’t suffice to check whether the client says the uploaded file is an image (e.g. one of image/…). Such information can be easily forged. And even proper image files can contain PHP code that is being executed when interpreted by PHP, whether it’s in an optional section like a comment section or in the image data itself.
Does'nt setting folder permissions to lower level fix the issue?
No, probably not. The upload directory must be writable by PHP’s and readable by the web server’s process. Since both are probably the same and executing a PHP file requires only reading permissions, any uploaded .php file is probably also executable. The only solution is to make sure that the stored files don’t have any extension that denote files that are executed by the web server, i.e. make sure a PNG is actually stored as .png.
I'm hosting my website in a shared server, so my options are limited. For instance, I don't have access to the exec function.
My problem is that my very easy addLog PHP function needs rights to write into log files. I had read in another post that the PHP user is usually assimilated as "others" in the traditional UNIX owner-group-other permission scheme.
However, since I built my own www structure, I was thinking of letting my ./log directory's permissions be set to 777 so the script could write to the necessary logs.
The application only needs to be able to write to the log files; no read or execute permissions are necessary. (I don't even know what they are when it comes to UNIX permissions) Additionally, I am not storing any database information in the logs; I may, however, store stack traces.
Is there a security risk to set the log directory's permissions to 777?
There's nothing in this folder except logs.
Are the read and execute rights necessary on this directory?
I only really need to write (append) into the logs.
Remember that it is possible that an application error could contain database login information, query strings, as well as file structure of your application. There may be certain files that you have hidden from users and robots, but are still in the document root. By allowing anybody (777) on the shared environment to view the log (any) files you open yourself to more risk.
If PHP is writing the log it should also be able to read the log, in theory. Bottom line is making the file owner the same user that will be writing to the file. Then use appropriate permissions.
Of course if you are not concerned with anything on your site being secure, and there are no DB connections, it really doesn't matter.
Really depends on the shared environment. I have seen poorly set up shared hosting where users are able to FTP traverse and view others files/folders. 777 is not a good idea on shared hosting. (Better to be safe, than sorry)
Is it possible to restrict PHP's file access to its document root? Basically on my work's server we have our domains in a file structure like:
/home/something/domains/domain1/
/home/something/domains/domain2/
/home/something/domains/domain3/
Right now, any script on domain1 has read and write access to anything in /home/something/domains/ including all of our other domains. I would like to restrict file access for a script in domain1 to only that domain.
The server is hosted with mediatemple and it is their grid service, so I don't have root access or even vhost config access. We can change php.ini, and i know it offers open_basedir, but it doesn't sound like that solves my problem as I could only restrict file access to /domians/ and not the individual domains. Any help appreciated.
What I'm really trying to do:
This server was recently hacked, and the hackers were overwriting domains/.htaccess which affected all our sites. We have tons of sites and many of them have lots of lines of bad code. They uploaded WSO, a hacking backdoor/shell which gave them full access to everything. I don't know how they got access, I guess it was either from the timthumb exploit, one of the millions of lines of bad code, or they just got our FTP password somehow. We updated old timthumbs, changed the password and removed all the bad files we found, but since there is a decent chance whatever exploit they found is still on the server, or that we missed some backdoor, I would at least like to limit their access to the actual domain that contains the exploit or unfound backdoor.
My initial thought was to set open_basedir for each of the virtual hosts (even if you have to ask your host admin to do it for you), but I am doubtful that will even work because I am fairly certain external/shell commands that run in PHP/scripts will still work on directories outside of the designated tree.
After more consideration, the closest way to configure your setup and get what you want, that I could think of, would be to set up chroot-jailed user accounts for each vhost and have your webserver use those user accounts through a mechanism like the Apache 2 MPM ITK, which I can only assume your hosting provider will have trouble setting up.
i have to admit, i never really completely got the *nix filesystem permission model. oh, the rwxrwxrwx stuff isn't too complicated, but i get confused easily when programs create new files and how i can handle them.
my current problem is the mixture of a (closed source) java-applet that does file uploads over ftp and php (it's on a dedicated server and the data isn't really critical, so i'm not all too concerned about world-writeability).
so, i have two users: ftp (1000) and apache/php (81). groups don't match, so they're basically "others", if i'm correct.
an "import" directory, set to 0777 owned by ftp.
if a visitor acesses the upload page, a subdirectory named after his username is created by my script. let's say, the visitors username is "foo", so it's "import/foo", set to 0777, user 81/php.
next, the visitor uses the java applet to upload a file to this directory (test.jpg). the file's permissions are now rw-r--r--, user ftp.
first question
the first thing i don't understand is: i'm able to unlink that file through php.
why? the users don't match, and the file isn't world writeable.
is this because of the parent directories world-write permission? understandably, i can't chown or chmod through php.
so far no problem, because as long as i can read and unlink, everythings ok.
second question
the java applet is able to upload whole directories, which is nice. if i do this, the new subdirectory import/foo/test has permissions rwxr-xr-x/ftp. the files in this directory are rw-r--r--/ftp.
now i'm out of luck. i can't do anything with those files (besides reading, which i do successfully), no unlinking, no chmod/chowning. they just sit around and gobble up diskspace.
so, what's the plan behind the default-permissions new files have? my guess is they have the permission set through umask, as long the creating script doesn't chmod them to something else. am i right?
third question
what can i do about it? i mean, what would a sensible person do? can i/should i change the umask for the ftp user? (i just learned about umask yesterday). i'm not very comfortable with this, as this would affect all ftp traffic, doesn't it? also, the server is dedicated but i'm not an admin, so my access is restricted.
i just had another idea. before starting this post i read up on the basic linux permission stuff. first, the sticky bit isn't set anywhere in the directory chain. and then, there it was: the "set user ID bit".
so, my current plan is to write a simple shell script with owner ftp that is other-executable with setuid. the script just transfers the file in the import directories ownership to user php.
then, after each import i just exec() that file from my php-script and process files further.
would that work? and more important: is that clean and legal? or would the sysadmin put a bounty on my head?
thx a lot!
update: i just tried to set the uid bit (4755) through winscp (through an ftp connection), but it somehow doesn't work - it seems to "forget" only the uid bit (the other bits get set). why is that? why can't the owner set the uid himself? is that server-specific or generally the case?
update 2:
wikipedia says it all
Due to the increased likelihood of security flaws, many operating systems ignore the setuid attribute when applied to executable shell scripts.
is it still possible for user root to set the uid-bit?
First answer
Correct, you have permission to modify the directory so you can unlink the file. Whether that file is readable or writable to you is irrelevant.
Second answer
Yes you are correct that the user's default umask will be used unless the script/applet then chmods the file permissions to something else
Third answer
Setting the default umask for ftp is the simplest solution, but as you say this affects all files then created by the ftp user. If that user is only used for the upload via the applet (and it should be really) then this isn't really an issue I'd say.
The other option is to have a cron job running that executes a script (like you suggest), chmoding/owning the files (and maybe virus scanning them etc) from the FTP upload area to somewhere on the webroot.
You don't state why having these files readonly to Apache is an issue (or is it the fact that the FTP root isn't under the web root?), maybe clarifying that would help point to a sensible solution? Generally you don't want to trust anything the user has given you unless you've vetted it first.
EDIT - just seen you're not an admin of the machine which makes things difficult.
what i learned today: the setuid bit is often deactivated for scripts.
the solution i've settled on: apache/php gets sudoer-rights for certain scripts (all scripts in one directory outside the webroot) that may run as either the ftp- or apache-user. i can then call those scripts with sudo out of php with system/exec/etc.
i didn't know sudo could be configured in this way. amazing
I have a PHP script that processes file uploads. The script tries to organise the files that are uploaded and may create new folders to move the files into if needed. These files will be below the www root directory (ie, a web browser will be able to access them).
My question is, what permissions should I set for the folders that get created and for the files that are moved into them (using mkdir() and move_uploaded_file())?
Your webserver needs read and write permission in those folders, execute permission should be revoked (assuming UNIX-like systems). If not, a user could upload a script and have it executed by sending a HTTP request for it.
But IMO the whole concept is a potential security hole. Better store the files in a folder outside the webserver root, so that no direct acceess is possible. In your web application, you can have a PHP download page that scans the upload directory and displays a list of download links. These download links lead to another script, that reads the fiels from you storage dir und sends them to the user.
Yes, this is more work. But the scenario is very common, so you should be able to find some source code with example implementations easily. And it it much less work that having your server hacked...
to answer it specifically 766 (no execute permissions) would be the loosest you would want to use. On the other end 700 would allow no one but the web user to mess with the file.
But really it all depends you were doing with the files that would determine the best result.