If one needs to create an office website (that serves as a platform for clients/customers/employees) to login and access shared data, what are the security considerations.
to give you some more detail,
The office portal has been developed in django/python and hosted through GAE. Essentially, the end point comes with a login/password to enter into the portal and access data.
I would like to know:
a) what are the things we can do to bring in a high level of security. Essentially the data is critical and hence need to be accessed by authorized people only. So would like to make it such that "The app is as safe as - how safely one keeps his password. Meaning, the only way to enter the system (unauthorized) is through a password leak (by the person) and not in any hackish way." :)
b) can we host the apps on GAE (appspot.com) with https?
c) are there better ways to secure other than passwords (i have heard about ssh keys/certificates). But the ultimate users may not be highly tech savvy.
There is always the choice between usabiity and secutity. The more security features you implent, the more difficult it gets to use it.
can we host the apps on GAE (appspot.com) with https?
Yes, but not on your own domain, only on appspot.com. If you are serving your app off of an own domain, you must direct all secure traffic through your app's appspot domain (on your own domain, you'd have to buy a SSL certificate, and you would need a dedicated IP etc.). If you really have to, there are ways to route SSL traffic over your own domain, but as this requires another server running something like stunnel, it gives attackers another attack target.
If your app has username/password authentication, the app is really as safe as how safely one keeps his password, if you have no bugs in your code that could be exploited. About the "hackish way": on GAE, you don't have to care about server security, the only possible attack target is your code.
These are some strategies for securing your app:
good QA and code review to find critical bugs; Django has already built-in protection against most trivial attacks like XSRF and SQL injection, so look at the parts of your own code that are related to critical data and authentication
think of other authentication methods like client side certificates (easy to use for the end user, most browser support this natively and modern operating systems have a certificate storage; probably not an easy thing to do on GAE)
the weakest point of every secure enviromnent is the user, so you should inform the users about good practices on handling sensitive data and passwords (BTW, requiring a password change every few months does not improves security at all as it usally results in users writing down their passwords as they can't remember it, you loose more security than you gain)
you should have good intrusion detection to lock out an attacker as soon as possible, as example behaviour analysis; Example: if a user from the USA logs in from an IP in Estonia, this is suspicious
network access restrictions: you could block all IP ranges except those from your enterprise of accessing critical data, if a password gets leaked, this minimizes the possible impact
improve end user security: if one of the users have a trojan on their computer that makes screen captures or keylogs, all your security is lost as the attacker could just watch the user while he's vieweing sensitive data; you should have a good security police in your enterprise
force users to access your site over SSL, you should not let the users choose if they prefer security ocer comfort of not
Related
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
The attack
One possible threat model, in the context of credential storage, is an attacker which has the ability to :
inspect any (user) process memory
read local (user) files
AFAIK, the consensus on this type of attack is that it's impossible to prevent (since the credentials must be stored in memory for the program to actually use them), but there's a couple of techniques to mitigate it:
minimize the amount of time the sensitive data is stored in memory
overwrite the memory as soon as the data is not needed anymore
mangle the data in memory, keep moving it, and other security through obscurity measures
Python in particular
The first technique is easy enough to implement, possibly through a keyring (hopefully kernel space storage)
The second one is not achievable at all without writing a C module, to the best of my knowledge (but I'd love to be proved wrong here, or to have a list of existing modules)
The third one is tricky.
In particular, python being a language with very powerful introspection and reflection capabilities, it's difficult to prevent access to the credentials to anyone which can execute python code in the interpreter process.
There seems to be a consensus that there's no way to enforce private attributes and that attempts at it will at best annoy other programmers who are using your code.
The question
Taking all this into consideration, how does one securely store authentication credentials using python? What are the best practices? Can something be done about the language "everything is public" philosophy? I know "we're all consenting adults here", but should we be forced to choose between sharing our passwords with an attacker and using another language?
There are two very different reasons why you might store authentication credentials:
To authenticate your user: For example, you only allow the user access to the services after the user authenticates to your program
To authenticate the program with another program or service: For example, the user starts your program which then accesses the user's email over the Internet using IMAP.
In the first case, you should never store the password (or an encrypted version of the password). Instead, you should hash the password with a high-quality salt and ensure that the hashing algorithm you use is computationally expensive (to prevent dictionary attacks) such as PBKDF2 or bcrypt. See Salted Password Hashing - Doing it Right for many more details. If you follow this approach, even if the hacker retrieves the salted, slow-hashed token, they can't do very much with it.
In the second case, there are a number of things done to make secret discovery harder (as you outline in your question), such as:
Keeping secrets encrypted until needed, decrypting on demand, then re-encrypting immediately after
Using address space randomization so each time the application runs, the keys are stored at a different address
Using the OS keystores
Using a "hard" language such as C/C++ rather than a VM-based, introspective language such as Java or Python
Such approaches are certainly better than nothing, but a skilled hacker will break it sooner or later.
Tokens
From a theoretical perspective, authentication is the act of proving that the person challenged is who they say they are. Traditionally, this is achieved with a shared secret (the password), but there are other ways to prove yourself, including:
Out-of-band authentication. For example, where I live, when I try to log into my internet bank, I receive a one-time password (OTP) as a SMS on my phone. In this method, I prove I am by virtue of owning a specific telephone number
Security token: To log in to a service, I have to press a button on my token to get a OTP which I then use as my password.
Other devices:
SmartCard, in particular as used by the US DoD where it is called the CAC. Python has a module called pyscard to interface to this
NFC device
And a more complete list here
The commonality between all these approaches is that the end-user controls these devices and the secrets never actually leave the token/card/phone, and certainly are never stored in your program. This makes them much more secure.
Session stealing
However (there is always a however):
Let us suppose you manage to secure the login so the hacker cannot access the security tokens. Now your application is happily interacting with the secured service. Unfortunately, if the hacker can run arbitrary executables on your computer, the hacker can hijack your session for example by injecting additional commands into your valid use of the service. In other words, while you have protected the password, it's entirely irrelevant because the hacker still gains access to the 'secured' resource.
This is a very real threat, as the multiple cross-site scripting attacks have shows (one example is U.S. Bank and Bank of America Websites Vulnerable, but there are countless more).
Secure proxy
As discussed above, there is a fundamental issue in keeping the credentials of an account on a third-party service or system so that the application can log onto it, especially if the only log-on approach is a username and password.
One way to partially mitigate this by delegating the communication to the service to a secure proxy, and develop a secure sign-on approach between the application and proxy. In this approach
The application uses a PKI scheme or two-factor authentication to sign onto the secure proxy
The user adds security credentials to the third-party system to the secure proxy. The credentials are never stored in the application
Later, when the application needs to access the third-party system, it sends a request to the proxy. The proxy logs on using the security credentials and makes the request, returning results to the application.
The disadvantages to this approach are:
The user may not want to trust the secure proxy with the storage of the credentials
The user may not trust the secure proxy with the data flowing through it to the third-party application
The application owner has additional infrastructure and hosting costs for running the proxy
Some answers
So, on to specific answers:
How does one securely store authentication credentials using python?
If storing a password for the application to authenticate the user, use a PBKDF2 algorithm, such as https://www.dlitz.net/software/python-pbkdf2/
If storing a password/security token to access another service, then there is no absolutely secure way.
However, consider switching authentication strategies to, for example the smartcard, using, eg, pyscard. You can use smartcards to both authenticate a user to the application, and also securely authenticate the application to another service with X.509 certs.
Can something be done about the language "everything is public" philosophy? I know "we're all consenting adults here", but should we be forced to choose between sharing our passwords with an attacker and using another language?
IMHO there is nothing wrong with writing a specific module in Python that does it's damnedest to hide the secret information, making it a right bugger for others to reuse (annoying other programmers is its purpose). You could even code large portions in C and link to it. However, don't do this for other modules for obvious reasons.
Ultimately, though, if the hacker has control over the computer, there is no privacy on the computer at all. Theoretical worst-case is that your program is running in a VM, and the hacker has complete access to all memory on the computer, including the BIOS and graphics card, and can step your application though authentication to discover its secrets.
Given no absolute privacy, the rest is just obfuscation, and the level of protection is simply how hard it is obfuscated vs. how much a skilled hacker wants the information. And we all know how that ends, even for custom hardware and billion-dollar products.
Using Python keyring
While this will quite securely manage the key with respect to other applications, all Python applications share access to the tokens. This is not in the slightest bit secure to the type of attack you are worried about.
I'm no expert in this field and am really just looking to solve the same problem that you are, but it looks like something like Hashicorp's Vault might be able to help out quite nicely.
In particular WRT to the problem of storing credentials for 3rd part services. e.g.:
In the modern world of API-driven everything, many systems also support programmatic creation of access credentials. Vault takes advantage of this support through a feature called dynamic secrets: secrets that are generated on-demand, and also support automatic revocation.
For Vault 0.1, Vault supports dynamically generating AWS, SQL, and Consul credentials.
More links:
Github
Vault Website
Use Cases
I'm writing an oauth2 provider and am not sure how to implement client registration. The oauth2 specification doesn't cover this aspect:
The means through which the client registers with the authorization server are beyond the scope of this specification but typically involve end-user interaction with an HTML registration form.
Moreover, the oauthlib documentation has the following to say about the Client data model:
It is common practice to link each client with one of your existing users. Whether you do associate clients and users or not, ensure you are able to protect yourself against malicious clients.
Now I sure would love to protect myself against malicious clients, but how can I link a client to a user if registering a user requires a registered client?
The oauth2 spec again has something to say about this, but it's very cryptic:
Client registration does not require a direct interaction between the client and the authorization server. When supported by the authorization server, registration can rely on other means for establishing trust and obtaining the required client properties (e.g., redirection URI, client type). For example, registration can be accomplished using a self-issued or third-party-issued assertion, or by the authorization server performing client discovery using a trusted channel.
Questions
How should a client be registered if linking to a user is required, given that registering a user requires a registered client?
How should a client be registered if linking to a user is not required? What is meant by 'redirection URI, client type, and third-party-issued assertion?
When answering this question, I am going to assume there is already an access control framework that this provider will be attached to, and the application that will use this provider will have HTTP access and has capabilities to handle HTML forms, as no details on this whatsoever were provided by the question (i.e. what framework is this provider going to sit on, or is it something completely naked and standalone on some homebrewed framework).
I'm writing an oauth2 provider and am not sure how to implement client registration. The oauth2 specification doesn't cover this aspect:
The means through which the client registers with the authorization server are beyond the scope of this specification but typically involve end-user interaction with an HTML registration form.
While it doesn't spell it out explicitly, it did suggest that typical registration of a client involves end-user interaction with a form. If you see how others have done it (such as through imgur's API, OAuth 2 user documentation) you will find that it provides a Registration link and hey that's how clients are registered. No OAuth 2 is required as you are already authenticated via the browser.
Now I sure would love to protect myself against malicious clients, but how can I link a client to a user
By linking your server applications's representation of the client details to the user (tracked by some system) that created those client details? It's not like user specific data suddenly becomes more mystical just because it is used for authenticating an OAuth2 client. If you find abuse related to access using those client details (from your logs) you could just revoke those credentials related to that client, and punish the user that own that client. (Unless it's their clients... erm, your other users using that client is doing the abuse but you should be able to see that, right?)
if registering a user requires a registered client?
If you really want to have people register their clients using their client before they register their client, that's pretty much madness (i.e. a chicken and egg problem that shouldn't need to exist). Nowhere in the specification this was ever suggested that they are mutually inclusive problems. Here, to simplify this:
You can use a registered client to register a user
You can register a client to a registered user
Those two things are completely separate from each other. You have to have one before the other (actually, you can create a user registration form that also generates a client credentials at the same time, but I digress), but really, a registered client is essentially reducible to some credentials that are shared between that client and the provider it is registered against.
You can make your own registered clients, too, since you have full control of the provider, you can inject any credentials that will be used by that registered client of yours to do whatever you need, including registering new users, but...
How should a client be registered if linking to a user is required, given that registering a user requires a registered client?
You know you can just register a user using a standard HTML registration form? Just use the user registration form that the framework provided, or write one* if that framework doesn't already provide one.
How should a client be registered if linking to a user is not required?
When I implemented an OAuth1 provider for Plone, client registration can only be done by administrators/managers of the site, so not something user can do, thus someone has to contact the owners of the site to find out how to do it. This generally removes the security problems associated with not linking clients to users (since clients are now linked to actual people coding those clients up who are not necessarily users of the site through external means).
I realized I did not really answer this question, but this is really up to your implementation and what needs/restrictions you decide to limit/provide. I mean you can have a totally anonymous form on your site and let it rip, but I don't think you want that as that weakens security of your application dramatically.
What is meant by 'redirection URI, client type, and third-party-issued assertion?
If you go to the sections as specified in the RFC, you will find answers there:
Redirection URI
There is actually quite a lot of ways to subvert the security of your users' (resource owner's) data if this is not carefully understood, but is used by the authorization server to "redirects the resource owner's user-agent back to the client", as the authorization is done on the authorization server which is part of the provider's infrastructure. So in general, the client has to let the authorization server know where/how it gets back to itself after the resource owner authorizes the client's access through this redirection URI. However, if the redirection URI specified is not verified, security issues can and will happen.
For instance, native applications (a client profile of the client type public) will (used to, I am coming from an OAuth1 background) have the complete client credentials embedded inside the application, which will be extracted by hostile attackers in a bid to masquerade as a legitimate web application (another client profile, but can be considered as a confidential client type) that makes use of your application's services. Once the hostile attackers are up and running they will entice your users (resource owners) to use their masqueraded site, and grant the masqueraded site their access tokens through your authorization server and if redirection URIs are not validated, it will redirect your users (resource owners) to the attacker with the authorization code (as outlined in section 1.3), giving the attacker access to your resource owner's data.
That was the easy common case - another problem case is that your other web application client might have a credential leak without them knowing, resulting in this exact scenario.
Hence this is why they suggest that you should only "redirect the user-agent to the client's redirection endpoint previously established with the authorization server during the client registration process... after completing its interaction with the resource owner", which can mean that only the domain name registered to that client will be legitimate redirection targets, otherwise something went wrong and your authorization server aborts and does not provide the authorization grant.
Client Types
Again, just read/scrutinize all that carefully.
Third-party-issued assertion
As opposed to self-issued client registration done kind of like a client registration form, your application might delegate the client authentication to a third party which will do the verification for you. If you have to worry about this and don't know where to start I suggest you ignore this and just only do self-issued client.
* Are you really sure you want to write an OAuth2 provider without any underlying user/ACL framework for you to hook this to? I mean you can write one but you should really build that part first before you worry about OAuth2 (again, I am not making any assertion, since the question provided no information on this).
Now, if you are not doing this as part of some existing framework but just something standalone that you want to toy/try out as learning, I strongly suggest you to pick something else because this is probably beyond what you can do in a correct manner. Especially if you don't already fully understand the implication of this with regards to the underlying ACL and security of the resource owner's data, and other related stuff.
No offense, but these things are very very difficult to do correctly. Even the bigger companies have had security issues with their OAuth2 solutions.
Finally, speaking from experience, I spent about four (4) weeks (!) staring at the OAuth1 specification years ago, using a poorly written Python OAuth library (later replaced with oauthlib, which is much better) in an attempt to build an OAuth1 provider on top of Plone, before I got a single line of code directly related to the provider committed. A lot of junk/trial code written was thrown away, and this was done because understanding all of this stuff actually took time (granted, I was not exactly working full time on this, had other responsibilities too which was distracting me from this). Another part of the time was spent trying to understand how the user/security stuff is put together at the Zope/Plone layer. Granted I was still relatively new to that side of that framework, but I can guarantee you that this road is not going to be easy... however I did seem to find that OAuth 2 cleaned things up in some ways to make it easier to understand, but find that the security may have been weakened. That said, I currently have no immediate plans to port my Plone addon to support 2.0 as my sponsors does not require that, so there may be things I suggested up there that may differ slightly from 2.0. Would love to hear your comments if others have read this far. I wrote way more words than I originally intended to, oops.
Anyway, good luck on your adventures.
Additionaly for dynamic registration, please go through this spec as well
https://www.rfc-editor.org/rfc/rfc7592
There are multiple mobile apps.
I want people using one app to login with their same login credentials into all other apps.
What is the best approach to implement this?
I'm thinking to create a separate authorization server that will issue tokens/secrets on registering and logins. It will have a validation API that will be used by mobile app servers to validate requests.
There is a protocol for handling this called Central Authentication Service(http://www.jasig.org/cas), or CAS. CAS utilizes OAuth2 protocol to provide a secure way to manage a single sign on procedure -- users have a single login credential that is used via tokens and proxy tickets to authenticate the user across a variety of applications using a single CAS authentication server. This is a procedure the company I work for uses to authenticate users across multiple applications (we use Java with Spring Security and Spring CAS) however this summer we built out a proof of concept with Django and an internal company API in which we implemented CAS procedure with the Django application -- Django authenticated users via the CAS server we run and returned them as valid, authenticated Django users. To do this we used the django-cas middleware and custom backend library which can be found here: https://bitbucket.org/cpcc/django-cas/overview.
CAS is definitely the way to go if you're looking to handle user authentication with a single sign on across multiple applications -- it was the reason CAS was created in the first place. The learning curve with CAS can be a little steep but django-cas does a good enough job making it easy to get set up with CAS in the Django project.
First check if OAuth could be adapted to using this, that would save you a lot of work. Of course all the services and apps would have to talk to some backend network server to sync tokens issued to apps.
Half-secure/maybe-abusable solution: have symmetric cipher encrypted cookie that webpages (and apps?) hold and use it for authorization with different network services (which again have to verify cookie for authorization with authorization service that knows the passphrase used to encrypt the cookie)
I've used approach #2 on internal systems but I am not sure if it is advisable to use it in in the wild - this may pose some security risks.
The authentification method in every application connects to the same webservice for autentification.
I'm building a centralized desktop application using Python/wxPython. One of the requirements is User authentication, which I'm trying to implement using LDAP (although this is not mandatory).
Users of the system will be mechanical and electrical engineers making budgets, and the biggest problem would be industrial espionage. Its a common problem that leaks occur commonly from the bottom on informal ways, and this could pose problems. The system is set up in such a way that every user has access to all and only the information it needs, so that no one person but the people on top has monetary information on the whole project.
The problem is that, for every way I can think to implement the authentication system, Python's openness makes me think of at least one way of bypassing/getting sensible information from the system, because "compiling" with py2exe is the closest I can get to obfuscation of the code on Windows.
I'm not really trying to hide the code, but rather make the authentication routine secure by itself, make it in such a way that access to the code doesn't mean capability to access the application. One thing I wanted to add, was some sort of code signing to the access routine, so the user can be sure that he is not running a modified client app.
One of the ways I've thought to avoid this is making a C module for the authentication, but I would rather not have to do that.
Of course this question is changing now and is not just "Could anyone point me in the right direction as to how to build a secure authentication system running on Python? Does something like this already exist?", but "How do you harden an scripting (Python) against wrongful modification?"
How malicious are your users? Really.
Exactly how malicious?
If your users are evil sociopaths and can't be trusted with a desktop solution, then don't build a desktop solution. Build a web site.
If your users are ordinary users, they'll screw the environment up by installing viruses, malware and keyloggers from porn sites before they try to (a) learn Python (b) learn how your security works and (c) make a sincere effort at breaking it.
If you actually have desktop security issues (i.e., public safety, military, etc.) then rethink using the desktop.
Otherwise, relax, do the right thing, and don't worry about "scripting".
C++ programs are easier to hack because people are lazy and permit SQL injection.
Possibly:
The user enters their credentials into the desktop client.
The client says to the server: "Hi, my name username and my password is password".
The server checks these.
The server says to the client: "Hi, username. Here is your secret token: ..."
Subsequently the client uses the secret token together with the username to "sign" communications with the server.