I know it's possible to plant a cookie on a user's machine when he is loading an image from my server, by altering the apache settings.
However, I want to know if it's possible to include an image in HTML code that will have parameters in it and I can activate some script to log these parameters, for example:
<img src="http://www.mysite.com/myimage.jpg?somcode=123&customer=abcd" />
In return to loading the picture, I would like to save a cookie on the user's machine with somecode=123 and customer=abcd and also to save this info in my db.
Is this possible?
Thanks,
Instead of using .jpg for the filename, just use .php. Then you don't have to mess around with server configurations and normal image files still get served correctly:
<img src="http://www.mysite.com/myimage.php?somcode=123&customer=abcd" />
Then your myimage.php file:
<?php
// Your tracking and processing code here
$customer = $_GET['customer'];
// Then, either:
header("Location: /urlpath/to/the/actual/image.jpg"); /* Option 1 */
// OR:
header("Content-Type: image/jpeg");
readfile("/filepath/to/the/actual/image.jpg"); /* Option 2 */
I prefer Option 1 because it allows your web server to very efficiently serve the actual image instead of PHP (Option 2).
I'm pretty sure you could do that, Just make apache treat the .jpg extension as php files.
You could add the following to your .htaccess file in the specific folder (don't put it in the root or it will treat all JPGs this way);
AddType application/x-httpd-php .php .jpg
Related
I'm trying to build a simple image uploader using PHP. I do know how to code it, however I have a few concerns..
My question I had is the following: Is saving files which users send safe to save as the original file? With this I mean: Will I not get any vulnerabilities when I'm saving a file send by an user?
Let's say my PHP script does this: It retrieves the POST data, which includes a file send by a person on my website. Is it save to just move the file over to a directory, with original name, content, etcetera? Is there any harm in doing this, or should I rename these files to a random string?
If this isn't a safe way to do this, then what is? How would I verify the send content isn't harmful?
There are always vulnerabilities in storing and providing content provided by a client.
This blog post gives a good description of the vulnerabilities you could face, how they're exploited and how to protect against them. I suggest you use this as a reference: http://blog.insicdesigns.com/2009/01/secure-file-upload-in-php-web-applications/
Make sure you only process files with the correct ending. Image files are never executed by a webserver, but .php files are for example. So make sure the users don't upload any file that can be executed.
I'm not aware of file names that are harmful. For the content this is difficult to answer. I remember an attack vector with modified TIFF images on windows and one in libjpeg on *nix Systems. However you probably won't be able to find these things without completely decoding the image.
Here's another approach: use this (https://hacks.mozilla.org/2011/03/the-shortest-image-uploader-ever/) very short Image Uploader, by Paul Rouget, based on Imgur.com's API.
Instead of uploading directly to your database, let imgur do all the security and validation, then if you need to, link to or download the (safe) image via Imgur.
It's free for non-commercial and very cheap for commercial.
Basically, you can use imgur's API to safely upload images from your HTML page, with no server side code at all
Here's a live demo: (http://paulrouget.com/miniuploader/)
I would say 100% user upload file are NOT 100% SAFE
JPEG files can contain arbitrary data in them in addition to the actual image data; it's part of the spec. Thus, merely checking if an image is a valid JPEG does not mean that the file is necessarily completely harmless.
File upload without validation
HTML Form:
<form enctype="multipart/form-data" action="uploader.php" method="POST"> <input type="hidden" name="MAX_FILE_SIZE" value="100000" /> Choose a file to upload: <input name="uploadedfile" type="file" /><br /> <input type="submit" value="Upload File" /> </form>
PHP Code:
<?php
$target_path = "uploads/";
$target_path = $target_path . basename($_FILES['uploadedfile']['name']);
if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file " . basename($_FILES['uploadedfile']['name']) . " has been uploaded";
} else {
echo "There was an error uploading the file, please try again!";
}
?>
Define a .htaccess file that will only allow access to files with
allowed extensions.
Do not place the .htaccess file in the same directory where the
uploaded files will be stored. It should be placed in the parent
directory.
A typical .htaccess which allows only gif, jpg, jpeg and png files
should include the following (adapt it for your own need). This will
also prevent double extension attacks.
deny from all
<Files ~ “^w+.(gif|jpe?g|png)$”>
order deny,allow
allow from all
</Files>
If possible, upload the files in a directory outside the server root.
Prevent overwriting of existing files (to prevent the .htaccess
overwrite attack).
Create a list of accepted mime-types (map extensions from these mime types).
Generate a random file name and add the previously generated extension.
Don’t rely on client-side validation only, since it is not enough. Ideally one should have both server-side and client-side validation implemented.
php
<a href="<?php echo $path_data['wall_path'];?>">
<?php echo $dimensions_data['width'] . "x" . $dimensions_data['height']; ?></a>
which outputs
<li>640x960</li>
<li>640x1136</li>
<li>720x1280</li>
<li>768x1280</li>
<li>1080x1920</li>
Now what I need to do is when the user clicks any one of the sizes, I want to prompt a save file dialog box containing the appropriate size file. I've read Forcing to download a file using PHP and PHP Force File Download, but based on my understanding, these are for single file downloads. Please correct me if not.
Restrictions:
don't want to forward to another page like download.php file when user clicks a link.
Normally a browser would not show a download dialog for an image, it will display the image instead, what is the desired behaviour. You can then click "Save As ..." and save the image.
What the browser does with a files depends on the mime type which the web server sends for that file. For jpg images it would be
image/jpeg
If you really want to trick the browser to show a save dialog you need to send a different mime type for that files, like:
application/octet-stream
This can be done using a download.php file (or whatever) which modifies the header and outputs the file. The existence of such a download.php can be hided from the user using rewritten urls.
If you don't want that, you need to tell the web server that it should send a different mime type for that files. If you run apache for example, you can add the following line to your .htaccess file:
AddType application/octet-stream .jpg
I am using codeingiter and had a image directory in it. Due to space issue I have shifted the entire directory to new location on same server.
Earlier path was /var/www/html/site_folder/assets/images
New Location is /home/new_site/images
Now when I want to display images on web site its not getting load.
I have tried using the below code
$file = '/home/new_site/images/3.jpg';
header('Content-Type: image/jpeg');
echo "<img src='".readfile($file)."' &glt;";
I have approximately 50 images and I want to load them on my site.
This works on local but not on server. I am using Linux on local and Centos on server.
You are mixing things up. What you want to do is to return the content of the image file, but you return an HTML fragment.
There are multiple solutions you could try:
Create a symbolic link to the new image directory, most things could stay as they are. This migth or might not work depending on your web server configuration.
Change all the references to images from
src="image5.jpg"
to something
src="image.php?name=image5.jpg"
Then you need the script "image.php" which takes the name of the image as a query parameter and then returns the content:
<?php
// take care to make some clever checks here
// otherwise you introduce a security nightmare
$file = '/home/new_site/images/' . htmlspecialchars($_GET["name"]);
header('Content-Type: image/jpeg');
readfile($file);
?>
I want to have a PNG picture, but when accessing it, it runs a PHP script, the PHP script should decide what picture to send (using some if statements and whatever). Then the PHP script should read the image file from somewhere on my web server and output it.
Here is the issue, if I get a .png file, and put PHP code in it, it won't work, however, if I use the .php extension, it works, and I can even embed the image into other websites, and the PHP can decide what image to send, but if I want to view that image directly (copy it's URL into my address bar) it doesn't work, it gives me the images plain contents (random jibberish).
Anyone know what to do?
Also This is my first question on Stack Overflow - please tell me if I am doing something wrong.
You need to send Content-Type headers.
For png:
header('Content-Type: image/png');
For others change png to jpg or gif or bmp or whatever.
Please note that header() function must be used before anything is written to output.
First, make sure you have your image image.png somewhere accessible to php.
Then create a php script image.php:
<?php
header('Content-Type: image/png');
readfile('image.png');
The script now acts like it was a PNG image.
It sounds like you know how to send the image, your issue is that you want the URL to look like it's a PNG image.
There are a couple of things you can do. First, if your web server supports URL rewriting (like Apache's mod_rewrite module), you can use a rewrite rule so that the user access the script as something like http://example.com/generated_image.png but your server will translate/rewrite this URL to point directly to your PHP script, so something like /var/www/image_generator.php.
Another option would be to actually name your script "generated_image.png" but force your webserver to treat it like a PHP script. For instance, in Apache you could try something like:
<Location /generated_image.png>
ForceType application/x-httpd-php
</Location>
As a final note, if you're not actually worried about the URL, but worried about the file name that is used if the user decides to save it to disk, you can simply use the Content-Disposition HTTP header in your response. In PHP it would look something like this:
<?php
header("Content-Disposition: inline; filename="generated_image.png");
?>
With that, it doesn't matter what the URL is, if the user saves the image through their web browser, the web browser should offer "generated_image.png" as the default filename.
Simplest version I know...
<?php
header('Content-Type: image/png');
if(whatever)
{
$image=your_image_select_function();
}
// as suggested by sh1ftst0rm with correction of unmatched quotes.
header('Content-Disposition: inline; filename="'.$your_name_variable.'"');
readfile($image);
?>
Then, you treat it like an image file. That is, if this is "pngmaker.php" then, in your HTML document, you do
<img src="pngmaker.php">
You can even do
<img src="pngmaker.php/?id=123&user=me">
I want code that loads an image to a PHP server and then send it to browser.
For example I want sample.php to send an image to browser once it is requested.
in other words, I want to create a PHP file that acts like a proxy for an image.
why are you doing this?
why don't deliver the image directly?
if you are trying to display a random image you may as well just redirect to the image using
header("Location: address-of-image");
for delivering the file to your clients from your server and not from its original location you can just do. however your php.ini settings need to allow external file opens
readfile("http://www.example.com/image.jpg")
correct headers are not required if you are going to display the image in an img tag,
altough i would recommend it. you should check the filetype of the image or in most cases just set an octet-stream header so the browser doesnt assume an incorrect type like text or something and tries to display binary data.
to do so just do
header("Content-type: application/octet-stream")
one more thing to consider may be setting correct headers for caching...
You need to use
$image = fopen("image.png");
Modify the headers(not sure exacly if it's correct)
headers("Content-type: image/png");
And then send the image
echo fread($image, file_size("image.png"));