Solved

PHP Solution to IE Image Problem

Posted on 2013-12-18
29
303 Views
Last Modified: 2013-12-20
Hello Experts!

I have a quick question for you PHP geniuses out there.  It is well documented that IE does not support usernames and passwords in url's (see http://support.microsoft.com/kb/834489), so my question is this:

I have images stored on a website that is protected by username and password authentication that I would like to use on a remote website.

Now, to display the image on my remote website would be simple using the HTML img tag:
<img src="http://username:password@example.com/someimage.jpg" alt="Sample Image" />

Open in new window


This will not work in IE, however.  What can be done in PHP to first authenticate the request and then retrieve the file contents of the image and display it on the remote site?  I know there has to be several possibilities.  All I need is one working one.
0
Comment
Question by:OmniUnlimited
  • 11
  • 9
  • 7
  • +1
29 Comments
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 39728533
If you want to put name and password into the URL then the question that begs asking is why would you have a name and password to the site in the first place - given that both name and password would now be out in the open?

The second question is if the images are protected - why do you want to access them from a remote site - would you not be in violation of the usage policy of the site that hosted the images?

Before answering this post the above need to be given some consideration.
0
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 39728661
Julian has a point.  I would never do that in any browser.
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39728828
Gentlemen,

It seems there must be some misunderstanding.  While I could understand julianH's question should I be using the img tag I used in my example, this would not be the case in PHP.  Obviously, any authentication that is done would be done via PHP code and would not be visible upon inspection of the source of the HTML page.

To answer question two, the answer is no.  Both sites are maintained by me, and I determine the usage policies.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 39728940
this would not be the case in PHP.  Obviously, any authentication that is done would be done via PHP code and would not be visible upon inspection of the source of the HTML page.
Then I don't think you understand the relationship between php and and html.

The browser fetches the requested page which is either rendered out by a php script or some other script or is just a plain html file. The browser then parses this file and fetches all the objects referenced in the html. So unless your img tag contains a url that points back to a PHP script - then PHP does not play any role in the fetching of images.

If you wanted to use a script (not sure I would ever want to do this) you would need to call a script for the current site - the php script could then CURL the image from the remote site and send the results back to the browser.

However - the php script would then be available to anyone out there who wanted access to the images and they would be able to get them in the same way i.e. if you made your links

<img src="somescript.php?img=name.jpg" />

Then I could host that image on my site just by pointing to that script - sort of makes the "hidding" of the images behind the name / password a bit redundant.

You could make it that the referencing site requires a login before it has access to the script - but in that case you might as well make it that the login gives direct access to the actual images.

No matter which way you cut it I cannot see the sense in trying to do it the way you suggest.
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39728968
However - the php script would then be available to anyone out there who wanted access to the images and they would be able to get them in the same way

Perhaps your concern is based on the idea that I am trying to protect the images in some way because they are hosted on a site that is password protected.  I am not.  I really don't care who has access to the images.  The images are under password protection simply because I want the site in general to be password protected, i.e. not available for public viewing.

I like the idea of using curl to retrieve the file contents.  Can you give me an example of the coding you would use for the img src php file?
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39729151
There are so many moving parts here, it's hard to figure out how to answer the question.

Here is how PHP client authentication works:
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_2391-PHP-login-logout-and-easy-access-control.html

You might consider using OAuth to protect the images.  You might use some kind of "secret handshake" in the cross-site request, perhaps sending a token that the image host would use.  Or if this is really true (" I really don't care who has access to the images.") why not just copy the image directory to the public site and host the images there?
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 39729152
 I am not.  I really don't care who has access to the images

Open in new window

Then why not make the images available at a location outside of the protected code and just access them directly?

Regarding the CURL solution - that would only work if the access control is file system based - as opposed to a managed session where you provide your own login.

Another option - to make the curl easier - is to have a magic number that when present in the URL would bypass the login requirement (for instances where you are managing your own login). You CURL the img url with a magic number on the end which tells the other system to give you what you ask for without having to logon.

So what you could do is put a php script outside of the protected area on the server. This takes a file name and a magic number.

You curl to the php script - it fetches the image using local paths and sends it back - avoids having to go through the hassle of a CURL logon - and gets around the problem of session managed login creds.
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39729173
@Ray: I don't see how your writeup has anything to do with what I am trying to accomplish.

@Experts:

With regards to transferring the images to a publicly accessible location, that is simply not a viable alternative at this time.  The transfer of the amount of images we are talking about would be extremely time consuming (not to mention the amount of recoding we would have to do)  The system is set up the way it is set up and that is what we have to work with, and we need a solution that can be implemented quickly and with little effort on our part.

@julianH: so you are saying curl wouldn't work in this case?  Is there any php solution that could work with the .htaccess password protection?
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39729198
Maybe my suggestion for PHP client authentication did not make sense because this design doesn't make sense.  Nobody does what you're talking about -- it's like teaching a fish to ride a bicycle!

cURL can use any kind of authentication.  A cURL session can accept and return cookies, follow redirects, etc., in all the ways that a well-behaved web browser would work.

Let me try to get a grip on the true nature of the question.  You have a site "A" that has your images, and you want to be able to render the images on site "B" but because of the way site "A" has been password protected, you cannot simply use fully-qualified HTML <img> tags to access the contents of site "A."  Does that paraphrase the issue correctly?
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39729205
@Ray: yes
0
 
LVL 51

Assisted Solution

by:Julian Hansen
Julian Hansen earned 100 total points
ID: 39729207
In fact you could just do a file get contents something like this

File 1 - calling the image
<body>
  <img src="t508.php?img=00800_thm.jpg" />
</body>

Open in new window

File 2 - proxy to fetch the image
<?php
$img = $_GET['img'];
$magic_number = 'a16078f5-ba08-1031-89d3-6198d6688668';
header('Content-Type: image/jpeg');
die(file_get_contents("http://www.marcorpsa.com/ee/fetch.php?img=$img&mn=$magic_number"));
?>

Open in new window

File 3 - agent to fetch the requested image and return it to calling script
<?php
$magic_number = 'a16078f5-ba08-1031-89d3-6198d6688668';
$img = $_GET['img'];
$mn = $_GET['mn'];
if ($mn == $magic_number) {
	readfile("images/$img");
}
?>

Open in new window

If you save file 1 and 2 to a server and call the first one - it should demonstrate how it works.
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39729239
@julianH: I am sorry I did not address the issue of adding another file to the site.  Experts, I know it is difficult to understand what is going on here, but I am trying to avoid lengthy explanations if at all possible.  Please note that it is undesirable for a number of reasons to add an additional file to the authenticated site.  I would like to avoid this solution if that is possible.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39729255
... it is undesirable for a number of reasons to add an additional file to the authenticated site.
Why?  That is the only sure way, outside of writing a cURL script, to get the images.
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39729277
@Ray: ok, so both you and Julian are saying that direct curl access to the images is not possible?

What about sending authentication using header() and then accessing the image?  Would that work?
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39729290
I believe that direct cURL access to the images is possible.  You would put the cURL script on Site "B" and use the script in the HTML <img> tag.  The cURL script will present authentication credentials to Site "A" then it will read the image file and replay it along with the appropriate header() on Site "B".  This is like what @julianH was describing here:
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28321949.html#a39729207

But why can't you add any scripts to site "A"?
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39729346
@Ray: can you give me a coding example of how the script on Site "B" would look like, with its ability to read the image file and replay it along with the appropriate header() on Site "B"?

I'm afraid that in order to explain why I can't add a script to site "A" would be to reveal proprietary information that is guarded under a non-disclosure agreement.  As I stated, I am trying to avoid long explanations.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 39729356
The question is not whether it is possible - but what is the most practical.

If you are managing security on Site A through sessions - where you display your own dialog box and then manage the security that way - then cURL is going to be a problem unless there is something on SiteA that allows you to login through some other means than interacting with the dialog.

If your security is file system based then you can cUrl the credentials through.

I would be interested to know why you can't put a script on Site A - otherwise it sounds like an attempt to hijack another site's protected content.
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39729376
If you are managing security on Site A through sessions

Site security is a simple .htaccess authentication requiring a username and password.

otherwise it sounds like an attempt to hijack another site's protected content.

Can you explain to me how you can hijack protected content without knowing the username and password?  And if you know the username and password, why go through all this trouble?  Why not just log into the website and take everything from there?
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39729424
I have to go out of town for a while, so I can't give you an example immediately, but I can probably give you an example later today.  To facilitate the process, please set up a test directory that is protected by .htaccess, just like the existing site is protected.  Inside that directory, put an "images" directory and put a test image in it named "ray_test,png" Then post the URLs with the username and password here.  I will try to get a script to present the username and password when accessing the site, read the file(s) from the images directory and present an image tag that you can put into HTML.
0
 
LVL 82

Expert Comment

by:Dave Baldwin
ID: 39729783
I'm sorry but these are ridiculous restrictions and methods.  This is a lesson in how Not to design things.  Maybe you're stuck with it but I would just tell them no.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 39729842
Can you explain to me how you can hijack protected content without knowing the username and password?
Easy - you sign up for a site that has protected content.
Then you create your own site where you want to use data from the other site.
Instead of capturing your own you use the images from the original site.

Not saying that is the case here.

As you say if you have the name and password then why are the images behind a login - why not just remove the security.

As DaveBaldwin says - sounds like a lesson in how not to design a website.

If you are dead set on doing it - take Rays advice and give a sample we can play with. Other than that - not much more to add.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39730073
And if you were on the other side of things and wanted to reduce the risk of "borrowed" images, this article shows how to watermark any hotlinked image.
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_10065-Adding-a-Watermark-to-an-Image.html
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39730306
@Ray: Sorry for the delay in getting back to you.  I didn't want to post until I had everything set up, and it took a while for the new subdomain to propagate.

Anyway I set up a new subdomain under .htaccess authentication, just like the site in question, at http://ray.omniunlimited.com/.

The username is ray and the password is ray_test123.

The path to the image is http://ray.omniunlimited.com/images/ray_test.png.

P.S. Thanks for the link to the watermark, but as I mentioned earlier, the images are not of proprietory nature.

@DaveBaldwin: I agree that things are a bit ridiculous, but I'm not the one making the rules.

@julianH:

Easy - you sign up for a site that has protected content.
Then you create your own site where you want to use data from the other site.
Instead of capturing your own you use the images from the original site.


I'm sorry, but this also seems ridiculous to me because under the authentication method I described, once you log in you can right click any image and download it to your desktop.  And if you can do that, what is to keep you from uploading the image to your server and using from your server, thus bypassing the need for all of this?

As you say if you have the name and password then why are the images behind a login - why not just remove the security.

Because there is other content on the site that must be protected because of its proprietory nature.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39730857
Please see http://www.laprbass.com/RAY_temp_omniunlimited.php

The various parts of this script could come from anywhere, including from a URL "GET" parameter that gives the URL of the image file.

<?php // RAY_temp_omniunlimited.php
error_reporting(E_ALL);


// <img src="http://username:password@example.com/someimage.jpg" alt="Sample Image" />
// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28321949.html#a39730306


// AUTHENTICATION CREDENTIALS
$uid = 'ray';
$pwd = 'ray_test123';

// IMAGE NAME
$nom = 'images/ray_test.png';

// THE RESOURCE, INCLUDING AUTHENTICATION AND IMAGE PATH
$url = "http://$uid:$pwd@ray.omniunlimited.com/$nom";

// READ THE FILE AND SEND IT TO THE BROWSER
$img = file_get_contents($url);
header('Content-type: image/png');
echo $img;

Open in new window

HTH. ~Ray
0
 
LVL 17

Author Comment

by:OmniUnlimited
ID: 39730922
Thank you so much Ray.  Well done, I think you are on to something.

The only problem I see with the code is that because of the header('Content-type: image/png'), the img tag is self generating and I have very little control over it (how, for example, do I display this nicely in a web page along with several other images from the same source, and how can I add custom attributes without resorting to javascript?), at least not the control I would have over normal images I set using the img tag.  Is there a way to channel this into the src of an img tag?
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 39731313
I'm sorry, but this also seems ridiculous to me because under the authentication method I described, once you log in you can right click any image and download it to your desktop.  And if you can do that, what is to keep you from uploading the image to your server and using from your server, thus bypassing the need for all of this?
Not that it is relevant to this thread any longer - but if you have a 1000 images on your site it is a bit prohibative to download and upload each one - you would have to do this wiht updates as well. Anyway - I was just saying this is a possibility which is why getting around it is not straight forward.

With respect to the code above -  I thought the whole problem with this approach was that creditials embedded in urls were not universally supported ? Did I miss a step?
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 400 total points
ID: 39731642
This shows the way to use the PHP script as the src= attribute of the <img> tag to dynamically load an image.  You can create any number of image tags in your HTML  document with this script in the src= attribute.  Just put the appropriate image path in the GET request(s).  One image path per <img> tag, just like normal image tags.  See the examples on lines 5 and 20-22.
http://www.laprbass.com/RAY_temp_use_omniunlimited.php
<?php // RAY_temp_use_omniunlimited.php
error_reporting(E_ALL);

// CREATE AN IMAGE PATH/NAME VARIABLE FOR OUR HTML
$imagepath = 'images/ray_test.png';

// CREATE OUR WEB PAGE IN HTML5 FORMAT
$htm = <<<HTML5
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex, nofollow" />

<title>HTML5 Page Showing External Image Link</title>
</head>
<body>
<h3>Here is the dynamically loaded image file</h3>
<h3>SEE: http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28321949.html</h3>
<p><img alt="dynamic" title="Dynamic Image $imagepath" src="RAY_temp_omniunlimited_img.php?q=$imagepath" /></p>
<p><img alt="dynamic" title="Dynamic Image $imagepath Smaller" src="RAY_temp_omniunlimited_img.php?q=$imagepath" style="width:100px;" /></p>
<p><img alt="dynamic" title="Dynamic Image Missing" src="RAY_temp_omniunlimited_img.php?q=gooseball" style="width:100px;" /></p>
</body>
</html>
HTML5;

// RENDER THE WEB PAGE
echo $htm;

Open in new window

Here is the script used by the HTML document.  It finds the name of the image path from the GET request.  You might want to add some sanity checks (maybe check the HTTP_REFERER), and perhaps a "default" image if the requested image is not found - whatever makes sense for your application.
<?php // RAY_temp_omniunlimited_img.php
error_reporting(E_ALL);


// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28321949.html
// THIS SCRIPT IS USED IN THE SRC= ATTRIBUTE OF THE <IMG> TAG


// AUTHENTICATION CREDENTIALS
$uid = 'ray';
$pwd = 'ray_test123';

// IMAGE NAME IS CONTAINED IN THE URL OF THIS SCRIPT
$nom = $_GET['q'];

// THE RESOURCE, INCLUDING AUTHENTICATION AND IMAGE PATH
$url = "http://$uid:$pwd@ray.omniunlimited.com/$nom";

// READ THE FILE AND SEND IT TO THE BROWSER
$img = file_get_contents($url);
header('Content-type: image/png');
echo $img;

Open in new window

This is the technique that is used in the "tracking image" strategy of HTML emails.  You use the name of a script as the URL of an image.  The script renders the image, but also gathers as much information as it can, such as IP address, time of day, original email address, etc.  It can record these data elements in a data base.  This gives the email company some insights into the efficacy of their email programs.

HTH, ~Ray
0
 
LVL 17

Author Closing Comment

by:OmniUnlimited
ID: 39731694
@Ray: BRAVO!!! Ray, you are truly the king of PHP.  What an outstanding (and elegant!) solution.  This is just what I needed.  Thank you very much!!!  I would have given all the points to you, but julianH did come up with a solution as well (howbeit not the one I could use.)

@julianH:

With respect to the code above -  I thought the whole problem with this approach was that creditials embedded in urls were not universally supported ? Did I miss a step?

I think you did.  If you examine the url's on Ray's example img tags, you will see that there is no sign of either a username or a password.  The images that Ray has called up render perfectly in IE.

@all:  Thank you very much to all experts that participated.  You guys truly help make EE what it is today.

Best Regards,

Jason
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39731738
Thanks for the points and thanks for using EE! ~Ray
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

This article will explain how to display the first page of your Microsoft Word documents (e.g. .doc, .docx, etc...) as images in a web page programatically. I have scoured the web on a way to do this unsuccessfully. The goal is to produce something …
I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now