pyramid AuthTktAuthenticationPolicy secret parameter - python

What exactly is the 'secret' parameter of Pyramid's pyramid.authentication.AuthTktAuthenticationPolicy function? The documentation says that it's "(a string) used for auth_tkt cookie signing. Required." The tutorial says that it's "is a string representing an encryption key used by the 'authentication ticket' machinery represented by this policy".
What is auth_tkt cookie signing? What is this 'authentication ticket' machinery? Is this secret supposed to be something I store as a hash in a database or something? I'm really confused.

A tkt auth cookie is a secure hash of several pieces of information, including the username and optionally a timestamp, but not the user password. Once authenticated, you give such a cookie to the user, and every time the user returns you just extract the username again and know it's the same user.
To keep this cookie secure, you need to have a server-side secret, however. Only a server in possession of that secret can create these cookies; if an attacker ever got hold of it he could generate authentication cookies for arbitrary users without ever needing to know the passwords of these users.
The secret parameter for the policy is that server-side secret; it's like a master password for your server. If you run more than one process for your site (and with WSGI, you usually do), you need to make it consistent across your processes, to make sure each process can verify the cookies. You can specify it in your configuration file, in your source code, or in your database; it depends on how much flexibility you need, your security policies, and whether or not you need to share the secret with other systems.
You can share the secret with other systems in your domain that also need to authenticate your users, using the same standard. Apache has a mod_auth_tkt module for example, Plone uses the same standard, and by sharing the secret you can provide a single sign-on for your users across disparate web applications.
Note that changing the secret means existing sessions become invalid, and users would have to re-authenticate.
In any case, existing cookies can have a limited life-span; the embedded timestamp limits how long it will be accepted as valid, if you configure the timeout parameter on the policy. It's good policy to set a timeout, combined with a reissue time; any user that re-visits your application within the timeout will be re-issued a new cookie with a new timestamp to keep their session fresh. That way your session cookies automatically expire if your users do not return, and their cookie cannot be reused by an attacker at a later time. The reissue parameter lets you control how quickly a new token is issued; revisit your server within reissue seconds would not produce a new token.

The secret parameter as far as I remember is just a string used as a salt for the creation of the cookie. You can put whatever you want. Having it in your config file should be more than enough. Saving it in the database might be overkill though if you want to invalidate anything created, I guess changing the secret will invalidate all cookies and session create before that change.

Related

How to check if user is signed in the frontend of swift App. Backend in python/django-rest-framework

Im trying to make an IOS app with a frontend coded in swift and the back in python using django's rest api.
I have a tab bar controller set up with two tabs, one ultimately connected to a HomeViewController. I have used firebaseAuth, in which I would normally use a firebase function that looked roughly like this
if firebase.Auth.currentUser != nil {
let vc = HomeViewController()
present(vc, animated:True)
}
However, to the best of my knowledge, django's rest api does not have a function of doing so, and so I have been stuck for a few hours now trying to figure this out.
Currently, I am planning on using the cached access token, retrieved on registration/login and sending a get request which returns the users information. (username and email). Then creating a function to decode the data which returns a boolean.
I plan on making a struct
struct AuthenticatedUser: Codable, Hashable {
let username: String
let email: String
}
If it does not confirm to the appropriate struct, the json decoder will fail. (This would be because the get request returned an error as the token was deleted. (In the process of logging out, i would delete the users tokens).
Finally, I will end up with something like this
if decodeData == false {
let vc = HomeViewController()
present(vc, animated:True)
}
Im sure this would work, but even as someone new to programming I can tell that this code seems longwinded, messy and most likely considered as bad code.
I was wondering if anyone had any improvement/new methods (preferably new methods) on combatting this problem.
Any help will be much appreciated!
Well, first your app does not strictly need to know a priori if the current user (which is some data stored persistently within the app) is signed-in in order to access protected user resources successfully (eventually).
The mechanism required in order to make this work, can be entirely embedded transparently into the "client network code", and your views and other parts of your app which perform "protected data access" do not need to know anything about the login scheme, or whether the user is registered or signed-in.
What is signed-in anyway?
What is registered?
What is a user?
Assuming you are using the more common login schemes (OpenID Connect or an custom scheme based in OAuth) which is based on user authentication, user consent and a bearer token, these questions can be answered as follows:
A user which is a struct containing some data about a real user is the identity which has been successfully authenticated. This information is available after user authentication and authorization which usually are the first two steps in the "register user" flow. This can happen on a third party identity provider, but can also be included in your domain server.
Once you have an authenticated user, the app registers this user in our domain database as part of the registration flow. That is, after this step, your user is registered, and that means, it can access the services provided by your domain server.
A user also can "unregister" and its private data and especially, the "user" record on the domain server will be deleted or marked "unregistered".
The processes running on the front end for this, can run on the device or anywhere, for example a web application or a desk top application.
Now, what should be immediately become clear is, that given a certain app on a certain device and just by querying local state, an app never can determine a priori if a user is registered or not, even if the app has a user info.
Now, suppose an app has a "current user" info, and that the user has been registered, but it is not yet "signed-in".
Signing in means, that the app receives a refresh token and an access token. The access token is the key to access protected user resources. When doing this, no user info is required, the access token is implicitly associated to this user.
The refresh token acts as a key to get a new access token, whose expiration time is much longer, possibly quite long, so that it literally never expires (not recommended).
The expiration duration of an access token is usually in the minutes. So, it is quite common that the access token expires all the time.
The access token will be required when accessing a protected resource, so it will be needed for every protected access.
When it is expired, the server sends a very specific unambiguous status code. So, your client code can act accordingly, which means:
push the request on a queue
use the refresh token and ask for a new access token on a certain refresh-token endpoint
Retry the request with the renewed access token
This mechanism is completely transparent to the higher level code and can be implemented quite deeply in the client network code.
Now, in the event that the refresh token is expired too, you again get an unambiguously status code from the refresh-token endpoint.
In this case, it is clear what to do:
Require the user to sign-in again
Step one returns a are refresh token and also access token
Retry the request.
It is clear, that this requires user interaction and will interrupt the current active flow. It should also be obvious, that an app can also not determine a priory if the refresh token has been expired.
Ideally, this "sign-in-again" flow can be pushed on top of any other flow which happens to access a protected resource. Alternatively, just let the refresh-token request fail without opening a sign-in flow, showing a clear error message hinting that the user needs to sign-in again.
The consequences of this is, that you have to try (or just can try!) to access a protected resource in order to find out whether a user is signed in or even registered.
This all has to be implemented in the client network code. Good luck! ;)

Pyramid Security - login carries over between separate hosted instances

I develop and maintain a python pyramid web page. It is deployed live on a separate machine that I have administrative access to (call this Server). I also host it on my own laptop (call this Test).
Login accounts are hashed with bcrypt, such that I cannot read user passwords from the live instance. I can, however, replicate the SQL (I use sqlite) from the live instance to my own Test machine, and do so regularly for testing. I would then replace all hashed passwords with my own password for ease of testing.
Recently I realized that if I'm logged in as user X on my Test instance and then open my Server instance in another tab of the same browser, the Server instance acts as if I'm logged in as user X there.
Is this a security flaw in my web page design? Could it be used to gain access to accounts on the system without knowing their password? This php question says this is linked to the session name I've used for my cookie (and I guess to the secret as well). What are the best security practices for this situation?
If you are using the same database on each case (determining what goes into the cookie), and you hash the cookies with the same secret (determining what the outcome of hashing a given payload looks like), then your cookies are interchangeable. This can actually be useful sometimes for multiprocess testing. It's not a security flaw per se, it's by design, but you need to have a separate cookie hashing secret for every deployed instance if you want their cookies not to be usable by each other.
Check if you using the same session secret for development and production environments

Python authentication and HTTP cookie handling

I have two questions regarding security issues.
Intro: I'm developing a command line client that communicates with server (ready product, don't have an impact on code of the server) with Curl. Server requires authentication: username and password (plain text). All requests are made with HTTPS.
I believe using HTTP cookie is a good solution: client will authenticate only once and for another request a cookie can be used.
Firstly: Authentication implementation. Is it safe to store user password in regular python variable? I mean can it be read by a third side during script runtime? (there can be many users on same machine, on the same OS account, every single one has a username and a password [for client - server authorisation] that should remain secret)
Secondly: Would you have some hints about cookie storing? Encrypted file or something like that?
I am using Python 2.6.
Your assumption is correct. As long as the users do not have access to one another’s home directories, there is no need in further hiding the cookie. Your design is secure. Also, since you are developing a CL tool, you could simply use a netrc-like configuration file (it could be .netrc itself) containing the authentication information and forget about cookie management.
EDIT many users have access to one account:
I would consider changing that. However, playing within your constraints, I would suggest you create a log-in and log-out mechanism that generates and returns an authentication token valid for one session only.
appname login
The CLI would prompt from a username and a password. If the latter are valid, the server replies with an alphanumeric sequence valid for one session. The client would save it in a temporary file and use it for subsequent uses.
appname use
And finally,
appname logout
which would invalidate the token and remove the file.

Why CherryPy session does not require a secret key?

I noticed that cherrypy session does not require a secret key configuration. On the contrary, Pylons session does: http://docs.pylonsproject.org/projects/pylons_framework/dev/sessions.html
I'm concerned about security issues if I'm using session to remember user authentication.
Any one can explain why cherrypy session does not need a secret key? Or is there any suggestion how should I make it secure to use session to remember user login?
There are basically two different ways of maintaining session state: on the server or on the client.
With the server-side approach, you keep the session data in files, a database, or in memory on the server and assign an id to it. This session id is then sent to the client and usually stored in a cookie (although they can also be embedded in URLs). Then with each request, the client's session id is read and used by the web application to load the session data from wherever it's stored on the server. This way, the client never has access to any of the session data and can't tamper with it, but the downside is that you have to protect against session hijacking through the use of stale session ids by malicious clients. This is the model used by most web frameworks and applications today.
Another approach is to store the session data completely on the client side inside of cookies. The downside to this approach is that the data can be seen and tampered with by the client, so you have to take care to properly sign and encrypt the data to prevent tampering. This is where having a good secret key comes into play. The upside is that you also don't have to worry about session hijacking.
Pylons uses Beaker sessions, which can be configured to store session data completely on the client side. That's why you need a secret key.
CherryPy only stores session data on the server and then sends the user a cookie with the session id, so the client never sees the session data and can't tamper with it. You can configure it to use files or just keep everything in memory. You can even hook into it and use a database to store the session data in.
Personally, I prefer the approach used by CherryPy, since it's the same approach used by the majority of the web. It's easier to secure, and you can easily share session data with other applications running on your server without worrying about encryption or keys.

Storing flask-jwt auth token. Can I / should I store in database?

I don't know if any of this is the correct way to do this. But here it goes.
(Please let me know if any of this is totally wrong)
I want to store a JWT against a user in flask, is it correct for me to store this in the database?
Currently I'm attempting to check on each request if they have a valid token but am getting a new token each time.
I'm using this.
app.before_request(check_token)
def check_token(*args, **kwargs):
if current_user:
if current_user.is_authenticated:
if not hasattr(current_user, "token"):
set_token()
elif current_user.token_time + timedelta(seconds=current_app.config["TOKEN_SECONDS"]) < datetime.utcnow():
set_token()
Obviously I've found it doesn't preserve the current_user so the token changes every time I make a new request.
1) Is it good practise to save this token in the database? I'm giving it 300 seconds currently. Or is there another way to save it against the current user?
2) I'm using Flask to render the page and I store the users token like this
<button data-token="asdkjhakjsdnkcz8323lkn42lk3n4kj2nkjn2kj3b4kjnlkj32">
Which I then pass to javascript Xhttp requests to update post comments on the fly. Seems like I probably shouldn't but with such a short validity period seems ok?
The decision whether to store the JWT token depends ultimately on the required security strategy.
The JWT token as well as the refresh tokens indeed store in themselves the sign time and their expiration, but this is not relevant on whether to use a persistent storage regarding their sessions.
From the Flask-JWT documentation:
In production, you will want to use some form of persistent storage (database, redis, etc) to store your JWTs. It would be bad if your application forgot that a JWT was revoked if it was restarted. We can provide some general recommendations on what type of storage engine to use, but ultimately the choice will depend on your specific application and tech stack.
Having said that, if the nature of your information is not so sensitive that a possible leak of the tokens matters, then you can avoid the hassle of persistent storage altogether. Otherwise, on logout you would want to revoke the token by closing the stored session.

Categories

Resources