On Python, I was wondering if there was a simple way to create a text file which can't be edited by the user and can only be edited once, by the computer.
I want to use this so that I can make a User ID for a user that cannot be changed. Does anyone have a solution?
If there is any security reason why the UserID shouldn't be changed then you need to store the information on your own server.
If you don't want it to be easy, but don't mind it being possible, then you could either change the file permission on the file, encrypt the file in some way so that it's not easy to edit by the user, or hide it by prefixing the name with a . so that it doesn't automatically appear in the explorer window.
Related
I have saved the game data to an ini file, how can I protect it from being edited by the user?
Strictly speaking, it's not possible. You can't do anything to a local file that user is unable to undo.
However, you can obfuscate or encrypt (however simply) that file, so that at least a casual person with a Notepad is likely to give up. The simplest thing to do is to save data as a pickle file, so that it's easy to manipulate in Python, but looks baffling to a non-techy user/player.
Make somehow a hash / control sum of your ini-file and store at separate file. It will not prevent the ini-file from modification but you'll be able to know if modification occured and react on such user's behaviour.
I want to change a file to be permanently read-only and tried the solutions provided creating-read-only-pdf-file-using-python and change-file-to-read-only-mode-in-python.
However, in both cases it was still possible to edit the file and manually change it back to a read-only file.
Is there a way to prevent that, so that nobody could edit the properties or content of the file?
I thought about encrypting it, i.e. using SHA256 with a randomly created key, but that would render the file unreadable.
Is there a way to prevent that, so that nobody could edit the properties or content of the file?
No. As long as the file is on a writable device, it's always possible for a user to delete the file and replace it with a modified copy.
(And even if the file is on an immutable device, like a CD-ROM, the user can still create a modified copy of the entire device.)
If you are one a Unix-like system you can use the chmod command in the terminal.
The chmod command has an equivalent in python
You might have to run your script is super-user to change some permissions.
I'm making a "wargame" like the ones on overthewire.org or smashthestack.org. When you finish the game, the user should get a python program that has extra permissions to edit a file in /var/www/html so that they can sign their name. I want to have a program like this so that they can add text to the html file without removing the text of other users and so that it filters offensive words.
How can I make a file editable by a specific program in Linux? And how can I make the program edit the file in python? Do I just use os.system?
I'm going to answer your question but also beg you to consider another approach.
The functionality you are looking for is usually handled by a database. If you don't want to use anything more complex, SQLite is often all you need. You would then need a simple web application that connects to the database, grabs the fields, and then injects them into HTML.
I'd use Flask for this as it comes with Jinja and that's a pretty simple stack to get started with.
If you really want to edit the HTML file directly in Python, you will need write permissions for whatever user is running the Python script. On Ubuntu, that folder is typically owned by www-data if you are running Apache.
Then you'd open the file in Python, perform file operations on it, and then close it.
with open("/var/www/html/somefile.txt", "a") as myfile:
myfile.write("l33t h4x0r has completed the challenge!\n")
That's an example of how you'd do a simple append operation in Python.
So I made a python phonebook program which allows the user to add contacts, change contact info, delete contacts, etc. and write this data to a text file which I can read from every time the program is opened again and get existing contact data. However, in my program, I write to the text file in a very specific manner so I know what the format is and I can set it up to be read very easily. Since it is all formatted in a very specific manner, I want to prevent the user from opening the file and accidentally messing the data up with even just a simple space. How can I do this?
I want to prevent the user from opening the file and accidentally messing the data up...
I will advise you not to prevent users from accessing their own files. Messing with file permissions might result in some rogue files that the user won't be able to get rid of. Trust your user. If they delete or edit a sensitive file, it is their fault. Think of it this way - you have plenty of software installed on your own computer, but how often do you open them in an editor and make some damaging changes? Even if you do edit these files, does the application developer prevent you from doing so?
If you do intent to allow users to change/modify that file give them a good documentation on how to do it. This is the most apt thing to do. Also, make a backup file during run-time (see tempfile below) as an added layer of safety. Backups are almost always a good idea.
However, you can take some precautions to hide that data, so that users can't accidentally open them in an editor by double-clicking on it. There are plenty of options to do this including
Creating a binary file in a custom format
Zipping the text file using zipfile module.
Using tempfile module to create a temporary file, and zipping it using the previous option. (easy to discard if no changes needs to be saved)
Encryption
Everything from here on is not about preventing access, but about hiding the contents of your file
Note that all the above options doesn't have to be mutually exclusive. The advantages of using a zip file is that it will save some space, and it is not easy to read and edit in a text editor (binary data). It can be easily manipulated in your Python Script:
with ZipFile('spam.zip') as myzip:
with myzip.open('eggs.txt') as myfile:
print(myfile.read())
It is as simple as that! A temp file on the other hand, is a volatile (delete=True/False) file and can be discarded once you are done with it. You can easily copy its contents to another file or zip it before you close it as mentioned above.
with open tempfile.NamedTemporaryFile() as temp:
temp.write(b"Binary Data")
Again, another easy process. However, you must zip or encrypt it to achieve the final result. Now, moving on to encryption. The easiest way is an XOR cipher. Since we are simply trying to prevent 'readability' and not concerned about security, you can do the following:
recommended solution (XOR cipher):
from itertools import cycle
def xorcize(data, key):
"""Return a string of xor mutated data."""
return "".join(chr(ord(a)^ord(b)) for a, b in zip(data, cycle(key)))
data = "Something came in the mail today"
key = "Deez Nuts"
encdata = xorcize(data, key)
decdata = xorcize(encdata, key)
print(data, encdata, decdata, sep="\n")
Notice how small that function is? It is quite convenient to include it in any of your scripts. All your data can be encrypted before writing them to a file, and save it using a file extension such as ".dat" or ".contacts" or any custom name you choose. Make sure it is not opened in an editor by default (such as ".txt", ".nfo").
It is difficult to prevent user access to your data storage completely. However, you can either make it more difficult for the user to access your data or actually make it easier not to break it. In the second case, your intention would be to make it clear to the user what the rules are hope that not destroying the data is in the user's own best interest. Some examples:
Using a well established, human-readable serialization format, e.g. JSON. This is often the best solution as it actually allows an experienced user to easily inspect the data, or even modify it. Inexperienced users are unlikely to mess with the data anyways, and an experienced user knowing the format will follow the rules. At the same time, your parser will detect inconsistencies in the file structure.
Using a non-human readable, binary format, such as Pickle. Those files are likely to be left alone by the user as it is pretty clear that they are not meant to be modified outside the program.
Using a database, such as MySQL. Databases provide special protocols for data access which can be used to ensure data consistency and also make it easier to prevent unwanted access.
Assuming that you file format has a comment character, or can be modified to have one, add these lines to the top of your text file:
# Do not edit this file. This file was automatically generated.
# Any change, no matter how slight, may corrupt this file beyond repair.
The contact file belongs to your user, not to you. The best you can do is to inform the user. The best you can hope for is that the user will make intelligent use of your product.
I think the best thing to do in your case is just to choose a new file extension for your format.
It obviously doesn't prevent editing, but it clearly states for user that it has some specific format and probably shouldn't be edited manually. And GUI won't open it by default probably (it will ask what to edit it with).
And that would be enough for any case I can imagine if what you're worrying about is user messing up their own data. I don't think you can win with user who actively tries to mess up their data. Also I doubt any program does anything more. The usual "contract" is that user's data is, well, user's so it can be destroyed by the user.
If you actually won't to prevent editing you could change permissions to forbid editing with os.chmod for example. User would still be able to lift them manually and there will be some time window when you are actually writing, so it will be neither clean nor significantly more effective. And I would expect more trouble than benefit from such a solution.
If you want to actually make it impossible for a user to read/edit a file you can run your process from a different user (or use some heavier like SELinux or other MAC mechanism) and so you could make it really impossible to damage the data (with user's permissions). But it is not worth the effort if it is only about protecting the user from the not-so-catastophic effects of being careless.
Is it possible to create read only files in python which can not be changed later and in which users can not change its attribute from read-only to normal file?
Please suggest.
Thanks in advance.
This is not python specific.
If the files are made by a different user that the one viewing it the script can make it read-only. As the file is owned by the python user, the viewing user cannot just change the attributes.
So it's very much an OS question, and not a Python question.
Oh, and there is no way to prevent an administrator changing the file, or for the file to be readable but not copyable.
This is just impossible.
Any user with administrative rights can remove readonly restrictions of any kind.
Another option might be "Write a python program to kill all users over the worls so that they would not be able to change file attributes or security settings" :-)
Take a look at os.chmod() function and execute it with appropriate parameters (filename, stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) for your just created file.
On linux other users then you will not be able to change file or change attributes to writable.
Some root user or someone logged into you account will be able to change it though.