-2

When I upload my images, It's throwing an error. How do I change permission settings of my folder in windows? Is there anything wrong with my code?

//This is my path for storing images. (I am using wamp 2.0)
$targetPath="../artistImages/";

$image=$_FILES['myimage'];
$image['name'] = mysql_real_escape_string($image['name']);
$targetPath.=$image['name'];

if(move_uploaded_file($image['tmp_name'],$targetPath)) {
   $insertQuery="INSERT INTO $tbl_name(ArtistImage)VALUES('".$image['name']."')";                       
   $result=mysql_query($insertQuery) or die("Failed to upload image");
}
else {
   echo "Could not upload file. Check read/write persmissions on the directory";
}
deepz
  • 73
  • 2
  • 10
  • 4
    Telling us you have an error is useless. We need to see the actual error message. Also "how do I change the permissions of a folder in Windows" isn't a programming question, and I've voted to move it to SuperUser. – user229044 Sep 07 '11 at 20:53
  • It doesn't have any sql error. It has some permission error. – deepz Sep 07 '11 at 20:56
  • 1
    Then *tell* us what permission error. That was my whole point. I never even mentioned SQL. – user229044 Sep 07 '11 at 21:00
  • 2
    Your script opens your server to remote compromise by allowing the user to scribble a file ANYWHERE on your server that the webserver UID has write permissions on. The remote filename (`['name']`) is user-specified and trivial to forge. Consider the case where they upload "../../../../../../../../windows/kernel32.dll". IUSER_INET is not likely to have permissions on that, but if it did, there goes your system. – Marc B Sep 07 '11 at 21:01
  • @meagar read/write permission error – deepz Sep 07 '11 at 21:02
  • @Marc B what should I do to solve that forging problem? All I want is my images to be uploaded in my folder, and the path to be saved in mysql – deepz Sep 07 '11 at 21:04
  • 2
    Assuming your mysql table has a integer primary key, use THAT number as the filename. You can store the original user filename in the database (after taking care of injection problems). Insert your DB record first, get the record's ID, do the file move. If any of that fails, delete the db record (or roll back the transaction) and gripe to the user. – Marc B Sep 07 '11 at 21:05
  • I would vote **not** to close this question, this is very relevant to php programming and all the security and other problems that go with that, I have absolutely no idea what this question would do on SU. – Johan Sep 07 '11 at 21:20
  • I'm a php beginner so I have less knowledge of working with all these stuff. Excuse my limited knowledge – deepz Sep 07 '11 at 21:22
  • For what it's worth, I think you asked a good question, with a relevant and short code sample and obvious effort to get the solution. You got it wrong, but that's how you learn. I think this is a very enlightening question, because of the many issues your code has: **dynamic tablenames, allowing users access to the filesystem, how to save files in the first place, permissions** I guess the number of issues is the gripe my fellow SO'ers have, but that's no reflection on you, you just tried to make stuff work. If I could I'd give you more upvotes for effort. How many hours did you spend on this? – Johan Sep 07 '11 at 21:40
  • I started struggling with this code last night. I learnt it from a tutorial. Approximately 4 hours, I guess. – deepz Sep 08 '11 at 12:56

2 Answers2

1

Your are trying to move a file to a path that has been mysql_real_escape_string()ed, which means it could potentially contain backslashes, which obviously will not work (at least, not in the way you expect it to).

Try this:

//This is my path for storing images. (I am using wamp 2.0)
$basePath = "../artistImages/";

$image = $_FILES['myimage'];
$storagePath = $basePath.$image['name'];

if (!is_dir($basePath)) {
  echo "Base path '$basePath' does not exist";
} else if (file_exists($storagePath)) {
  echo "File '$storagePath' already exists";
} else if (!move_uploaded_file($image['tmp_name'], $storagePath)) {
   echo "Could not move file to '$storagePath'. Check read/write persmissions on the directory";
} else {
   $insertQuery = "INSERT INTO `$tbl_name` (`ArtistImage`) VALUES ('".mysql_real_escape_string($image['name'])."')";
   if (!mysql_query($insertQuery)) die("DB insert failed: ".mysql_error());
}

Note that the above code has many error messages in that you would want remove, or at least water down before you put the code into any kind of environment where it would actually be used, but it should help you to debug the code while developing.

EDIT

If you actually do need to change the permissions on a folder, the method for doing it varies greatly between versions of Windows (actually it's pretty much identical for all 2K+ versions, but in some you may have to change some settings to get the correct dialogs to appear) and it would be a question for http://www.SuperUser.com/

DaveRandom
  • 87,921
  • 11
  • 154
  • 174
  • its saying:- Base path '../artistImages/' does not exist. That folder is in my website in www directory. – deepz Sep 07 '11 at 21:13
  • And where in your `www` directory is the above script? What is the URL you are using to access the script? – DaveRandom Sep 07 '11 at 21:18
  • It's this:- C:\wamp\www\Online Video Library. Am I supposed to put that in $basePath ? – deepz Sep 07 '11 at 21:19
  • Well you could, but it does make it less portable... Where is the `artistImages` directory? Is it at `C:\wamp\www\Online Video Library\artistImages` or `C:\wamp\www\artistImages`? As a side note, try and avoid using spaces in your web directory names, it makes life more confusing and, to some degree, your applications less portable... – DaveRandom Sep 07 '11 at 21:25
  • "artistImage" folder is in my website folder (Online Video Library). It's here:- C:\wamp\www\Online Video Library\artistImages – deepz Sep 07 '11 at 21:27
  • 1
    Right, there's your problem. Your `$basePath` should be simply `artistImages/`, or you could also do `./artistImages/` (single dot). In general, a double dot means 'up a directory' and a single dot means 'this directory'. You are working from the directory that contains the images directory, so you don't need to go up a level. It might be worth you skimming through [this](http://en.wikipedia.org/wiki/Path_(computing))... – DaveRandom Sep 07 '11 at 21:32
  • ./artistImages/ and artistImages/ isn't working =( – deepz Sep 08 '11 at 13:13
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/3271/discussion-between-deepz-and-daverandom) – deepz Sep 08 '11 at 13:13
0

You need to do a couple of things:

1- Make sure you test $tablename[ArtistImage] against a whitelist of tablenames before you inject it into your query.
If you don't you are still open to SQL-injection, because escaping only works for values, not for table or column names (or other SQL syntax) that you dynamically inject into your SQL-statements.

$tbl_name = ......
$allowed_tables = array('table1', 'table2');
if (in_array($tbl_name, $allowed_tables)) {
    $query = "......
} else { echo "tablename not allowed"; }

2 - Add a space between the tablename and VALUES

$insertQuery= "INSERT INTO `$tbl_name` VALUES('".$image['name']."')"; 

See: How to prevent SQL injection with dynamic tablenames?

A much simpler answer is to never let the user specify where a file should be saved, or how it is named (on the filesystem).
Follow @Marc B's advice and only store the desciption in the database and use the PK (id) as the filename.

$description = mysql_real_escape_string($_POST['description']);
$query = "INSERT INTO images (description) VALUES ('$description')"
$result = mysql_query($query);
$id = mysql_insert_id; //get the id you just inserted.
$filename = "../fixed_path/".$id.".jpg";
if (!move_uploaded_file($image['tmp_name'], $filename)) 
{ 
   echo "this should never happen" 
}
Community
  • 1
  • 1
Johan
  • 74,508
  • 24
  • 191
  • 319
  • thanks for the advice :) I'll do that. But, my images won't upload in the folder. – deepz Sep 07 '11 at 21:00
  • This is completely unrelated to the question he's asking, and there is no indication that `$tbl_name` is coming from some external source, so there is absolutely no reason to run it through a white-list. – user229044 Sep 07 '11 at 21:03
  • @meager, I have lots of other questions/answers where I err on the side of caution, make sure to downvote those too. – Johan Sep 07 '11 at 21:05
  • @Johan Maybe you should post relevant answers instead. Less work for me. Downvotes aren't some hostile thing, they're a part of the site. Don't get all offended just because your answer was downvoted for completely legitimate reasons, that's the entire point of downvotes. – user229044 Sep 07 '11 at 21:07
  • @Johan Your code doesn't even make sense. `(in_array($tbl_name(ArtistImage), $allowed_tables)` is an obvious syntax error. – user229044 Sep 07 '11 at 21:08
  • 1
    @deepz, don't worry about it, I don't mind downvotes, as long as they are not drive-by shootings. meager has a point, I just don't agree with the point that every answer should address the exact question asked. – Johan Sep 07 '11 at 21:09
  • @meager it's not a problem, I have a problem with erring on the side of danger, instead of erring on the side of caution. The syntax error is my haste and copy pasting of the OP's code.Fixed now. – Johan Sep 07 '11 at 21:11
  • @Johan I didn't know how to prevent websites from sql injections. Now that you mentioned it, I really appreciate the idea which you have provided =) – deepz Sep 07 '11 at 21:16
  • @deepz, I've updated the answer, does this work for you? – Johan Sep 07 '11 at 21:35
  • $filename = "../fixed_path/".$id.".jpg"; is not working. Everytime it says my path is not available, although I have a folder named artistImage. I also did .artistImage/ and artistImage/ but still it's not working. – deepz Sep 08 '11 at 13:12
  • @deepz, use an absolute path instead. – Johan Sep 08 '11 at 13:25
  • @Johan. First of all, thanks for supporting me. Second, I did that, it still doesn't work! – deepz Sep 08 '11 at 13:33
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/3272/discussion-between-deepz-and-johan) – deepz Sep 08 '11 at 13:33