Pausing and resuming a Mediawiki edit session - session

Is it possible to pause and resume a Mediawiki edit?
To explain, I've written a MW extension that accesses an external database; this database requires OAuth authentication, which is a three-step process requiring the user to be redirected to an external site to allow the extension access to the external db. If the MW extension already has an access token for the extDb, all is well. However, if there isn't a token, there is a problem. This is a tag extension, and is triggered by finding a certain XML tag in the wiki page, which typically occurs in the 'preview' or 'submit' of an edit, e.g. http://server.com/wiki/index.php?title=Bibliography&action=submit (the parser hook is ParserFirstCallInit). The callback URL constructed by the OAuth code returns you to the page you were editing, but in its pre-edit state: i.e. you lose all your edits.
How can I resume the edit and not lose my edit data?

You could just use store the data in $_SESSION. MediaWiki itself uses it to store user authentication data, so it should be well integrated with MediaWiki's own session handling.
Note that, by default, MediaWiki doesn't create a session for anonymous users unless they try to log in or do something else that requires a session. If your external authentication code is only meant to be used by logged-in users, this should not be an issue, but just to be safe you may want to make sure that a session is set up before trying to use it:
if ( session_id() == '' ) {
wfSetupSession();
}

Related

What would cause redis to retain an old key?

We're running an install of Magento Enterprise which has built-in support for using Redis as a session handler.
For context: We're having with a module that implements PayPal payment method as an option for our users.
The module generates a lightbox with the PayPal form in it so that the user doesn't have to be redirected away from the page.
To do this, we have to generate a token, and save it to the session. The lightbox loads in the PayPal page with the token in the URL parameter.
When the user completes the form, the user is redirected to a confirm order page with the same token in the URL.
The URL token has to match the session token, or else the process fails.
This works fine when we disable redis and use normal file sessions (which we cannot do in our production environment).
Here is what we don't understand:
When we step through the code with xdebug with breakpoints, we see the token being set in the session in redis. The payment processing works fine.
When we don't step through the code, the process fails due to a token mismatch, and when we inspect the token key throughout the process, it originally sets it correctly, and then at the end, the token is we see is a token that was set several sessions ago.
The TTL on the session key is 24 minutes but don't think that should be an issue because it should be overwriting the value. Not sure why it works fine when we pause through the process with breakpoints.
Any ideas?
Is it the standard Magento PayPal module?
My first thought is that something else is storing an object to redis (and it should not do it) and later requests receive a cached value because this object is cached.
Maybe do a simple test:
Clear redis cache
Place an order and proceed to PayPal
Is at this point everything ok?
Check the token stored in Redis for this particular session and write it down
Place another order & proceed to Paypal
Verify whether the received token is the same as the previous one

A pattern to implement a secure client side session storage (web site)

I need to store a state of a paging component between page visits (specifically I need to save currently viewed page, number of items to show per page, and filter/search criteria text).
At first I thought about using localStorage to create a client-side-local-session. But this does not work in IE8, so I fall back to using session cookies when in IE8. But filter/search criteria is sensitive data so session cookies are not acceptable.
Now I am thinking about using server side session storage, but I would like to make the implementation transparent. The idea is to create a global javascript object (or jQuery plugin) called "local session". Local session implementation will send its content with every request (using jQuery AJAX beforeSend callback). So every request will send a fresh state of the clients "local session".
Server than will include all local session data with each freshly rendered page (i.e. only for non-AJAX responses).
I am using ASP.NET MVC and it would be easy to create a global filter that will be collecting this "local session" data and storing it in the server side session.
Two questions:
is storing sensitive data in javascript object any more secure than storing this data in session cookie?
would it be a good idea to send local session content as a header (I can do some optimization and only send it when it actually changes, or even only send the changes).
any other suggestions for implementing this requirement?
Note: using history API won't work in IE8, it also not quite what I need (page state should be persisted even if I get back to the page by following a link, not by clicking BACK button).
Note: It would be nice if the solution would work when cookies are disabled, but this is not a strict requirement though.
If you want to protect the integrity and confidentiality of what's sent to the browser to be stored in a cookie you could sign and encrypt the value using server-side secret key(s) like in Ruby on Rails version 4.
However, keep in mind that the cookie would be subject to replay attacks and there is a size limit.

Will .htpassword interfere with AJAX?

Will password-protecting a directory on a server that supports .htaccess interfere with an AJAX request? I have not encountered an error, but have also unlocked the domain on my end, meaning I've started a browser session.
If a directory is password protected you need to provide credentials in order to access it.
The authentication is required only once per session so if the user was already logged in by viewing another page inside the same directory, ajax calls will succeed after viewing that page.
But if the user hasn't accessed any file inside this directory before and immediately sends an AJAX request to a file within it your AJAX request will fail unless you set the appropriate headers.
To see some examples have a look at How to use Basic Auth with jQuery and AJAX?

How to block external http requests? (securing AJAX calls)

I want to use post to update a database and don't want people doing it manually, i.e., it should only be possible through AJAX in a client. Is there some well known cryptographic trick to use in this scenario?
Say I'm issuing a GET request to insert a new user into my database at site.com/adduser/<userid>. Someone could overpopulate my database by issuing fake requests.
There is no way to avoid forged requests in this case, as the client browser already has everything necessary to make the request; it is only a matter of some debugging for a malicious user to figure out how to make arbitrary requests to your backend, and probably even using your own code to make it easier. You don't need "cryptographic tricks", you need only obfuscation, and that will only make forging a bit inconvenient, but still not impossible.
It can be achieved.
Whenever you render a page which is supposed to make such request. Generate a random token and store it in session (for authenticated user) or database (in case this request is publicly allowed).
and instead of calling site.com/adduser/<userid> call site.com/adduser/<userid>/<token>
whenever you receive such request if the token is valid or not (from session or database)
In case token is correct, process the request and remove used token from session / db
In case token is incorrect, reject the request.
I don't really need to restrict access to the server (although that would be great), I'm looking for a cryptographic trick that would allow the server to know when things are coming from the app and not forged by the user using a sniffed token.
You cannot do this. It's almost one of the fundamental problems with client/server applications. Here's why it doesn't work: Say you had a way for your client app to authenticate itself to the server - whether it's a secret password or some other method. The information that the app needs is necessarily accessible to the app (the password is hidden in there somewhere, or whatever). But because it runs on the user's computer, that means they also have access to this information: All they need is to look at the source, or the binary, or the network traffic between your app and the server, and eventually they will figure out the mechanism by which your app authenticates, and replicate it. Maybe they'll even copy it. Maybe they'll write a clever hack to make your app do the heavy lifting (You can always just send fake user input to the app). But no matter how, they've got all the information required, and there is no way to stop them from having it that wouldn't also stop your app from having it.
Prevent Direct Access To File Called By ajax Function seems to address the question.
You can (among other solutions, I'm sure)...
use session management (log in to create a session);
send a unique key to the client which needs to be returned before it expires (can't
be re-used, and can't be stored for use later on);
and/or set headers as in the linked answer.
But anything can be spoofed if people try hard enough. The only completely secure system is one which no-one can access at all.
This is the same problem as CSRF - and the solution is the same: use a token in the AJAX request which you've perviously stored eslewhere (or can regenerate, e.g. by encrypting the parameters using the sessin id as a key). Chriss Shiflett has some sensible notes on this, and there's an OWASP project for detecting CSRF with PHP
This is some authorization issue: only authorized requests should result in the creation of a new user. So when receiving such a request, your sever needs to check whether it’s from a client that is authorized to create new users.
Now the main issue is how to decide what request is authorized. In most cases, this is done via user roles and/or some ticketing system. With user roles, you’ll have additional problems to solve like user identification and user authentication. But if that is already solved, you can easily map the users onto roles like Alice is an admin and Bob is a regular user and only admins are authorized to create new users.
It works like any other web page: login authentication, check the referrer.
The solution is adding the bold line to ajax requests. Also you should look to basic authentication, this will not be the only protector. You can catch the incomes with these code from your ajax page
Ajax Call
function callit()
{
if(window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}else{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
xmlhttp.onreadystatechange=function(){if(xmlhttp.readyState==4&&xmlhttp.status==200){document.getElementById('alp').innerHTML=xmlhttp.responseText;}}
xmlhttp.open("get", "call.asp", true);
**xmlhttp.setRequestHeader("X-Requested-With","XMLHttpRequest");**
xmlhttp.send();
}
PHP/ASP Requested Page Answer
ASP
If Request.ServerVariables("HTTP_X-Requested-With") = "XMLHttpRequest" Then
'Do stuff
Else
'Kill it
End If
PHP
if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )
{
//Do stuff
} else {
//Kill it
}

What's the best way to use HTTP Authentication in an Ajax Application that's not 100% AJAX

I have a standard HTML login page, which I would much rather use than the standard HTTP authentication pop-up provided by browsers. Today, I am using session cookies to keep track of the session after logging in, but I'd like to be stateless and pass the HTTP authentication every time. The web services I am hitting already support this, so this is a browser-only issue.
Adding authentication credentials is trivial in jQuery, but I don't know how to keep them around. If you go from the login page (a jsp) to the Home page (another jsp) you clearly don't keep the username and password fields from the login page. I know some browsers will store your HTTP authentication credentials if you enter them from the pop-up, but I don't know if they get stored when using an XHRRequest. If they do, is there much consistency among browsers?
Also, the user needs to be able to "sign out" of the application, too. If the browser stores the authentication credentials, is there a way to clear them using JavaScript.
I feel like I can't be the first person to try to solve this. Is there some jQuery plugin or something that already handles this? Or is it simply not possible to do what I'm trying to do?
You have 2 options:
1) Client-side storage of credentials -- not a good idea. For obvious reasons you don't want to store the username/password on the client. If you had a hashed version of the password, it might not be so bad, but still not recommended. In any case, if you're going to store on the client side, you either have to use a cookie, or HTML5 local storage (which is not widely supported, yet)
2) Server-side storage of credentials -- typically done with sessions. Then the resultant Session ID can be passed back to the client and persisted in either a cookie or in the URL of each subsequent AJAX call (?SESSID=xyz for example)
The server-side approach would be the most secure, reliable, and easiest to implement
Okay, I'll take a stab at helping ...
Firstly, understand how HTTP authentication works. There are two versions - Basic and Digest. Basic transmits in plaintext, digest is encrypted. With these types of authentication, the username/password are passed in the HTTP header with every single request. The browser captures these at login and they are stored in an inaccessible browser session cookie which is deleted when the browser session is closed. So, in answer to one of your questions, you can't access these from javascript.
You could create your own session cookie variables for username and password. The jQuery functions for this are really simple. See jquery-cookie module as one example of how to set session cookies. These could be retrieved from the session cookie and sent with each ajax request and validated in the server. However, this is not a particulary good way to do authentication since sniffing the network will allow anybody to easily grab your auth details. But, it would work.
Using session cookie based authentication where the session ID is sent sent with each request is the best way to do this. At the server side, you need to have a function called for every HTTP request. This function should do the following:
check to see if the session has been authenticated
if no:
redirect to login screen
if yes:
do authorization and allow the user access to the page
Most web frameworks support session cookie authentication and the management of session ids at the server. This is definately the way to go.
This is interesting one.
Manage user sessions on server by use of cookies. Create a session when user first accesses the login page and pass the session id/key as value to one of the cookie via response. When the user is authenticated put user "key" info in cookie and "values" in application context at server. Once user is logged, any subsequent request will be authenticated based on session cookie value at server. Authorization will be done based on user "key" passed as cookie value.
On logout clear the session based cookies from server and refresh the site to default page.
Cookies are bizarre with different browsers - just a note ;)
Hope this helps.
Update
The answer below was posted in 2012 and the links are mostly dead. However, since then, a more elegant standards-based approach to the same solution appeared using JSON Web Tokens. Here is a good blog post explaining how to use them.
Most answers miss the point, which is to avoid having any server-side session. I don't want any application state in the server. I'll award the bounty to answer that came closest, but the real credit goes to the rest-discuss group and Jon Moore for the correct answer and to Mike Amundsen for helping me to actually understand it.
The best answer I've gotten is to use a cookie, but not the typical automatic session id cookie given to you by most application servers. The cookie (which will automatically be sent with each subsequent request) is a user identifier and time signed by the server. You can include an expiration time with the cookie so it simulates the typical 30 minute session on a server (which means you have to push it forward with subsequent requests) as well as keeps the same cookie from being valid forever.
The XHR/AJAX part is a red herring. This will work whether you are doing XHR requests or an old-fashioned page-by-page web application. The main points are:
The cookie is automatically sent on subsequent requests so there's no
special scripting required - it's just how browsers work already.
The server does not need to store any session for the user, so the user
can hit any server in a cluster and not have to re-authenticate.
Slightly interesting in that you consider pushing some of the authent to the client. If you want a conventional solution, KOGI's server-side suggestion is the way to go.
But you also seem to be asking questions about memory leaks involving your user supplied secrets. Good questions. But to take a general stab at answering that I'd say it would have to be browser specific. It's browser internals, javascript engine internals -dependent where a client side application (i.e., the browser, or js in the browser) is storing the values the user inputs.
Most likely those values are not replicated needlessly throughout memory, but there's no way to guarantee that. Apart from responsible javascript coding practices, there's nothing you can do to guarantee the limit of locations of user inputs.
Slight digression
The basic point is if you store it on the client it is not really secure -- unless, the serve stores encrypted information on the client with a key that only the server (or the user via their correct credentials), has. So you could conceivably code a JS application to do some authent on the client -- much the same as how bank card (used to?) do POS authent by checking the PIN to the PIN on the card, and not back at the DB. It's based on the (somewhat flimsy) assumption the user has no direct read/write access of the "dark area" cookie/local storage on client / mag strip on bank card. So I would only advise this as disqualifier for false authents and not as a sole qualifier for the credentials.
Main point
If you do want to be stateless, just store user credentials in localstorage, or as a cookie but encrypt them with a server key. When you need them send an XHR with the encrypted / use stored credentials to the server over HTTPS, let your server decrypt them and send them to the callback. Then pass those cleartext of HTTPS to do your authent.

Resources