Qualtrics 3rd Party Add-On Best Practices - php

I am working with Qualtrics, which is just a web-based survey engine. The request is that, once users finish the survey, they will receive a small prize in the form of a gift code. Since I can't host the prize code data on the Qualtrics platform, my idea was to store the prize codes on a remote server. When the user finishes the survey they will be directed to my server (https), to a PHP script that will give out the prizes. On the surface this is possible, because as one piece of customization they allow to re-direct to a URL upon completion of the survey.
The problems that I am faced with, regarding my PHP script that gives out the prizes are as follows:
1) Make sure visitors have COME FROM the survey and have actually
finished the survey.
2) Only give out 1 prize per participant per survey.
It is difficult to address #1 because it seems like after the survey is complete, you just get a basic re-direct to my site. It would be possible to add GET data to the URL, its very easily readable and doesn't offer security. Even encrypting the GET data doesn't seem feasible because a hacker could just copy the data string once they see it.
The idea I had to address #2 was to check the user's IP address using PHP, and store the address in my DB after a 1-way encryption. This way the IP would be unknown, but I could check for duplicates, only allowing 1 prize per IP.
So the question is, is it even possible to do what I am trying to do with just a simple URL re-direct? Is my idea for addressing #2 acceptable?
Thanks.

There are probably many ways this could be handled. Two that come to mind:
1) At the end of survey, Qualtrics creates an embedded data field called ResponseID which is in the Qualtrics data. You can include the ResponseID in the redirect then have your php script call the Qualtrics REST API, and try to retrieve the response with that ResponseID to make sure it exists.
2) Just before the end of survey, you could do a web service call to a script that creates a unique id, store the id on the server side, and return it to the survey as an embedded data field. Then pass the unique id in your redirect and make sure it matches a unique id you stored.
EDIT based on comment below:
You can add custom parameters to your redirect by piping in parameter values like this:
http://mywebsite.com/myscript.php?rid=${e://Field/ResponseID}

If you are able generate special request parameter for redirect url and make it for every user unique, then you could invent some algorithm, and encrypt user ID with it and pass this ID as parameter in redirect url.

Related

Secure a PHP GET Parameter coming from salesforce in a email link to the public?

I am sending a GET Parameter which is an ID, of course this ID is needed to pull fields from salesforce using the soapclient API.
My issue is because this parameter can easily be changed by a user to a different ID, on load of my page it will pull up other fields based on that other ID the user had altered.
How can I secure this in some form? whether it is from the salesforce end or the php side, My Solutions I came up with are the following but I found tedious.
Have a field in salesforce that is ticked if user has submitted the data before so old data can not be viewed again when it does a check to see if it was submitted.
Create a session, grab the get parameter, then redirect to the same page. but that is a bit tedious.
What is the best solution for handling a GET Parameter from a salesforce link that will arrive in a email to the user?
I'm not sure how you generate these ID's or where you use them. But if you store them somewhere and then retrieve them at a later time you could try and hash them. When the ID gets generated either hash it right away and use this hash as the identifier or, if you only get the ID at a later point (on insertion for example), you could create a hash out of the generated ID and store it in a different field of the same record. Later when you are retrieving or showing records to the user you can hash the ID again and make only requests using the hash. This would be a pretty difficult way for the user to get any other records since they would have to know the hash that was generated for the ID.
Of course it all depends a bit on your implementation. I don't have any personal experience with salesforce, so I don't know what might or might not be preventing you from implementing such an idea.

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.

How does facebook server validation work?

Considering a simple example:
Login to your fb account
Post a status
Click on the status dropdrown(top-right corner)
Open developer tools in your browser and find the html for the "delete" option
edit a parameter which looks like story_fbid=10202782137141336
Since the wall consists of several statuses and posts each with a different value for story_fbid, facebook should be using these values to update/delete respective posts.However, changing even a single digit of this value(story_fbid) to lets say story_fbid=10202782137141337 throws up a error as shown in the snapshot below.
I am a beginner in php programming and was curious to know how the server side validation of data is done in php...
So, I was looking for a basic explanation of how this client side changed html is detected at the server end.
I came across a similar question here. According to one of the answers, one possible methods would be the server uses UUID associated with an ID of a particular post. If this UUID is manipulated at the client side, the server detects this and does not perform the requested operation(like DB record update/deletion) on that ID.But since a page can contain multiple such posts with different IDs, it could not be possible to have a UUID associated with each one of them.
So. what method does facebook use to detect such changes?
Disclaimer - I have absolutely no idea exactly what validations are made on Facebook's side - this is post consists solely of educated guesses and general web security concepts.
Any data submitted by a user should be treated as if it has been tampered.
I think this is a great motto to go by. The data you send to Facebook when liking/commenting/deleting a post is composed solely of data that was generated by the user submitting the request. Whether that data was generated by the JavaScript that is already on the Facebook page or by a cURL command or even manually compiled by a user makes no difference to the Facebook server responding to that request.
Since there is no way to validate the data before it arrives at a Facebook server, all data should be considered as "possibly manipulated/harmful". For this reason, it's safe to assume that every single request made to a Facebook server passes though multiple levels of validation:
Is this request valid? Does the request pertain to the expected format? Valid endpoint? valid parameters? Valid arguments?
Is there a valid user on the other end of the request? Are they using a valid access_token or similar parameter?
Is that user allowed to make this request? Is the object owned by the user? Does the user have the required permissions to make this request?
etc...
etc...
etc...
Many more etc's...
Probably even more validations...
If anyone of these (assumed) validations fails, an error message is returned to the user. In order to keep the exact validations secret Facebook probably elected to return generic errors to the users as to not let them know exactly which validations are performed.
If a user was to know exactly what validations were performed it might not be too hard to bypass them - hence, as you can see, the error you get mentions an array of possible problems:
"can not be displayed right now" - most generic explanation.
"temporarily unavailable" - huh? like a hard drive failed? power outage? Data center's internet is down?
"link... has expired" - possible manipulation of an access token?
"don't have permissions"
It would be impossible to know exactly what is happening on Facebook's side - and this is their intention.
In a similar manner, sites that give a login error similar to "user name or password invalid" don't give the user any indication as to which parameter is invalid. It could be the username or it could be the password. Saying that only the password is invalid hints to the fact that the supplied username actually is valid and that may be information that the site doesn't want to share.

How to secure JSON call without using a captcha

So we are building a website and created our basic information to send logins to our database. We have trouble trying to disallow requests that just plug their own data in.
E.g.
http://testing.site.com/php/interfaces/User.php?Action=1&Email=test#gmail.com&FirstName=herp%20derp
By replacing email and firstname, they are able to add multiple users to the database and potentially with a script thousands. Is there any way to prevent this without using a captcha? We are trying to be very minimal and open with the site's design so would love some input if this is possible.
One option we have considered is moving our PHP offline and only allowing our API to access it- however it still presents the problem of users adding in authorised data (and overloading our database with thousands of multiple requests)
Here is a sample option, create a table with 2 fields, one is an Auto Increment id and one is a random code, lets name them ID and CODE
When sending that request, create 1 record in that table and pass the ID and CODE along with request, when receiving the request, check if there is a record in database with that ID and CODE process the request and delete that record from database too and if there isn't that record, just ignore request ...

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";

Categories