Do PHP sessions get lost when directing to a payment gateway? - php

If i was to store some order details in a session whilst the customer is redirected to a payment gateway, would they be lost by the time the custom returns back from the gateway?
My plan is:
website take order -> store order in session -> website goes to paypal -> payment made -> returns using paypal autoreturn to confirmation page -> on return get session order data and submit to database.

I found the problem.
Paypal redirect back client to yoursite.com without the www.
cookies on http://www.yoursite.com are http://yoursite.com are not considered the same.
To fix that, add .htaccess to your www root;
RewriteEngine on
RewriteCond %{HTTP_HOST} ^yoursite.com$
RewriteRule ^.*$ "http\:\/\/www\.yoursite\.com" [R=301,L]

That depends on how long it takes them to come back to your site. I don't know what the default expire time is for sessions but you can assume it to be anywhere from a few minutes to a few hours.
If you want to assure the user gets to see whatever he needs to, you will need the payment gateway to redirect the user to a URL that you specify. For instance:
/payment.php?status=complete&receipt=875628dwf87sdfsg785623
Where the receipt identifies anything you want it to: the user, the transaction, both?
Most payment gateways support such a feature. If yours does not, contact your payment gateway.
If you want to show them a receipt, do not use sessions or cookies, use the return URL method I describe.

Session may be lost if visitor was in HTTP when leaving and comes back as HTTPS (or vice-versa)

Sessions won't get "lost" as long as your server supports session cookies, but they may expire.

The session is an ID to identify the session and the data belonging to the session. The data is stored on your server as long as you like. The ID is either saved as a cookie or handled as a GET-parameter which should be avoided generally. If you have the ID saved in a cookie then there is no reason why another site should interfere with it.
So I see no reason why your session should be lost.

As long as the customer has cookies enabled in their browser, the session will remain when they return, unless they've closed their browser window first. Sessions IDs are kept in a cookie, which expires when the browser closes.
You could also, if you wanted to, keep the information in a cookie, though this would be less preferable if there was any private information you needed to be kept.
EDIT
also, the answer about creating a session in HTTPS then accessing it again in HTTP is correct.

The session remains active as per your application's session expiry settings.
The new versions of the browsers might be destroying the session because of the new cookie policy.
References
https://developers.google.com/search/blog/2020/01/get-ready-for-new-samesitenone-secure
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
Whenever the cookie is required to be sent to server, the browser sees the SameSite attribute to decide if the cookie to be sent to server or blocked. For user actions, it is sent to the server but for auto-redirects, it doesn't if SameSite is set to 'Strict' or 'Lax' (Lax is going to be the default value now).
Solution:
The cookie attribute SameSite can be set to 'None' along with specifying the 'Secure' attribute to 'true'. Setting 'Secure' attribute to 'true' would require your site to run on https. Sites running with http:// protocol will not be able to set 'Secure' cookie.
Please set the 'HttpOnly' attribute to 'true' for making it accessible for http requests to the server only.
In PHP, it can be achieved as below
session_set_cookie_params(0, '/PATH/; SameSite=None', <COOKIE_DOMAIN>, true, true);

Related

Maintain SameSite "Strict" Session Cookie Policy throughout redirect

Let's say you have a website A, of which you control the login + navigation across protected pages of A via PHP Session cookies. For thus maximum security, these cookies are all secure, httponly, and use samesite equal to Strict, and are limited to the domain of A, hence also "host-only".
If a user who's logged in now confirms a payment while on A, some banks / payment services will automatically redirect that user to execute a subsequent / multi-factor authentication on page B of the concerned service. After the client responded to that additional authentication, no matter if yes or no, the system normally redirects the client back to A.
What I'm wondering now is concerning security. Using the above-mentioned session cookie settings, the redirects to B and back to A would obviously cause that the client would lose the session, and get signed out after being redirected on A.
This can be avoided by setting the SameSite attribute of the session cookie to Lax in the server configs. However, what if I wanted to keep it to Strict?
The solution I came to think of, but no clue on how to implement this in PHP:
The session cookie configs on the server define the Strict value for the sameSite attribute, as I want that to be the case, in general. When the payment is confirmed on A, the function which handles that confirmation on the server-side, so before the redirect to B, changes that samesite value of the session cookie to Lax. Then, on the page which B redirects to, at the very beginning, I reset that value back to Strict.
Is something like this possible in PHP? Or would you rather consider sth like creating an entirely new session cookie having Lax, copy your $_SESSION data into it, and then take up that $_SESSION data back after the redirect, into the cookie you're using for the sessions on A using sameSite="Strict"?
Or any other, better-suited solution?
As far as I know payment providers usually requires some kind of signed transaction token passed in the GET request. Such token is the being sent back in the GET, together with the redirections.
In such case, assign the session data to such transaction token generated in the site A, send the token with the redirection to the the site B and restore the session data, when the token is received with the redirect from site B.
Token must be signed, so site A and B must be sure, that it originates from the site A.
This requires additional controls in place, to prevent session hijack by someone, who is in a possession of such token: some kind of additional session validation must be in place, for example browser fingerprinting.
In such case there's no need to get the same session cookie.

Will a user's PHP session persist if they navigate away from the site and back?

I'm creating a session variable in one PHP page and on that page I am redirecting to an online payment portal.
After payment, the user is redirected to a payment success page on my server. Will the session variable still be valid?
The above answers are true if you are storing sessions using cookies. If cookies are disabled then a PHP_SESSION parameter will be passed in the URL. For the returning user to be able to continue using the session the payment gateway would need to redirect back with the same session hash.
As stated if you are using the default PHP session settings then cookies should be in use and this would not be an issue. What about the users whom may have cookies disabled, your flow will break. Chances are slim and the amount of users effected may be small.

Paypal REST API Return Page

I'm currently using the Paypal REST API to process billing agreements for users with multiple plans.
When a user signs up for a plan, it takes them to PayPal to pay. After they finish that step, PayPal redirects them to a return URL that I have supplied.
The problem is, sometimes the user's session does not persist when they return from PayPal!
I have session_start() as the first line in all of my files, so the sessions are being created. I have verified, before taking the user to PayPal, that the $_SESSION array is being populated - it's just when they are brought back after PayPal.
Is there a better way to persist data like that so I can update a users account on return back from PayPal? Or maybe there is a way to pass the email with the PayPalrequest so that it is returned in the object they send back to my website on return?
If you're properly starting the session via session_start() on both your sign-up page and the page that PayPal redirects back to, your session should be starting properly.
Assuming that you're not inadvertently closing the session, or regenerating the ID, it sounds like there isn't an actual "session management" issue, but perhaps it has to do with the URL that PayPal is redirecting back to.
A common issue with PHP sessions is that, with a default PHP config, they don't carry between subdomains.
For example, if I visit your domain domain at example.com, my session will only be active on example.com. If I then go to www.example.com, I will receive a new session.
You can verify this by going to your site at example.com or www.example.com and checking what domain the PHPSESSID cookie is set for. If it is not .example.com (note the leading .), then this is the issue =]
To help resolve this, you can modify your server's config to set the .example.com as the cookie's domain. Taken from this answer:
session.cookie_domain = ".example.com"
The same answer I gave to a recent question should work here as well:
The solution I used for this same problem was to set
override_merchant_preferences on the billing agreement, with the
return_url containing the user id in the query, like
www.domain.com/api/handler.php?uid=42&action=return.
Though of course you can pass any identifiers you'd like through the $_GET that way.

Are cookies necessary for a login page?

Are cookies necessary to create a login page with php (that keeps you logged in across several pages), or could a session variable do the trick without use of cookies?
Answer simply is yes.
Sessions rely on a session id.
Sessions in php use a cookie to store this id, but you can change it to append the id to each url instead of saving it in cookies.
ini_set('session.use_cookies', false);
in the config variable url_rewriter.tags, you see which URLs automatically get rewritten to append this id:
"a=href,area=href,frame=src,form=,fieldset="
As Pekka mentions, jQuery requests and special JS/Ajax/jQuery calls are not getting rewritten by default and you have to append the id manually like:
<script>
$.get('/yourpage/?PHPSESSID=<?php echo session_id(); ?>');
</script>
the session name can be obtained via session_name();, default is in the config variable: session.name.
Use ini_get(); or phpinfo(); to see your configuration.
Actually if you are using sessions you can use a cookie or a special GET/POST fields to identify yourself towards the server. The server then using the user id, passed either by GET/POST or a cookie - knows which data set is connected to the current user/client at server side. This way using sessions you can store data at server side with only sending a special user id to the client.
This way you can save login data for each user, thus login functionality can be implemented using sessions in PHP.
And yes, you can solve login with no other cookie just the Session user ID, or use the POST/GET session id.
Typically sessions are more reliable when working with keeping a user logged in. Sessions are stored on the server, whereas cookies are stored client sided. So that falls down to: do you want your login dependent on something the client can control and manipulate?
I've had first hand issues with logins being hacked with cookies, so I suggest sessions.
No, you do not need cookies in order to set up a login system, sessions suffice. However, if you seek a "Remember me" option, you need cookies in order to keep the user logged in beyond the point when the user closes the browser or the session expires.
http://www.php.net/manual/en/features.sessions.php
For maintaining a session with server, you need to identify yourself (your page) to server. So that server can keep track of your page's subsequent request and maintain a session.
So, if you only have username and password option on your login page, then cookies may not be required. Refer to the following link:
Passing the Session ID from page to Server
You can have a special URL which will have identifier as part of URL, which will inform server about your subsequent request.
However, please note that using this type of special URL is not always the recommended approach. Because this is insecure than cookie based session. For example, someone may paste their own link on a chat or in an email, and other person will be entered to your site without username/password.
You can do authentication without cookies (or sessions which are a special case of cookies) but it won't be on a page. This method is called HTTP Authentication.

What is cookie with key "ebNewBandWidth"? Where is it set?

Over the past 3 days I've been getting the "Disallowed Key Characters" error from CodeIgniter's Input class. I've found that this is resulting from CI checking for valid global cookie keys in the $_COOKIE array. The particular keys tripping the alert are below (where asianfanfics.com is the site I'm working on):
ebNewBandWidth__www_asianfanfics_com=277%3A1357053922099;expires=Wed,_01_Jan_2014_15:25:24_GMT;_path=/;_domain=_www_asianfanfics_com
ebPanelFrequency__www_asianfanfics_com=\"\";expires=Tue,_01_Jan_2013_15:43:39_GMT;_path=/;_domain=_www_asianfanfics_com
So if $_COOKIE[$key] = $value, $key is not passing CI's check and $value is always empty. When inspecting that cookie on Chrome's cookie inspector, I see that it is set for the www subdomain and under expires, instead of a date, it says "session".
The only other question on SO relating to this is due to someone using the jQuery Tabs plugin which I'm not using.
Does anyone know what could be setting this cookie?
By the name of the cookies (starting with ebNewBandWidth and ebPanelFrequency), you might want to ask LinkedIn if their servers have injected some code into client resources served by your server or otherwise connected to your website or domainname it is served from that has created these cookies:
LinkedIn Corporation
Attn: Privacy Policy Issues
2029 Stierlin Court
Mountain View,CA 94043
USA
http://www.linkedin.com/static?key=privacy_policy
Might because generally everybody can set everything which is acccepted as a valid cookie name from the browser requesting with such cookie request headers.
Session in that cookie means, it will expire when the browser is closed.
The rest looks like that Codeigniter is dropping that cookie for some reason. Probably only a pre-caution.
Any HTTP client can send any kind of cookie request headers to your server, so there is nothing you can do against that.
The cookie is always set by the user-agent, at least the cookie in the request that is causing the error (what goes into $_COOKIE).
Which process originally has set this specific cookie can not be said by the name of the cookie only. Any process can create any kind of cookie header, and the cookie seems at least valid enough to make the browser send it with the requests.
Probably Codeigniter needs some fix or setting here so you can make use of such keys, e.g. you might want to disable that (in your case useless?) check.
I believe MediaMind formerly EyeBlaster (hence eb prefix to cookies) is behind these cookies. Their service is widely used by banner adservices, so they may well be involved indirectly by a service your site uses. The infiniti cookie page referred to above links them to ebNewBandWidth.

Categories