Jump to content

Extra secure "readfile" image?


ChenXiu

Recommended Posts

Circumstance:
"label.php" is actually PHP "readfile" page that fetches images from a private root directory.
"customer.html" is the public page where visitors view their images like this:
Dear Customer, Here Is Your Image: <img src="label.php?image=id_number_1001.png">

Question:
Is it okay to use a hidden $_SESSION["filename"] and change what I have now:
Dear Customer, Here Is Your Image: <img src="label.php?image=id_number_1001.png">
To this:
Dear Customer, Here Is Your Image: <img src="label.php">

This works by having the actual image name stored in a hidden session variable, using the following lines of code on my readfile page "label.php" like this:
$imgName = $_SESSION[ "filename" ] . ".png";
$imgPath = "../root_directory/" . $imgName;

Since I do not want customers to be allowed to ever see the image again after logging out, is it okay to rely on a hidden session variable for the filename as I described above?

(Potential hackers will be less tempted to "try different image names and numbers" like "id1.png, id2.png, id3.png" because they will have no idea if the image will be a gif, jpeg, or png, nor have any idea of a numbering sequence.)

Thank you!!

 

Link to comment
Share on other sites

Sessions are always hidden (from the user's perspective) so I'm not sure what you are asking. Also, the time a session exists is limited unless you specifically change it. It seems to me the most secure way to handle this is to store the viewed image names in your user database with each user name. The check to see if the user has already viewed it. You just have to be careful about how you handle interrupted image uploads.

Link to comment
Share on other sites

The problem with sessions is that things get screwy if people try to do two different things at once. Say, in multiple tabs or windows.

So don't use the session for this. Do what GW said: create a unique token for the image, store in the database, then use that token with label.php.

Link to comment
Share on other sites

36 minutes ago, gw1500se said:

so I'm not sure what you are asking

Sorry, I was just asking if by using sessions and avoiding all file names completely, it seemed to be even more secure. A potential hacker "viewing html source" might see <img src="id123.png"> and then be tempted to try "id124.png" "id125.png" "id126.png" but buy using sessions (which are 100% hidden), the hacker would only see <img src="mylabel"> in the html code.

20 minutes ago, requinix said:

The problem with sessions is things get screwy...

I always thought that in the back of my mind. It actually hurts to see someone say that out loud.
Now I'm worried.
That begs the question "when" and "how much" should one use sessions?
I would assume the following factors as to "when" and "how much" someone uses sessions would be:
1. when the 'convenience value' outweighs the stability of the code
2. how badly will the code and flow be ruined if sessions go wrong
3. how important the session variables are (e.g. just to save a user's color preference red vs green)
4. you need an extra layer of security (e.g. if "order number 12345" is hard coded, making sure $_SESSION["orderid"] == '12345' matches the hard code")
5. when money is involved: if for whatever reason $_SESSION doesn't match the hard code, I would rather have the visitor leave rather than continue with a transaction where something went screwy somewhere.

Edited by ChenXiu
Link to comment
Share on other sites

6 hours ago, ChenXiu said:

That begs the question "when" and "how much" should one use sessions?

Consider what a session is. You give the user a cookie with a unique value, then every time you receive that unique value, you pull up a block of data you stored previously. Different unique values give you different blocks.
A cookie identifies a single device, for the most part. That single device then typically identifies a single user, but there are occasional exceptions to this - such as the famous "uncheck on a shared computer" checkbox.

As long as you want to store data in that block according to the device or the user then you're probably okay because that session is tied to that device and that user. (There are other kinds of Bad Things you can do with sessions, obviously, but they're another conversation.)
If you want to store data in that block according to the webpage they were just on, well that's a problem because the session is not per page. How long has the data been in there? What has the user done in the time after visiting the first page?
Storing data per day of the week would also be a problem. What if you access that data on a different day?

Link to comment
Share on other sites

44 minutes ago, requinix said:

then you're probably okay

So circling back to my original question....

a while back it was suggested that when the visitor is finished posting and reposting data to a product page, the final page should be a "get request" (for various reasons including disallowing the back button and inadvertantly changing the final 'shopping cart').

To get from a post/repost page to a "header(location)" get request, the only way to carry over data is via sessions.
(The only alternative is to have the final "header(location)" page be an ugly url and end in an order number "...example.com/order-complete?ordernumber=123456778" rather than a tidy url like "...example.com/complete.php")

So I put the customer's order number into a Session Value.

Then, on the final page, I do a mySQL query, select data from my table where orderid = $_SESSION["order_number"].

My problem has been generating the stupid image from my readfile page...

I've already got the customer's order number in $_SESSION["order_number"]. I don't need to add yet another id autoincrement column to my mysql table because the table already has the 100% unique order number for the customer, where I can get all the relevant data to display the final "thank you your order is complete page."

Currently, I have the image file named after the order number (using <img src=".../readfile_page.php?label=$_SESSION["order_number"] . ".png">)

I'm trying to figure out what's wrong with just <img src=".../readfile_page.php"> because my readfile.php page can easily derive the order number from the session and display the image.

So, TL:DR (haha too late) the "order number" is already unique (I don't need an id auto increment column in addition to all of that), and if sessions $_SESSION is good enough to carry data over from my post page to the GET request redirect, why all of a sudden not good enough to display an image to the customer while they're browser is open?

(I'm not trying to argue -- I'm well aware my PHP knowledge is about 1.5 on a scale of 1 to 100 -- I'm just trying to find out if I missed the boat somewhere, even though I've implemented almost everything suggested here to me).

Link to comment
Share on other sites

45 minutes ago, ChenXiu said:

(The only alternative is to have the final "header(location)" page be an ugly url and end in an order number "...example.com/order-complete?ordernumber=123456778" rather than a tidy url like "...example.com/complete.php")

There's nothing wrong with using query parameters.  Trying to avoid them for the sake of having a "pretty" URL is silly.  If you really want pretty URLs, use mod_rewrite to get something like example.com/order/123456/complete or whatever.

47 minutes ago, ChenXiu said:

I'm trying to figure out what's wrong with just <img src=".../readfile_page.php"> because my readfile.php page can easily derive the order number from the session and display the image.

In your case, there may be nothing wrong with it.  A user isn't likely (or maybe even able to) process two different orders at the same time in different tabs.  That multi-tab action is where using the session to pass data around can become a problem.

As an example of what not to do, I work on a system for a school where staff search for students and then "open" their student record.  Opening the record stores the student's ID in the session and takes them to a page showing various details and links to reports.   With modern tabbed browsing it's easy to open different students in different tabs messes up the state of previous tabs.  For example, opening student B in a new tab, the going back to the previous tab where you had student A opening and clicking the link to view their class schedule would end up showing student B's schedule rather than student A's schedule as expected.

So when determining when you can use the session to pass data, you need to consider that kind of multi-tab interaction and whether it might cause problems. My general rules for storing data in sessions is the data must be either:

  • Be related to the entire session, regardless of how many tabs/windows a user has open.  Things like the active user, shopping cart details, site preferences, etc.
  • Be short-lived temporary data that's used then removed in the next request.  For example, I have flash messages on the site so after saving a DB record I add a "Record saved successfully" message to the session and redirect back to the list.  The list page displays that message then removes it from the session.

From the sounds of it, your situation doesn't really meet either of those parameters, so I wouldn't use the session.  I'd stick the order number in the URL as a parameter and pass it along in the image URL as well for the readfile script.  Eliminates and potential session issues and makes the code more standalone/reusable (ie, you could maybe reuse the page in a "Past orders" view).

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.