Safest method to integrate web version of Email - php

I am having a couple of mails in which I need to implement web versions. But I don't want to pass sensitive information like UUID or userID. I have a "View in browser" link and when user clicks on it, it should take the user to the website page, which will take input from GET and display specific content for each of the user. How this can be implemented ?
I am already using UUID here and passing it through the URL, which will turn fetch the user from DB and display the contents. It is a fool proof method ?
I am doing this in PHP

If it's super-sensitive information, put it behind your sites login mechanism.
If it's just something random people should not stumble upon by accident, just generate a random unique ID (like you do) which you associate with the e-mail and display the user data. Again, this should probably not give any third-party a possibility to change or impersonate the user, just read the e-mail of one e-mail.

Related

Linking two user accounts together

I am building a method for users of my website to link their accounts together, so that resources can be shared between them. My process so far is:
1) User enters email addresses of users he wants to link with.
2) If matches are found, these users receive an email.
3) Email contains a confirmation link. If the recipient clicks this, the connection between the two accounts will be formed.
I'm wondering how secure I need to be with this final step. My confirmation link is in the format: domain.com/link-confirm.php?fromid=xxx&toid=yyy
In theory, it would be possible for anyone to spoof this link, if they knew the user id of their target, thus setting up a connection without permission.
I tried hashing both user ids, then scanning through the user database for matches, but the password_verify function takes so long to run that the page times out (and that's with only 1000 users).
What I would like to know is:
Does my plan above make sense?
Is there a neater way of doing it?
Am I right to be concerned about the spoofing (connecting the accounts does not in itself share any data between users, it merely makes it possible for either user to initiate)?
Thanks
You can just encrypt both id values and after obtaining it from get - decrypt them, hashes don't need to be used here. That way it will take thousands of years for somebody to brute force spoof them.
What you could do is generate some unique data per account linking request and require that unique data to be sent with the linking acceptance request.
So for example user A requests to link with user B, you store the request with some unique data like a random hash and a timestamp, and then when user B clicks "accept" in his email, he is sent to a page on your server. The link in the email contained the unique data that is submitted to the page. You check if the unique data is indeed the data that was generated when user A submitted the request, and, if so, boom, users linked.

Embedded iframe - Verify source/origin of GET request

I'm seeking to utilize an iframe to embed some html in customers websites that will list some information from my database using a simple GET request like so:
// customer would copy/paste this code onto their site
// value of key would be unique key for that customer
<iframe src='http://mydomain.php/api?key=1234j1lj1hj124kh' ></iframe>
Now I want to be able to verify that the request is coming from customer that owns the key, and not just anybody who copy/pasted that code onto their page.
I've done some research and found that $_SERVER['HTTP_REFERRER'] can give me this information, but with mostly mixed reviews saying it isn't always reliable (and most of the questions I came across were a couple years old).
QUESTIONS
1.) Is this method of using an iframe/GET request the standard way of achieving this functionality?
2.) Is there a standard, SECURE and RELIABLE way to verify the origin of the GET request?
Unfortunately this is not possible in a secure way.
To answer your questions: In fact this is not a standard functionality itself. I mean, there is no standard secure way of allowing content to be loaded only through iframes from allowed websites.
There are three parties in this communication:
1) Your website
2) Customer website that loads your website's data in an iframe
3) End user visiting customer website
When an end user visits customer web site, he will perform a GET request to your website through the iframe. At this connection, 2nd party above (customer website) is not involved. In this case, there is no reliable way for your website to know whether this request is coming through the iframe or not. Only favor that party 2 does here is adding HTTP_REFERER header to end-user's request. But this header cannot be trusted.
For example, if I want to abuse this and show that content on my website, I can create a proxy page on my application, where I perform a back-end call to your app (adding a valid HTTP_REFERER header) and display results back.
Personally I would never use iFrames for this functionality. I am assuming that this has to be reasonably secure, which is why only your specified customer can view it? If for whatever reason you can't use PHP to embed the content you need to display (through the use of an "included" file for example), I would instead use AJAX which would still use any PHP user verification you have in place to dynamically load content into a secure webpage.
This is because your PHP user verification will (should!) use cookie/session information to determine which customer is viewing the page and therefore decide whether the content should be delivered, since Session variables are determined by a single unique code stored client-side, which match up to as much information as you want to collect about a user server-side (Which could include the last page they visited, which is what the "HTTP_REFERRER" variable would give you, if they came from another page on your website).
'$_SERVER' variables aren't reliable because they rely on the information given to them by the web browser when the request is made, and such information can easily be forged, by most people who have a basic understanding about how headers are sent.
In summary, use a NONCE (cookied), validate IP and user agent.
Steps:
When you deliver the outer frame, generate a unique identifier
(totally random, long string) and return that in a cookie with the
HTML content.
At the same time, note the IP and the user agent string you have
sent that unique identifier to, and store in a DB with the time.
When requesting the inner frame, assuming the same domain, the
cookie will come too. (If a different domain, you'll need to attach
the unique identifier as a visible string, but that's not really of
concern, just uglier)
If the user agent or IP do not match those you stored against the
unique string, or the request is too long (i.e. after an hour, or
whatever is reasonable for your application) or the unique string is used more than once
(or whatever other restrictions you place on it) then reject the
request and invalidate (delete) the unique identifier.
Not 100% foolproof, but just combine more options to make it less and less likely to be abused.

Making of Referral System

I'm currently working on my Referral System, but I have a problem with protecting it of frauds.
Okay, here's how it works for now:
user registers and activate it's account
user now have access to the control panel and there is it's uniqe link in following format: domain.tld/ref/12345
when someone other click to user's link, he or she must to click a specific button to confirm that is not some kind of fraud (like "click here, you'll get $100" or something)
system writes visitor's IP in a database and some data to cookies to prevent re-pressing the button. User now have +1 point.
But, the problem is that visitor can change it's IP, clear cookies and hit button again. It takes a few seconds, and that's not OK, that's cheating.
How to prevent it? Is there some trick to get some unique computer ID or something can't be changed that easy?
Really the only options are to tie the process to something which is not so easily manipulated by the user - super cookies, browser fingerprints, OpenID, Email addresses and telephome numbers (the latter 2 using some sort of validaton step before a vote is counted)
The only way you can be certain a referred party does not reuse a referral code is for the original user to send different one-time-use-only referral URLs to each person. Once the code has been used, it is flagged as such in (or removed entirely from) your database so that it can not be used again.
How you prevent the original user from sending multiple links out to the same person is another matter - and not an easy one to resolve.
Who do you perceive to be the threat?
Although it's certainly not 100% accurate, you can still fingerprint visitors using for example a combination of their ip, browser user agent, and with some javascript you can even go for screen size or installed fonts. Using these pieces of information you can set up a system where you save the fingerprints in datatable and in the same record you store the session id (from the cookie). Now when a new visitor arrives you can test their fingerprint against the db of recent fingerprints with different visitor ids. If you find a large number of matching fingerprints (you define the threshold) with different sessions then you can alert for the possibility of fraud.
Cheers
How about storing the link with with the user when they navigate to the link. then in the database you will have the link and if the users has already been to the link then deny them. Seems like it could work then you wouldn't have to worry about the cookies etc...

PHP Guest Access to Website

I have a PHP project is essentially an order processing website for a company. Each user in the company has access to this website and is given certain credentials to the application that control access to pages and functionality throughout.
Now I have a request to allow a guest access to a single page. The complexity of this request is that the guest will be different each time as well as the page will be different. Basically it is a portal to allow customers, who don't have accounts within the system as there is no live ordering on this site, to be able to access and verify the order and shipping information.
My thought to accomplish this is to have a database table setup as a guest relationship table that will be used to store UIDs, MD5 Hash Keys and the destination page that the record is referring to. Also included would be a visit counter and expiration date. When the user receives an email they would have a link provided in the email to somewhere like http://website.com/verify/?HASH-KEY.
When this link is clicked I expect that the verify index.php page takes in the HASH, verifies it in the database and displays the page reference in the database within this location instead of redirecting into the application. This would allow guest access to the single page without the need to expose the structure of the website or a rework of the user authorization already setup.
Am I approaching this solution in the proper manner?
How do I grab the contents of one page and display it in another?
1. Am I approaching this solution in the proper manner?
Yep, more or less.
Some pointers:
Make sure you seed hash generation randomly. For example, DON'T simply MD5 a customer ID or some other small/sequential number, as that would make it easy for a malicious use to hunt down other pages.
Expire the hashed links after a set time out.
2. How do I grab the contents of one page and display it in another?
If you want people to "access and verify the order and shipping information" you should probably create a page specifically for it, instead of trying to pass through normally secure pages to insecure guests. Ie, a 'shipping confirmation page' that populates details according the data keyed by the supplied hash.
I'm trying to a follow this as well as I can.
It seems to be you should use your hash method, and just have a stand alone page that will generate the content you want, totally separate from the rest of the system. Just put enough data in your hash URL to determine what is needed.
Something else to do is use a timestamp in your hash string URL and have that timestamp part of the random bits that you generate your hash on. This will allow you to make a URL essentially "expire" after a certain point.
Example: url.com/in/123456789865/hash-here
You can compare "123456789865" in this example to the current server time and determine if its expired. Of course you need to make "123456789865" part of your hash encryption to still validate
If I understand you correctly (and I think I do), than I think you're approaching this correctly.
To include another page's contents, you usually use include.
include "/path/to/page.php";

MySQL PHP Verify an advert/post via email before displaying on website?

Working on a web based "buying and selling" application with PHP MySQL where users can post adverts for items and services.
Before a new advert is displayed on the system there must be a method of verification to ensure that the user provided email address is correct, and that the advert is legitimate.
I want to send the creator of any new advert an email containing an url which directs to a page whose primary functionality is to receive a posted variable, $advert_id, and to select the advert from the db for updating / editing / deleting.
This variable is embedded in the url with PHP syntax
ie. [http://www.example.com?content=modify_advert&advert_id=2246317].
This part is quite simple to implement, BUT, if a user was to modify this variable called "advert_id=2246317" to any other integer, they can access other posts/adverts in the system.
The system is advert based, and users dont need an account or login to post, so we cannot prompt for a login at the point of verification which would have been convenient.
Any ideas as to how we could protect the adverts/posts in the system from being accessed via the aforementioned url???
Any suggestions?
If visitors will only be viewing that page from the link you send via e-mail, you can include a hash in that address instead of the advert_id — essentially a random, one-time password.
One common and "often good enough" trick for generating such a random password is to take a single, secret, truly random string (I usually use grc.com), concatenate it with the unique advert_id, and hash the whole thing with, say, SHA1(). Like so:
UPDATE advert SET advert_hash = SHA1(CONCAT(advert_id, 'lots-of-randomness-here'))
You could even vary this by adding time(), or (better still) a random number to the end. The outcome is a 40-character string stored in your database that nobody could possibly predict (without knowing the secret data you used to generate it).
For example, I might get this instead of advert_id=1:
f2db832ddfb149522442c156dadab50307f12b62
If I wanted to sneakily edit advert_id=2 (which somebody else created), I'd first have to guess that the hash is this completely different string:
e5c6a3a9473b814b3230ee7923cbe679fcebc922
So, include that in the URL instead of the advert_id (or, if you like, in addition to the advert_id), and suddenly your users are powerless to ruin other people's content.
You could add a salt to the id and then hash it.
sha1($advert_id . $salt);
Send this to the user in the URL instead of the advert_id, and store it in your database, along with the advert_id.
Then when they click the link, you find the matching advert for that hashed value.
Making the salt a secret is how you keep users from 'guessing' a valid URL that will let them modify an ad that they did not post. Perhaps you could use the users email address, the time posted and/or a name or something that the user enters when they make a post.
Generate a GUID as the advert ID so simple ID guessing attacks are unlikely to succeed.

Categories