I am working on a program, written in Python 3, for work to automate a number of tasks we do. Currently the tasks are each their own program, but I intend to eventually move them all together under a unified interface (thinking of using prompt-toolkit). My current solution for credentials is just a creds.toml file and each of the needed credentials are stored within it:
[db_name]
user = "me"
pass = "changeme!"
What I'd like to do is maintain the dictionary interface my credentials have, but store those passwords in an encrypted file. Eventually I'd like to have it so that credentials are added through my program so no one needs to interact with the program at all. I think this would be the best for users as we have a mix of sysadmin on my team and not all are too comfortable with CLIs and interacting with text files (silly Windows people ;) ).
What would be my best option for this? I am mostly concerned with accidentally viewing one another's credentials more than I am concerned with anything else. This will be used in a NOC so shifts share the same consoles and would have access to one another's file. It's pretty common to have to go into someone else's home dir to grab a script they wrote or to pick up something they didn't complete on their shift.
Ideally my workflow would be:
s_creds = decrypt(file)
creds = pickle.load(s_data)
session = Database(creds['db_name']
And the Database class would contain:
def __init__(self, cred):
...
self.user = cred['user']
self.pass = cred['pass']
...
I had initially thought that the file would be a toml file that was just encrypted. But it would make more sense to skip that and just serialize a dictionary.
Not too concerned with licenses, but I prefer not GPLv3 because of the hoops.
While editing one of the very first utils I created for this project I stumbled upon my initial credential storage method, keyring. This package allows for storing passwords on the local machine's keyring, in memory, or in an encrypted file (with use of another package, keyring.cryptfile). It will require reworking some stuff, though, as the credentials are not in a dictionary, but in an object.
Using keyring works something like:
>> import keyring
>> svc = 'service_name'
>> usr = 'username'
>> pass = 'qwerty'
>> keyring.set_password(svc, usr, pass)
>> credentials = keyring.get_credential(svc, usr)
>> credentials._username
'username'
>> credentials._password
'qwerty'
I will then be able to make this much more secure than even an encrypted textfile, by letting the OS handle the actual handling of the credentials. This seems like a good solution, while I can say "the passwords don't matter, no one will see them other than people who already have access to the same resources" that's wishful thinking and I should be more security minded with the proverbial "keys to the kingdom".
Related
Basically, I have built a login system.
The first time that a user uses the login system, a text file is created and the username and password are saved there when the user uses a "remember password?" function.
The second time the software uses the system, the system already has the user and password typed in if the user previously used the "remember password?" function.
The thing is, the text file where the password and user are stored can be accessed by simply just going to folder and double clicking on it, which is awful for security reasons.
Is it possible to make it so that the text file can't be accessed outside the program?
It's not possible, as long as you are storing data on your disk, the data will always be readable.
Actuall when you uses .txt, it means that you want it to be readable to others. If you are looking for security, you have to encode your content(Account & Password) to something else that only your program can read.
something similar to chaning 'A' to 'B', '1' to '0', '0' to '7'.....
or another approach used by modern Login Sytem: Hashing your Password
Basically, there isn't a way to securely store a password in clear in a file in the file system.
You can arrange things so that a file can only be read by a specific account on the system. However, someone with admin privilege will (probably) be able to do things that will give themselves access. And there will most likely be other ways to break file system security in some circumstances.
The ideal solution is to NOT store the password. Even storing it encrypted with a private key is a bad idea.
Creating and storing a "salted hash" of a password can be secure ... provided that there is no way that a "bad guy" can capture the password characters before they have been hashed, but I don't think that is going to help you here ... since you apparently need to be able to recover the actual password.
Maybe the best approach would be to investigate "password safe" or "key chain" products that are provided by the client's OS or web browser. Unfortunately, this is going to be platform specific.
You could also just "hide" the file containing the password, or (reversibly) obscure the password. But this is insecure. It can easily be defeated by reverse engineering the steps that your code is taking to hide the password.
I've heard that MongoDB is very good Database, especially for placing large data inside, However i'm not sure how safe can it really be.
I'm not experienced at MongoDB, but before i choose, i want to know how safe it can be for important data.
So for example, if i specified uri, i would type this:
uri = "mongodb://test1:test1#ds051990.mongolab.com:51990/base1"
I'm trying to make a P2P text chat, It can be accessed on user's PC with root permissions, Whenever user registers, User's Latest IP, Username and will be added to database, as code was shown below.
But the "Hacker" would easily access it by simply getting into code, and viewing all the information, then he would read/write all the data inside.
What would be the best solution to prevent this issue? I think high-level Databases like MongoDB would have some-kind of protection against other users accessing it.
How can make sure only necessary users can access database and other users can't enter it by viewing uri variable?
If not is there ANY other way i can do it? So user can't access Database at all, But i would read and write files from database.
You have no easy way of hiding the credentials. Instead, create a user with the minimal required permissions in the database, and use these credentials in your distributed code.
If you are worried about the users being able to see plain-text IP addresses, you should hash and salt them before inserting them to the database.
I am creating a small system where the person can login with a username and a password. The code would then check the text file that contains the username and the password on the same line.
I have no idea how to make this work thought. How come it is so complicated to create a simple login system based off of a text file with the details in it? I believe that it is my philosophy that is wrong and not the actual code.
I have used various codes like the following:
with open('users/users.txt') as f:
{int(k): v for line in f for (k, v) in (line.strip().split(None, 1),)}
Which come to no use. What am I doing wrong?
I'm assuming you have a text file that's laid out like so:
username1 password1
username2 password2
...
From what I gathered from your question, you wish to parse this file and store the results in a dictionary (i.e. username key maps to password value). This sort of stuff is more appropriately stored in a database (SQLite is built-in to Python, for instance), so you should definitely look into learning about databases rather than using a plain text file for data storage, especially user accounts.
Also, you should think about how you should store sensitive information like passwords using techniques such as hashing, but that's something you can think about when you want to make the next step (I'm under the assumption this is a small learning project, so concepts like databases and hashing might be beyond your current scope, but they are absolutely worth learning).
As for your question, you could think about doing something like the following:
accounts = dict()
with open('users.txt') as f:
for account in f:
(usr, pwd) = account.strip().split()
accounts[usr] = pwd
print(accounts)
I think code clarity is more important than keeping it all in one line! The code that I have shown isn't exhaustive, more like a guideline. As I said before, I don't recommend you go this route, so definitely look into databases and proper password storing techniques!
What you could do in the mean time to ensure some form of security is to store the password as a hash (i.e. pwd would be a hash). Then when the user passes the password to the system you can calculate the hash and check if the hashes are equal. This would be better than dealing with plain text passwords. Python has a built-in module for hashing called hashlib. I'm not an expert on hashing, but this would be a decent starting point.
I am writing a desktop application in Python. This application requires the user to input their GMail email and password (however an account must be created specifically for this app, so it's not their personal (read: important) GMail account). I was wondering what would be the best way to store those login credentials. I don't need it to be super secure, but would like something more than storing it as plain text.
Thank you in advance.
Any chance you could not store the information on disk at all? I think that's always the most secure approach, if you can manage it. Can you check the credentials and then discard that information?
You can always encrypt the information if that doesn't work, but the decryption mechanism and key would probably have to reside in your program, then. Still, it might meet your criterion of not super-secure but better than plain text.
Use the OS keyring for this, which is the job of the python-keyring module.
Use the platform's native configuration storage mechanism (registry, GConf, plist).
If you are using Qt for your app, you should really use QSettings and let the framework handle the storage for you. Note: QSettings will NOT encrypt anything for you, but will store values in the most appropriate location depending on the platform it's running on.
Regarding security, you really should use OAuth, like in the example here, and just store the resulting token.
I'm working on an application that lets registered users create or upload content, and allows anonymous users to view that content and browse registered users' pages to find that content - this is very similar to how a site like Flickr, for example, allows people to browse its users' pages.
To do this, I need a way to identify the user in the anonymous HTTP GET request. A user should be able to type http://myapplication.com/browse/<userid>/<contentid> and get to the right page - should be unique, but mustn't be something like the user's email address, for privacy reasons.
Through Google App Engine, I can get the email address associated with the user, but like I said, I don't want to use that. I can have users of my application pick a unique user name when they register, but I would like to make that optional if at all possible, so that the registration process is as short as possible.
Another option is to generate some random cookie (a GUID?) during the registration process, and use that, I don't see an obvious way of guaranteeing uniqueness of such a cookie without a trip to the database.
Is there a way, given an App Engine user object, of getting a unique identifier for that object that can be used in this way?
I'm looking for a Python solution - I forgot that GAE also supports Java now. Still, I expect the techniques to be similar, regardless of the language.
Your timing is impeccable: Just yesterday, a new release of the SDK came out, with support for unique, permanent user IDs. They meet all the criteria you specified.
I think you should distinguish between two types of users:
1) users that have logged in via Google Accounts or that have already registered on your site with a non-google e-mail address
2) users that opened your site for the first time and are not logged in in any way
For the second case, I can see no other way than to generate some random string (e.g. via uuid.uuid4() or from this user's session cookie key), as an anonymous user does not carry any unique information with himself.
For users that are logged in, however, you already have a unique identifier -- their e-mail address. I agree with your privacy concerns -- you shouldn't use it as an identifier. Instead, how about generating a string that seems random, but is in fact generated from the e-mail address? Hashing functions are perfect for this purpose. Example:
>>> import hashlib
>>> email = 'user#host.com'
>>> salt = 'SomeLongStringThatWillBeAppendedToEachEmail'
>>> key = hashlib.sha1('%s$%s' % (email, salt)).hexdigest()
>>> print key
f6cd3459f9a39c97635c652884b3e328f05be0f7
As hashlib.sha1 is not a random function, but for given data returns always the same result, but it is proven to be practically irreversible, you can safely present the hashed key on the website without compromising user's e-mail address. Also, you can safely assume that no two hashes of distinct e-mails will be the same (they can be, but probability of it happening is very, very small). For more information on hashing functions, consult the Wikipedia entry.
Do you mean session cookies?
Try http://code.google.com/p/gaeutilities/
What DzinX said. The only way to create an opaque key that can be authenticated without a database roundtrip is using encryption or a cryptographic hash.
Give the user a random number and hash it or encrypt it with a private key. You still run the (tiny) risk of collisions, but you can avoid this by touching the database on key creation, changing the random number in case of a collision. Make sure the random number is cryptographic, and add a long server-side random number to prevent chosen plaintext attacks.
You'll end up with a token like the Google Docs key, basically a signature proving the user is authenticated, which can be verified without touching the database.
However, given the pricing of GAE and the speed of bigtable, you're probably better off using a session ID if you really can't use Google's own authentication.