WTForm hidden-token update when it expires with SocketIo - flask-wtforms

Im developing a app which has a form but i need the form to be usable for long periods of time because the app works in a static tablet fixed to a wall. Im using a hidden tag, so when it expires the page must be refreshed manually. Im using sockets so i thought that instead of taking off the expiring time of tokens i could send a new token through a socket when the expiry time is coming. The problem with sending a new token is how and if i should do it...
I thought a solution by sending new tokens every 30 minutes to the clients:
It starts by sending 2 tokens on rendering (instead of just the hidden tag).
One of them (the one that is not the wtform token) uses jwt and is the result of encrypting a datetime which is the datetime when the actual hidden tag was updated (in rendering would be created on request so it would be the time of rendering). The second token is the token of the hidden tag itself.
Every 30 minutes the client-side would send a request with the jwt token to a socket handler that would check that have at least passed 30 minutes from the datetime in the token and then emit the 2 tokens (the new token of wtforms and the updated encrypted datetime to use in the next emit by the client-side) this way i prevent some client from editing the front end to send thousands of request for new tokens which i thougt could be problematic (maybe its not).
I dont think pasting the code would be of much help because i have a theorical question about working of the logic of the code more than a code itself.
My expected result is to have a working front-end form which uses a token to prevent csrf without deactivating the expiry time of the tokens.
MY QUESTIONS ARE:
is there a real necessity of using that jwt encrypted token instead of just giving a new token to every client asking for one ?
is there a better solution to the problem i have more than the one i thought ?

Related

Google Analytics Data Feed 400 Bad Request on First Request Only

I have an inherited VB6 program that runs each morning to download Google Analytics feed data for several clients. The process does the following:
Checks that my current OAuth 2.0 Access Token (saved in my database from yesterday) has not expired, and if so obtains a new one. Naturally, when the program runs for the first time each day it gets a new Access Token.
For each client, post a request for feed data.
Processes the XML data received from the Google server.
My problem is with step 2 above. The first post using the new Access Token always fails with a 400 Bad Request error. Making a second post using the exact same data always succeeds and my program can move to step 3.
Here is an example of my POST (with Client Id and Access Token in [ ] brackets):
https://www.google.com/analytics/feeds/data?
ids=ga%3A[Client Id]&
start-date=2016-01-10&
end-date=2016-01-10&
metrics=ga%3Asessions%2Cga%3Atransactions%2Cga%3AtransactionRevenue&
dimensions=ga%3Amedium%2Cga%3Asource%2Cga%3Akeyword&
filters=ga%3Asource%3D%3Dshopping&
access_token=[Access Token]
This has been occurring for several weeks.
The error description (Err.Description) from my code is "400 Bad Request". The entire response from the Google server (less HTML) is "400. That's an error. Your client has issued a malformed or illegal request. That's all we know."
Can anyone offer any suggestions as to why the first request fails, but subsequent requests don't? I have even built in a five minute delay between getting the new Access Token and making the first data request, but still get the 400 Bad Request Error.
Any help you can offer would be greatly appreciated.
Thanks.
Using Fiddler (thank you M Schenkel) I was able to finally track the source of the problem.
My VB6 program is using the IP*WORKS! SSL component from nsoftware. The form had a single HTTPS component that was being used for (1) getting a new Access Token, and then (2) for getting the feed data.
Fiddler showed that the second use of the component was using some of the parameters from the first use of it.
I added a second HTTPS component to the form so my feed data request would start off with a blank slate and it worked.
Thank you very much for your help!

ASP.NET MVC Anti Forgery Token is not one-time (per request) token?

I've read a lot of articles and made some own tests and what I can see from my tests and source code (IsCookieTokenValid and GenerateCookieToken - you can see there hard coded IsSessionToken = true) that ASP.NET Anti Forgery Token is per session, not per request (or POST request and so on). So token stored in the cookie remain the same during user's session. But token on the form changes (it's new) with every request (page refresh).
I've check if form submit with old form tokens are still valid, and they are. So what's the point to generate every time new form token if old tokes still valid and token in the cookie remains the same during the user's session?
I don't see in the code any setting to change this behavior and make token "one-time". The only option or solution is to delete the cookie and that will force to generate the new one. Correct? Any other ideas?
I ended up modifying ASP.NET MVC library and added setting GenerateOnetimeToken to AntiForgeryConfig to be able generate new pair of tokens (cookie and form tokens) with every page request (AntiForgeryToken() helper call).
Here is ASP.NET MVC 5 branch for this change.

Requesting header by name angular

I have an asp.net application that I'm attempting convert the front end to Angular. Getting header information is important to the view. I'm used to getting the header information like so in C#:
httpContext.Request.Headers["USERID"]
How can I do the same thing in an angular controller?
In asp.net each request runs in its own independent context and hence the header access as you have shown in your code make sense.
This does not hold good for angular or in fact any client side framework. You can always get the headers for any request or response made using angular $http but the question is which request? During the lifetime of the app you would make many such requests.
Let's say you want to get the current userid, you can create a service that returns the logged in user. There are two ways to implement such a sevice
create a method on server to return this data. Invoke this method from service and cache results
on the client side assuming there is a login request made through angular, implement a success callback method which can update the service with the logged user id.
You can look at $http documentation here to understand how to access headers.

how to save and retrieve cookies using ajax webservice calls

Hi I have web app which stores certain things on a page in a cookie when the page posts back in case the user doesn't finish what they're doing and come back later. But now I must do a javascript time-out and actively save the info to the cookie rather than wait for the user to postback. All my cookie code is on server side where I use Response and Request objects to read and write cookies and I want to leverage that. So I would like to just use ajax calls to a webservice. Is there a way for me to access Request and Response objects and read and write cookies to the browser via those objects during a webservice call? Or should I just go with javascript?
EDIT: Sorry i wanted to specify that I would like to use jquery-ajax.
Implement an ajax callback on a timer that posts back every n number of seconds. When the ajax posts back, check your constraints and simply update the cookie.
OK so I created the static web method on .cs side of the page and in the method I enable session. So this way, I can save stuff to cookie by making ajax calls and using my already existing .cs cookie code.

Time sensitive webpage access

Is it possible to create a page that redirects to a private page if a correct time sensitive variable is passed?
Ex:
http://www.mysite.com/redirectpage.aspx?code=0912042400
The code value is a year-month-day-time combination that must fall withing some time window (15 min, 30 min etc) based on the server's time.
The redirectpage would parse the code and would redirect to a private page (using an obfuscated url with the code variable) if the code is valid or show a 404.
Usage scenario:
Party A wishes to show party B a private page.
A sends a link to B with a code that is valid for the next 30 minutes.
B clicks the link and is redirected to a private page.
After 31 minutes clicking the link produces a 404 and a refresh/postback of the private page also produces a 404.
Thanks
Yes.
One approach is to concatenate the "valid start time" with a private string known only to the server. Generate a has code (e.g. MD5 hash) based on that concatenated value. Send the "valid start time" and the hash back to the client. They pass both back in to view the page. The server re-combines the "valid start time" with the secret key, recomputes the hash, and ensures it matches the passed-in hash. If it matches, compare the passed-in time to the server time to make sure the redirect is still valid.
There is no need for a database of valid keys and what time range they pertain to with this approach. You can even add the page name for the redirect to the time to make the system completely self-contained.
Server computes:
Hash = md5("2009-12-12 10:30:00" + "MyPage.aspx" + Secret Key)
Send to client:
"2009-12-12 10:30:00" + "MyPage.aspx", Hash
Client later sends to server
"2009-12-12 10:30:00" + "MyPage.aspx", Hash
Server checks
newHash = md5("2009-12-12 10:30:00" + "MyPage.aspx" + Secret Key)
Hash == newHash?
Yes and time within window then redirect, else error.
This is a simple task for a database connected web appliction. The basic algorithm would be to insert a "ticket" into a database table. The ticket would be composed of a random string and a timestamp.
When a request comes in for the page, the script that generates that page can look in the ticket table to see if there is a record that matches the code passed in via the URL argument. If there is a record, the script then checks to see if the timestamp is expired. If so, generate the 404 page. Otherwise show the correct info.
There may be a pre-built content management system module or a caned script that can do this, but I don't know of one myself.
As an example, in ASP.net i would cache a keyvaluepair with the code and the redirect page, and set the cache timeout to 30 mins, just a quick example, but this is very possible.
The one issue you are going to run into here is how easy it would be to simply change the url and view private information.
The approach I would take would be this:
When the private page is generated, make a new record in the database with an encrypted key, that contains the starting availible time, and the starting ending time.
Put this encrypted ID in the URL.
when the person goes to the page, look up the timestamps, make sure they are within range, then redirect them to a 404 page.
One way of doing it is to pass the page an encrypted time-limit as part of the query string. Something like http://www....aspx?timelimit=[encrypted]. Where [encrypted] isn't user editable. You may just need to hash the DateTime somehow.
Yes, you could do it that way. However, encoding the valid date range in the value passed is a security risk.
A better approach would be to generate a random code and store that code in a database along with a date range for when the code is valid.
That way there's less of an opportunity for malicious users to guess valid values.
Do you know ahead of time, when the X minutes will start ? Some sites have promotion codes for specific times (hours,days etc) and if you know it ahead of time you can check if the request from the client is within those times.
If you do not know it ahead of time, this is what I would do.
Make sure that the user given token/code is valid
Create a session object with the code as the session key(you can do that in asp.net, not sure about other programming languages) and the IP (or any unique string as value for that key, if behind a proxy, IP will not work, so generate a GUID and pass it as a secure cookie to the client when sending the response). This will prevent multiple users from accessing the secure resource at the same time (though not sure if this is a part of your requirement)
note down the first request time in the session and DB
You can expire the session after X minutes (Get Session to expire gracefully in ASP.NET) .
For subsequent requests check the validity of the key(cookie) sent by the client (against the server side value) and the request time with the first request time + X minutes, If the Key & time is valid, let him access the resource, if the Key is invalid, tell the used that there is already a session in progress
If the user tries to access it after X minutes, (you know it from the session) send a "your page cannot be served as your X minutes has expired since visiting the page the first time" instead of sending a 404 (404 says the resource was not found and would not convey that the request time was not valid) or log him out

Resources