I have written a PySide app which needs to send a user name and password to an online server.
I am encrypting the password after the user entered it via a QLineEdit widget, but since this is just python code, any user could open up the file and modify the code before the encryption to steal password.
Distributing pyc files is not much of a security boost as those can be decompiled AFAIK.
So my thought is to get somebody to write a custom QT widget in C++ with respective PySide bindings, which would be a modified QLineEdit that never stores the plain text, but only the encrypted text based on an external key. Is this a silly idea? Is it doable?
Are there any other options?
How would you guys handle this?
Cheers,
frank
Not really a "silly" idea. It's just that it wouldn't work.
All someone would have to do is to edit some other part of your code and install an event filter on the QApplication instance. With that in place, they could capture every keyboard event before it even reached your custom QLineEdit.
Attempting to fence off parts of your PySide application is never going to work. At the end of the day, it's a python program. Even trying to fence off the entire application by freezing it into an executable comes with a whole host of caveats (see "How do I protect Python code?" for some useful discussion).
You're never going to plug all the holes, no matter what you do (and no matter what language or libraries you use).
At some point you just have to take a breath, draw an artificial line somewhere, and leave it at that.
In the first instance, you should ensure you aren't echoing the password to the screen. However, ensuring the QLineEdit never stores the full password is probably not possible securely.
You could override the keystroke commands, and encrypt each incoming character. But per character encryption is not really done nowdays, at least in the form A=E or what have you.
You could do progressive hashes of the string as additional letters come in, but this means a user has 1 attempt to enter their password, as they can't backspace. Any mistake, such as a slipped finger, e.g entering g instead of f would mean needing to erase the whole password and start again - not a very friendly UI.
With regards to your worry of someone editing your code, and then capturing the password between the user entering it, and it being sent off, your being paranoid here. To a certain extent once you've sent of your code, you have little control over it. You could distribute the code with an appropriate MD5 hash for the relevant parts and you can check at run time to make sure the code hasn't been altered.
Even then, if someone has the ability to inject arbitrary code into your program then you have bigger problems. I'm not saying your program is insecure, but if someone malicious has access to a computer with the code, they could just as easily insert a hardware or software keylogger rendering all of your attempts moot.
Write your code as secure as possible, accept that at somepoint the password will be in plaintext somewhere and encode it at the first available opportunity. eg:
import mySecureLibrary
password = mySecureLibrary.saltAndHash(self.ui.passwordField.text())
self.ui.passwordField.setText("HAHA, no password for you")
Related
I'm creating a website where users can write about their day in a sort of diary. Right now, if a user decides to write something even remotely personal I can immediately see that just by querying the database for their entry content. I was wondering what the best way would be to encrypt this diary entry I get from the user so it would at least take some more effort from myself to see what people are writing. I am using Flask and SQLAlchemy.
if its a matter of human readability, you could just base64 encode it - therefore obfuscating it, instead of encrypting it. This is included in the python standard library, here's an example:
https://www.base64encoder.io/python/
If it needs to be encrypted, you could assign the user a private key and encrypt the data with its corresponding public key. This may be overkill, unless you do not want anyone else to be able to read it, even with a lot of effort put into it. Obviously you need to keep those private keys secret to anyone except the user, which would be complicated and you would not be able to assist the users if they lose their keys.
I am writing a program in python for a school project and one of its features is that it can send emails out.
However, in order to send an email from the program, you must login to the email account meaning my password for that account is contained within a variable in the program.
Because this is for a school project, I will have to send this to people I am working with and they'll be able to read the code but I don't really want my password being openly left in a variable for them to see.
Is there any way to hide it or encrypt it so that other people can't see it?
Unfortunately, the answer is no.
This is a big security issue and a very common way for people to have programs "hacked" (they post some code on a public repository with an API key or password in it, and people can take that and do what they want with it).
Here are the most common solutions to this problem:
Use a server. This probably isn't very viable for you since it's for a school project, but in larger project, we'd typically send a request to our server (which knows the password), and it would send it form there. Code on a server (if protected correctly) is considered moderately safe. Even still, it would be very bad design to put the password in the code. Since the end user won't see the server's code, they won't be able to get that password. Note that this is an oversimplification and there's more to securing a server than just what I've mentioned.
Use environment variables. Environment variables can be set in your terminal and store the information on your own computer, not in the program. However, for it to work, each user would need to set their environment variables in their own terminal, and if you're trying to share an account, this is not the way to go because then you'd have to give them the password anyways. This is a good article that discusses environment variables and how to set them. In python, you can get the variable using the os module (os.environ["ENV_VARIABLE_NAME"]).
A general rule of thumb is never ever put anything in your source code (for the client side) that you wouldn't want the whole world seeing. It is possible to get this information out of the code and can cause big issues down the road.
Let me know if you have any other questions!
I have something in my clipboard, and I'd like to run a python script that invokes CTRL+V as if it was pressed on the keyboard, and pastes the clipboard's content to the current focused window (say chrome). Any idea how to do that?
You have an X-Y problem.
What you want to accomplish is programmatically take data from one program (where you hit cntrl-V) and place it into another arbitrary program (chrome).
There are two ways to do that:
First
You can either set the programs up to have a data exchange mechanism such as a system pipe, or a network connection. This requires some API for data exchange to be already included in the program or access to the source so you might add one. There are very specific channels for cross program data exchange and you wont do well to try to circumvent them. Program A cant just say
get_program_b().get_text_box().add(clip_board);
That would be a violation of Process Isolaton and an OS like windows is written expressly to make it impossible. Some programs are designed to take input from other programs.
popen.open('mysql -e "ISNERT INTO table (a) VALUES ('4')")
Chrome is not one of those programs, chrome avoids allowing programs from doing this because it would be a target for programs to do things like, get the saved password or credit card data out of chrome. Or use save password to login to someone account and buy things in someone elses name.
Second
You could try to spoof user input and input the data exactly like a user would so chrome wont know the difference. But spoofing a user is hard to do and intentionally so because it prevents malicious scripts from taking control of a computer and doing bad things. The makers of windows are accutely aware that spoofing input is a method to circumvent allowed data exchange channels. So the makers of windows made it hard to do. You need to have access to a lot of system assets that most programs wont be given. At a minimum a program has to run as admin on windows to accomplish this, then there are libs that will let you do it. Even then Im willing to bet there are easier way to get the job done. On a machine where you have access to anything and everything it is possible. If you don't have admin access, it should be downright impossible without knowing some unpatched exploit in the system.
Therefore
What you are trying to do goes against what the computer was designed to let you do. If we had more information on what you want to accomplish maybe some of the wonderful people here could help. Getting to the end result you want shouldnt be that hard. But you way of doing it is like trying to run across the ocean, when you just need a boat. As it is my answer is -- dont do it, that's not how windows was designed to work.
This is a project that I wanted to work on. I want a program that people can enter their login details and their username and password information will be sent to another program that will check to see if the login details are right and then will tell the other program whether they can login or not.
The problem is I have no idea how I will make the programs send data to each other. If anyone could help me, maybe introduce me to some new modules that could help me, I would be very happy.
Thanks,
Dan
The program that you want to send the data to confirm if it'll work has to be able to allow such method of confirmation, else, it wouldn't work. If it does, it may be that you would have to supply such to the program from the command line.
You could try out https://pypi.python.org/pypi/EasyProcess
If you're talking about a sort of client-server setup here, you could look into using sockets in order to facilitate the communications between the client and server software. However, I would advise that you keep in mind that sending information such as passwords over the net will probably require that they be secured as well.
I'm sorry if I'm a little unhelpful with your project, but the vague nature of your description was such that I can only really point you towards the modules you may want to look into for accomplishing the key aspect of your task.
What I want to do is protect a Python program from being stolen by people with no computer knowledge. I accept the inevitability of the program being pirated, all I want to do is protect it from average users.
I have come up with two ideas.
1.)Set a time restriction by checking online for the date and time. I.E. 10 days from downloaded time.
2.)Checking the IP or Name of the computer that downloaded it and make the program only runs on that computer. (to prevent friends from simply sharing the file).
The problem with both of these is that I'll need to create a .py file "on the fly" and then use something like pytoexe to make it into an .exe so that the user doesn't need to have Python installed.
The problem with the second is that to my understanding ip's change and getting the computer name is a security risk and might scare away users.
So to sum it up, here are my two questions:
1.) Is there a good way in python to only allow the program to run on that single computer?
2.) What is the best way to implement a "on the fly" creation of the exe? (I was going to host the website on my computer and learn php(?)/servers.
I have moderate c/c++ and basic html/css, java, and python experience.
Thank you for your time!
Messy business. You probably already understand that compiled does not mean encrypted.
However, if you're boss considers c-compiled as satisfactory, you can use cython to compile your python code to c-code and then gcc to compile the c-code.
Check here on how to build your setup.py script.
http://docs.cython.org/src/reference/compilation.html#compiling-with-distutils
And you can embed python using into the resulting c code using the --embed option:
# will generate the target.c
$ cython target.py --embed
Give each user a customized installer that has a unique key in it. When it runs, it contacts a server (with the key) and requests the actual program. Server-side, you check if the key is valid and if so, serve the program customized with the key, and mark the key as used. The installer saves the program somewhere the user can access it, and creates a hidden file that contains the key somewhere deep in the bowels of the computer, where the "average user" won't think of looking. When the program is run, the first thing it does is check if the hidden file exists and if it contains the correct key, and refuses to run if not.
(I am assuming that unzipping an executable and reading source code is beyond the ability of the "average user" (read: "grandma"), so using py2exe is ok.)
To avoid having to contact anything on the Internet, you could use the following way to 'dongle' your program:
Take a vital part of your program (something without which the rest won't be useful),
put it into a string,
encrypt that string symmetrically with the MAC address of the computer it shall run on,
then in your program do this:
decrypt that string with the MAC address of the current machine it runs on an and
call that decrypted string using exec.
Example with the vital part being print "hello world":
def getMyMac():
return 123456789L # for testing now
return uuid.getnode() # this would be the real thing
def strxor(s, key):
key *= len(s) / len(key) + 1
return ''.join(chr(ord(key[i]) ^ ord(s[i])) for i in range(len(s)))
def performVitalCode():
code = 'A#ZZA\x16\x15P\\]^\\\x14BYET]\x13'
# I found that code by entering:
# strxor('print "hello world"', str(getMyMac()))
realCode = strxor(code, str(getMyMac()))
exec realCode
I here used a simple xor on strings for crypting (which is not a hard cypher to crack).
Of course the user of the "allowed" computer can hand over his MAC address to the next user which then
either can patch the getMyMac() or
spoof his own MAC address; most network cards allow this.
So this is not a "safe" solution to your problem.
But if a person with just little computer knowledge gave your code to some other guy without any further information (maybe by putting it online in a forum or similar), the receiver won't be able to execute it out of the box.
Finally I need to point out that every chaining of code to a specific computer may well become a hassle for the rightful user of the code. If I'm using a program which stops working just because I switch to a different hardware (maybe just because I get a new laptop), I'm usually pissed and curse the writer of that code. You might not want to annoy your customers.
Seems like a combination of things here. Encapsulating python as others have suggested is a good way to go, for bundling. You may also consider obfuscation, as talked about here in another StackOverflow thread:
Python Code Obfuscation
Which references:
http://freecode.com/projects/pyobfuscate
As for making it so that someone can't just download your program and run it elsewhere or distribute it, how willing are you to inconvenience your end users? :)
As others have noted above, you can generate a compiled and bundled bit of code with the ID specific to the user. That way, if/when the application phones home, you can track usage.
If your end users/customers have the following requirements fulfilled:
An account with you, which they can login and check their subscription/account status
Internet connectivity from the machine running the program
You can make the installation process do the following:
Installer is NOT the full program. Generates a profile of the machine.
This profile bundled up and a hash is generated. Both are uploaded to your servers.
The hash is displayed to the end user to enter, once they have signed into their online web account.
The user installing the application submits the hash, and gets a download link and an unlock key. The key is only good for that dynamically generated download and only on that machine. The downloaded program, however, will accept a range of keys unique to itself(iteratively generated, etc).
The user can then complete the install and run their program. The program will periodically check the profile of the machine it is on, to make sure that the hash does not deviate. If it does, the program can prompt them to login to their web account to generate a new key. The new key is then used to refresh their application. This can be automated by the application, but with the internet laws and such, having the user sign into their account and perhaps agree to any updates to the EULA, would be better.
If they decide to share the program in a VM bundle, they would still need an active account to get keys.
Note, this does not prevent someone from bypassing the hash check. But for the average user, this will serve as a good way for you to deter people giving away or reselling your program.
Just bear in mind, no system is foolproof.