Re: How to protect Python source from modification
Dennis Lee Bieber wrote: On 13 Sep 2005 01:00:37 -0700, Frank Millman [EMAIL PROTECTED] declaimed the following in comp.lang.python: 2. I am a great believer in 'field-by-field' validation when doing data entry, instead of filling in the entire form, submitting it, and then being informed of all the errors. I can inform a user straight away if they try to do something they are not entitled to. Ensuring a field is numeric (with range checking) or string is one thing... But if a certain user is not even supposed to see a field, or only have read-only access, those could be determined at the server side when generating the form (okay, that was phrased more as a web-page scheme, but...) Better that low-privilege users never even learn of the additional data fields rather than be tempted by the forbidden fruit G Food for thought - thanks 3. I can cater for the situation where a user may not have permission to do something, but they can call a supervisor who can override this. I have seen solutions which involve prompting for a password, but this has to be programmed in at every place where it might be required. I allow the supervisor to enter their userid and password, and my program reads in their permissions, which become the active ones until cancelled. I create a flashing red border around the window to warn them not to forget. I suspect such an override could still be done through the server side. Not sure of the programmed in at every place concern -- it sounds like just an exception handler with retry (and if it were done via web forms, it would be the server detecting no privilege and returning the override log-in form). I'd be more concerned that the override doesn't go away after the transaction is completed... To me, if a lowly user needs to have a supervisor unlock operations -- and the supervisor then walks away while the higher privileges are active, it is a sign of either poor security practices, or a need to grant that user more privileges. Imagine a store where supervisor approval is needed for any check over a certain amount... You don't want the supervisor to key in their approval code on a register and walk away leaving that code active (and letting the clerk then enter dozens of high value checks without calling for a supervisor). The code should only be active for the completion of the check approval and then automatically reset to the regular clerk's mode of operation. H'mm, more food for thought. The advantage of my approach is that no additional programming is required. I have a very flexible security model, which is entirely user-definable. If any user finds that they are blocked from doing something, they can call anyone who does have that permission, without exiting from their position in the app. The other person can key in their userid and password, perform the required action, and the original user can carry on. You are right that the danger is that the second person forgets to cancel their code. That is why I create a flashing red border. This is how it works from a user perspective. There is a hot-key, Ctrl-U, which can be pressed at any prompt (wxPython makes this easy). If pressed, I pop up a box asking for userid and password. If accepted, I save the original user's permissions, read in the new user's permissions, and create the flashing border. To cancel the setting, the user simply presses Ctrl-U again, and everything is reset. I think this works quite well, so I will run with it for now and see if it causes any problems in practice. Many thanks for the valuable comments. Frank -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Magnus Lycka wrote: [snip lots of interesting stuff] There is the question of where state should be maintained. If on the server, I would have to keep all the client/server connections open, and maintain the state of all the sessions, which would put quite a load on the server. Really? How many users do you imagine? How would you plan to organize your servers? One process per connection, one thread per connection or asynchronous processing in one thread as in Twisted or asyncore? Perhaps you should have a look at Twisted ot asyncore? I was thinking of one thread per connection. How many users? I would be ecstatic if I got a 20-user system working. However, I know from experience that these things can mushroom, especially if there are no licence fees involved, so it can easily be more. Actually I should just get it working, and then monitor performance as the number of users increases. I am sure there will be many things I can do if it starts to slow down. This raises the question of whether I should even bother with a gui client, or bite the bullet and only have a browser based front end. Judging from recent comments about new technologies such as Ajax, a lot of the disadvantages have been overcome, so maybe this is the way to go. It's still a big difference, isn't it? Have you seen a web based accounting system that you thought was good enough? Actually no g It would be a shame to scrap all the effort I have put into my wxPython-based front end. On the other hand, it would be pointless to continue with an approach that is never going to give me what I want. Any advice which helps to clarify my thinking will be much appreciated. A wxPython client and a Twisted server might well be a useful combo. If you have well written Python modules for validating data etc, you might just run them in both client and server to achieve instant feedback on the client without lowering the security bar. I have seen Twisted mentioned many times in this ng, but I have no idea what it actually does. Can someone tell me in simple terms what advantage it might give me over a multi-threaded socket server program. I have (just now) reread the intro to the asyncore module, and it says this strategy can seem strange and complex, especially at first. This describes my present situation exactly :-) Many thanks for the valuable comments. Frank -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Frank Millman wrote: I have seen Twisted mentioned many times in this ng, but I have no idea what it actually does. Can someone tell me in simple terms what advantage it might give me over a multi-threaded socket server program. More control. Less resource usage. Twisted also provides a very flexible way of building network aware software which you will appreciate if you ever consider using something else than sockets. Using several process means using more memory, and inter process communication isn't as fast as in-process communication. Using threads is error prone and difficult to debug. There are also scaling issues with threads in Python (but maybe not when most threads wait for network connections). Twisted is based on an event loop, just like GUI programs. But instead of waiting for GUI events, such as button clicks, the Twisted app will wait for network events, such as data received. With Twisted and sockets, you write code that will implement handlers for such events. A simple example is provided here: #!/usr/bin/python # Copyright (c) 2001-2004 Twisted Matrix Laboratories. # See LICENSE for details. from twisted.internet.protocol import Protocol, Factory from twisted.internet import reactor ### Protocol Implementation # This is just about the simplest possible protocol class Echo(Protocol): def dataReceived(self, data): As soon as any data is received, write it back. self.transport.write(data) def main(): f = Factory() f.protocol = Echo reactor.listenTCP(8000, f) reactor.run() if __name__ == '__main__': main() You see? You just subclass Protocol and override the relevant event handler, and get the thing going! The factory will create an Echo instance for each socket connection. The problem in Twisted is that functions in this single thread that are run inside the event loop must be fast--just as the event handlers in your GUI app. Twisted helps you achieve this. For instance, there is the concept of deferred execution, (described in a paper available at http://python.fyxm.net/pycon/papers/deferex/ ) but you might want to use a separate thread for things like database queries etc. There are a lot of other batteries included, check out the Twisted documentation at http://twistedmatrix.com/projects/twisted/documentation/ You have to ask other Twisted users about scalability, but I think it will scale well beyond your needs. -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Magnus Lycka wrote: Frank Millman wrote: I have seen Twisted mentioned many times in this ng, but I have no idea what it actually does. Can someone tell me in simple terms what advantage it might give me over a multi-threaded socket server program. More control. Less resource usage. Twisted also provides a very flexible way of building network aware software which you will appreciate if you ever consider using something else than sockets. [snip Twisted tutorial] Thanks a ton, Magnus, that really was a brilliant description. Clearly I must find the time to look into Twisted properly. Many thanks again Frank -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Frank Millman wrote: Steven D'Aprano wrote: On Mon, 12 Sep 2005 08:33:10 -0700, Frank Millman wrote: My problem is that, if someone has access to the network and to a Python interpreter, they can get hold of a copy of my program and use it to knock up their own client program that makes a connection to the database. They can then execute any arbitrary SQL command. Why is that your problem, instead of the company's problem? It is their database server, yes? If they want to connect to it and execute arbitrary SQL commands on their own database, (1) who are you to tell them they can't? and (2) they hardly need your program to do it. -- Steven If they choose to give the userid and password to an individual, they are obviously giving him permission to execute any command. On the other hand, they can reasonably expect to set up users without giving them direct access to the database, in which case I think they would be upset if the users found this restriction easy to bypass. Certainly, but that access control *shouldn't happen in the client* whether the source is visible or not. -- Robert Kern [EMAIL PROTECTED] In the fields of hell where the grass grows high Are the graves of dreams allowed to die. -- Richard Harter -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Steve M wrote: [...] 1. Based on your description, don't trust the client. Therefore, security, whatever that amounts to, basically has to happen on the server. That's the right answer. Trying to enforce security within your software running the client machine does not work. Forget the advice about shipping .py's or packaging the client in some way. The server should be designed with the expectation that any input is possible, from slightly tweaked variants of the normal messages to a robotic client that spews the most horrible ill-formed junk frequently and in large volumes. It is the server's job to decide what it should do. For example, consider a website that has a form for users to fill out. The form has javascript, which executes on the client, that helps to validate the data by refusing to submit the form unless the user has filled in required fields, etc. This is client-side validation (analagous to authentication). It is trivial for an attacker to force the form to submit without filling in required fields. Now if the server didn't bother to do its own validation but just inserted a new record into the database with whatever came in from the form submission, on the assumption that the client-side validation was sufficient, this would constitute a serious flaw. (If you wonder then why bother putting in client-side validation at all - two reasons are that it enhances the user experience and that it reduces the average load on the server.) Good advice. -- --Bryan -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Dennis Lee Bieber wrote: On 12 Sep 2005 08:33:10 -0700, Frank Millman [EMAIL PROTECTED] declaimed the following in comp.lang.python: My problem is that, if someone has access to the network and to a Python interpreter, they can get hold of a copy of my program and use it to knock up their own client program that makes a connection to the database. They can then execute any arbitrary SQL command. If your DBMS is directly accessible on the net, you're vulnerable even without Python. Especially if you have authentication logic being done at the client end. There is nothing to prevent someone using a compatible query browser or command-line utility to make connection attempts to the server, followed by classical username/password cracking stuff. Right - this is the conclusion I have come to. The server program is currently programmed to accept a number of message types from the client program. Each message's data string starts with a numeric prefix, which indicates the type of message, followed by a pickled tuple of arguments. The server program reads the string, extracts the numeric prefix, and passes the rest of the string to the appropriate function using a subthread. Ah, okay -- you /do/ already have something running in the middle. It is more on the side than in the middle at present - the client connects to my server program, but also connects directly to the database. My proposed change is to put it really in the middle - the client connects to my server, and my server connects to the database. For example, I keep track of who is currently logged in. On startup, the client connects to my server and sends a '1' followed by their userid and other information. The server receives this and passed the data to a 'login' function, which uses a Python dictionary to store the information. If the server detects that the user is already logged in, it sends back an error code and the client program displays a message and terminates. Otherwise it sends back an 'ok' code, and the client can continue. When the client logs off, it sends a '2' followed by their userid, which the server receives and passes it to a 'logoff' function, which deletes the entry from the dictionary. Obscuring the Python stuff will only be a minor delay factor in breaking that -- someone really serious could probably stick in a packet sniffer and record a transaction sequence, eventually reverse mapping back to the types of operations each code represents. Would using SSL be a solution? This is on my to do list. Database security? First step would be to USE the DBMS privilege system to limit operations to only those SQL statements, tables, and data columns that are needed for your client program; since you appear to be using user/password information already, each such user could have different privileges, limiting some to retrieval only, for example. As for your server, I'd probably start a thread for each connected user, so that thread handles all communication. Your description sounds more like a rudimentary proxy adding in a counting scheme, but not really isolating separate client connections. -- A number of replies have indicated that I should be using the DBMS itself to manage security. I think there are some benefits to managing it via the application. Admittedly I did not think it through when I started, but now that I have a reasonable security model working, I would not want to give it up. Here are some examples of what I can do. 1. Users and groups can be maintained by anyone using my app (with the correct permissions, of course). You do not have to go through the database adminstrator with all the complication or red tape that could arise. 2. I am a great believer in 'field-by-field' validation when doing data entry, instead of filling in the entire form, submitting it, and then being informed of all the errors. I can inform a user straight away if they try to do something they are not entitled to. 3. I can cater for the situation where a user may not have permission to do something, but they can call a supervisor who can override this. I have seen solutions which involve prompting for a password, but this has to be programmed in at every place where it might be required. I allow the supervisor to enter their userid and password, and my program reads in their permissions, which become the active ones until cancelled. I create a flashing red border around the window to warn them not to forget. There is some support for this approach given by MS SQL Server, which has the concept of an Application Role. 'Application roles contain no users, though you can still assign permissions to application roles. They are designed to let an application take over the job of authenticating users from SQL Server.' Thanks for the interesting comments. Frank -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Bugs wrote: As a side question Frank, how was your experiences using wxPython for your GUI? Any regrets choosing wxPyton over another toolkit? Was it very buggy? How was it to work with in general? Any other real-world wxPython feedback you have is appreciated. Frank Millman wrote: I am writing a multi-user accounting/business system. Data is stored in a database (PostgreSQL on Linux, SQL Server on Windows). I have written a Python program to run on the client, which uses wxPython as a gui, and connects to the database via TCP/IP. snip Difficult to give a balanced answer, but I will try. wxPython more or less chose itelf. I need the gui to work on Windows and Linux. Alternatives were Tkinter and PyQt. I got the impression from reading other comments that Tkinter is a bit old-fashioned and does not have a native look and feel, and PyQt is not free on Windows. That left wxPython. I did not evaluate the others, so I cannot compare directly, but do I have any regrets - no. Some things that I thought would be difficult I found amazingly easy. Other things that should have been simple gave me endless trouble. Understanding the concept of 'sizers' (for laying out the widgets on the screen) took me a while to grasp, and it is still not 100% clear, but I can get it to do most of what I want. The cross-platform capability is very good, but there were times when I got something to work on one platform and not the other. After much experimenting I usually managed to get it to work on both, often with a surprising side-effect - the code I eventually used was often cleaner and felt more correct than my original attempt, and therefore if I had been more experienced and done it the 'right' way in the first place, I may not have had a problem. Documentation is not perfect, though it is being worked on. The primary source is the documentation for wxWidgets, which is written in C++. Some people have commented that they do not understand the format, as the C++ function calls are not quite the same as Python's, but personally I did not find this a problem. A bigger problem is that the documentation does not keep up to date with the product, so there are often new features available that are not apparent. I have got into the habit of doing a dir() on most of the objects, to see if they have any methods that are not listed in the docs - quite often they do. Work has started on proper wxPython documentation, and apparently it looks quite good, but I have not used it. There is also a book in the pipeline. Support from the wxPython community is exceptional. There is a very willing and helpful mailing list, and a wiki with a lot of useful stuff. The main developer of wxPython, Robin Dunn, is a regular contributor to the mailing list, and is the authoritative source of up to date information. Unfortunately he has been tied up with personal business for a few months, and his absence from the list is quite noticeable. I am sure I speak for the entire list when I say I am really hoping that he returns soon - it makes us realise how dependent we are on him. Overall, I have found the experience frustrating from time to time, but I am happy with what I have achieved. I have shown samples of my app to a few people, and the appearance has never even raised a question - it just looks and feels like a modern gui application, and I can get on with demonstrating the functionality, which is as it should be. My 2.5c Frank -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Steve M wrote: This is a heck of a can of worms. I've been thinking about these sorts of things for awhile now. I can't write out a broad, well-structured advice at the moment, but here are some things that come to mind. [snip lots of interesting stuff] Thanks for the reply, Steve. My thinking has followed a similar path to yours, so it is good to have some validation. I have decided that my next step will be to set up a server program as discussed, and move all my authentication and business logic there, then get a client program working using the same gui as at present, but communicating with the server for most of the database stuff instead of doing it by itself. I am aware of Dabo, but I have not looked at it yet. I got my own framework working before Dabo came along, and it works well enough for my purposes, so I don't really want to go back and reinvent that wheel at the moment. Frank -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Thanks Frank, I appreciate the feedback. -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Frank Millman wrote: Hi all I am writing a multi-user accounting/business system. Good! The client program contains all the authentication and business logic. Not good. You lose...if it's *only* in the client. Of course, there is no such thing as a safe system, and you need a pragmatic approach to deciding a level of security. For a system like this, I'd certainly prefer to design the system so that it's immune to modifications in any software running on a machine that isn't safe, such as a typical end user PC. IOW, no direct DB access allowed (at least not with anything but select permissions) and all authentication and security related verifications etc in a server process which isn't available to ordinary users. However, such schemes aren't immune to flaws. First of all, there might be mistakes in the implementations (how ever cleverly they are made) and there are always people who have access to servers and databases. You need audits and checks on various levels to handle such things. You can probably get transaction logs for the database system to be stored on some other server, which might make it more difficult for someone who manipulates the system to hide their tracks. All external transactions (especially payments from the system) need to be audited and scanned for irregularities. Can all payments be traced back to valid business transactions? Are there patterns in payments that stick out, such as many small transactions to the same receiver? Security checks like these should probably be made completely outside your accounting/business software, and by people who have nothing to do with your main system. Regardless of your intentions, there is no way you can stop people from hurting themselves. The customer of the system will basically set a ceiling for the security of the system, depending on how ambitious they are, and what kind of infrastructure they can provide etc. Small customers might well demand perfect security, but they probably don't want to pay for it. It has dawned on me that anyone can bypass this by modifying the program. As it is written in Python, with source available, this would be quite easy. My target market extends well up into the mid-range, but I do not think that any CFO would contemplate using a program that is so open to manipulation. Just distribute zipped library instead of .py files, and you've raised the bar to the same level as if you've written it in Java. I.e. it's as if you send your mail in envelopes (just not glued together) instead of in postcards. No one will accidentally see the source code, but the persistent user can. There is the question of where state should be maintained. If on the server, I would have to keep all the client/server connections open, and maintain the state of all the sessions, which would put quite a load on the server. Really? How many users do you imagine? How would you plan to organize your servers? One process per connection, one thread per connection or asynchronous processing in one thread as in Twisted or asyncore? Perhaps you should have a look at Twisted ot asyncore? This raises the question of whether I should even bother with a gui client, or bite the bullet and only have a browser based front end. Judging from recent comments about new technologies such as Ajax, a lot of the disadvantages have been overcome, so maybe this is the way to go. It's still a big difference, isn't it? Have you seen a web based accounting system that you thought was good enough? It would be a shame to scrap all the effort I have put into my wxPython-based front end. On the other hand, it would be pointless to continue with an approach that is never going to give me what I want. Any advice which helps to clarify my thinking will be much appreciated. A wxPython client and a Twisted server might well be a useful combo. If you have well written Python modules for validating data etc, you might just run them in both client and server to achieve instant feedback on the client without lowering the security bar. A budget solution if you want to keep a simple fat client / thin server solution is to run the clients on a box that the end users can't manipulate. Just let them access that box via VNC and only run this client program there. It's not completely trivial to set up such a safe environment though, but it basically gives you an application server and very thin clients that still give you the same rich UI as wxPython on their desktops. They'll have to get used to a non-Windows GUI though, unless you choose to run Citrix instead of VNC (or use one application server per user :). -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
bruno modulix wrote: Frank Millman wrote: I am writing a multi-user accounting/business system. Data is stored in a database (PostgreSQL on Linux, SQL Server on Windows). I have written a Python program to run on the client, which uses wxPython as a gui, and connects to the database via TCP/IP. The client program contains all the authentication and business logic. It has dawned on me that anyone can bypass this by modifying the program. If your program relies on a RDBMS, then it's the RDBMS job to enforce security rules. Don't know enough about Millman's app to comment on it specifically, but many reasonable server-side applications use a single log-in to the database, then enforce security in the application server. Web shopping-carts, for example, generally work that way. -- --Bryan -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Frank Millman wrote: Hi all I am writing a multi-user accounting/business system. Data is stored in a database (PostgreSQL on Linux, SQL Server on Windows). I have written a Python program to run on the client, which uses wxPython as a gui, and connects to the database via TCP/IP. The client program contains all the authentication and business logic. It has dawned on me that anyone can bypass this by modifying the program. As it is written in Python, with source available, this would be quite easy. My target market extends well up into the mid-range, but I do not think that any CFO would contemplate using a program that is so open to manipulation. [...] My suggestion is to use py2exe or cx_Freeze to package your application. It's then not as trivial to modify it. Btw. you don't need to ship the .py source code files, it's enough to ship only .pyc bytecode files. Using py2exe it's not even obvious that your application is written in Python at all. It's not a silver bullet, but at least it makes recompiling/modifiying your app not easier than with Java (and/or .NET I suppose). That being said, even if you continue with the GUI approach, it may still be a good idea to factor out all the business logic in a separate module so you can eventually switch to a web application or a three-tier model without too much effort. Also, there's no need at all to put in countless hours implementing your own network protocol. If you really want to separate client and app server, then why not use something simple as PyRO, or even XML/RPC. HTH, -- Gerhard -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Frank Millman wrote: I am writing a multi-user accounting/business system. Data is stored in a database (PostgreSQL on Linux, SQL Server on Windows). I have written a Python program to run on the client, which uses wxPython as a gui, and connects to the database via TCP/IP. The client program contains all the authentication and business logic. It has dawned on me that anyone can bypass this by modifying the program. As it is written in Python, with source available, this would be quite easy. My target market extends well up into the mid-range, but I do not think that any CFO would contemplate using a program that is so open to manipulation. The only truly secure solution I can think of would involve a radical reorganisation of my program Please define what truly secure means to you. I think you'll find that the only truly secure solution is to install the critical authentication and business logic stuff that you want to protect on a server to which the user does not have physical access. People wanting to protect critical algorithms often conclude that they need to have a black box server which cannot be physically opened by the user. Or do you think this issue is in some way unique to Python? You might not realize that the only difference from a security point of view between shipping such a program written in Python and one written in, say, C++, is that modifying the program is somewhat more tedious with C++. That's no better than security by obscurity; maybe it should be called security by adiposity. ;-) But the real answer does depend a lot on *exactly* what kind of security you want (or, ultimately, what it turns out you really need, once you've clarified your thinking based on the feedback you do get here). Issues like: are you more concerned about detecting changes, or in preventing them in the first place? (the latter is much harder); what is the nature of software that competes with yours? (is it really any more secure, or only apparently so? maybe this is just a marketing issue); and is there any intellectual property that you are trying to protect here, or are you just interested in avoiding casual disruption of normal operation? -Peter -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Gerhard Häring wrote: Frank Millman wrote: Hi all I am writing a multi-user accounting/business system. Data is stored in a database (PostgreSQL on Linux, SQL Server on Windows). I have written a Python program to run on the client, which uses wxPython as a gui, and connects to the database via TCP/IP. The client program contains all the authentication and business logic. It has dawned on me that anyone can bypass this by modifying the program. As it is written in Python, with source available, this would be quite easy. My target market extends well up into the mid-range, but I do not think that any CFO would contemplate using a program that is so open to manipulation. [...] My suggestion is to use py2exe or cx_Freeze to package your application. It's then not as trivial to modify it. Btw. you don't need to ship the .py source code files, it's enough to ship only .pyc bytecode files. Using py2exe it's not even obvious that your application is written in Python at all. It's not a silver bullet, but at least it makes recompiling/modifiying your app not easier than with Java (and/or .NET I suppose). My problem is that, if someone has access to the network and to a Python interpreter, they can get hold of a copy of my program and use it to knock up their own client program that makes a connection to the database. They can then execute any arbitrary SQL command. That being said, even if you continue with the GUI approach, it may still be a good idea to factor out all the business logic in a separate module so you can eventually switch to a web application or a three-tier model without too much effort. Agreed Also, there's no need at all to put in countless hours implementing your own network protocol. If you really want to separate client and app server, then why not use something simple as PyRO, or even XML/RPC. Perhaps 'protocol' is the wrong word. I already have a simple socket server program running. If explain how I do it, perhaps you can indicate whether PyRO or XML/RPC would make my life easier. The server program is currently programmed to accept a number of message types from the client program. Each message's data string starts with a numeric prefix, which indicates the type of message, followed by a pickled tuple of arguments. The server program reads the string, extracts the numeric prefix, and passes the rest of the string to the appropriate function using a subthread. For example, I keep track of who is currently logged in. On startup, the client connects to my server and sends a '1' followed by their userid and other information. The server receives this and passed the data to a 'login' function, which uses a Python dictionary to store the information. If the server detects that the user is already logged in, it sends back an error code and the client program displays a message and terminates. Otherwise it sends back an 'ok' code, and the client can continue. When the client logs off, it sends a '2' followed by their userid, which the server receives and passes it to a 'logoff' function, which deletes the entry from the dictionary. The system of numeric prefixes and associated data string making up a message is what I mean by a protocol. HTH, -- Gerhard Thanks Frank -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Frank Millman wrote: Hi all I am writing a multi-user accounting/business system. Data is stored in a database (PostgreSQL on Linux, SQL Server on Windows). I have written a Python program to run on the client, which uses wxPython as a gui, and connects to the database via TCP/IP. The client program contains all the authentication and business logic. It has dawned on me that anyone can bypass this by modifying the program. If your program relies on a RDBMS, then it's the RDBMS job to enforce security rules. As it is written in Python, with source available, this would be quite easy. Then there's probably something wrong with the way you manage security. NB: splitting business logic from the GUI is still a good idea anyway. -- bruno desthuilliers - unpythonic sig: python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Peter Hansen wrote: Frank Millman wrote: I am writing a multi-user accounting/business system. Data is stored in a database (PostgreSQL on Linux, SQL Server on Windows). I have written a Python program to run on the client, which uses wxPython as a gui, and connects to the database via TCP/IP. The client program contains all the authentication and business logic. It has dawned on me that anyone can bypass this by modifying the program. As it is written in Python, with source available, this would be quite easy. My target market extends well up into the mid-range, but I do not think that any CFO would contemplate using a program that is so open to manipulation. The only truly secure solution I can think of would involve a radical reorganisation of my program Please define what truly secure means to you. Fair question. I am not expecting 'truly' to mean 100% - I know that is impossible. I will try to explain. Here are some assumptions - 1. A system adminstrator is responsible for the system. 2. There is a single userid and password for connecting to the database. This must be stored somewhere so that the client program can read it to generate the appropriate connection string. The users do not need to know this userid and password. 3. Each user has their own userid and password, which is stored in the database in a 'users' table. I use this in my program for authentication when a user tries to connect. 4. The client program can be run from anywhere on the network that has access to the program and to a Python interpreter. [snip] But the real answer does depend a lot on *exactly* what kind of security you want (or, ultimately, what it turns out you really need, once you've clarified your thinking based on the feedback you do get here). Issues like: are you more concerned about detecting changes, or in preventing them in the first place? (the latter is much harder); what is the nature of software that competes with yours? (is it really any more secure, or only apparently so? maybe this is just a marketing issue); and is there any intellectual property that you are trying to protect here, or are you just interested in avoiding casual disruption of normal operation? I am not concerned about anyone reading my code - in fact I am looking forward to releasing the source and getting some feedback. My concern is this. I have all this fancy authentication and business logic in my program. If someone wants to bypass this and get direct access to the database, it seems trivially easy. All they have to do is read my source, find out where I get the connection string from, write their own program to make a connection to the database, and execute any SQL command they want. If I move all the authentication and business logic to a program which runs on the server, it is up to the system administrator to ensure that only authorised people have read/write/execute privileges on that program. Clients will have no privileges, not even execute. They will have their own client program, which has to connect to my server program, and communicate with it in predefined ways. I *think* that in this way I can ensure that they cannot do anything outside the bounds of what I allow them. The only problem is that this is very different from the way my program works at present, so it will be quite a bit of work to re-engineer it. If someone can suggest a simpler solution obviously I would prefer it. But if the consensus is that I am thinking along the right lines, I will roll up my sleeves and get stuck in. -Peter I hope this explains my thinking a bit better. Thanks Frank -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
bruno modulix wrote: Frank Millman wrote: Hi all I am writing a multi-user accounting/business system. Data is stored in a database (PostgreSQL on Linux, SQL Server on Windows). I have written a Python program to run on the client, which uses wxPython as a gui, and connects to the database via TCP/IP. The client program contains all the authentication and business logic. It has dawned on me that anyone can bypass this by modifying the program. If your program relies on a RDBMS, then it's the RDBMS job to enforce security rules. Two possible responses to this - 1. You are right (90% probability) 2. I have certain requirements which can not easily be expressed in the RDBMS, so it is easier to use the application to enforce certain rules (10% probability) Unfortunately I am stuck with number 2 at present. As it is written in Python, with source available, this would be quite easy. Then there's probably something wrong with the way you manage security. Probably - I am learning the hard way g NB: splitting business logic from the GUI is still a good idea anyway. I do have it fairly well split, but it all ends up being processed on the client, which I think is the root of my problem. -- bruno desthuilliers - unpythonic sig: python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) Thanks Frank -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
As a side question Frank, how was your experiences using wxPython for your GUI? Any regrets choosing wxPyton over another toolkit? Was it very buggy? How was it to work with in general? Any other real-world wxPython feedback you have is appreciated. Frank Millman wrote: I am writing a multi-user accounting/business system. Data is stored in a database (PostgreSQL on Linux, SQL Server on Windows). I have written a Python program to run on the client, which uses wxPython as a gui, and connects to the database via TCP/IP. snip -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
This is a heck of a can of worms. I've been thinking about these sorts of things for awhile now. I can't write out a broad, well-structured advice at the moment, but here are some things that come to mind. 1. Based on your description, don't trust the client. Therefore, security, whatever that amounts to, basically has to happen on the server. The server should be designed with the expectation that any input is possible, from slightly tweaked variants of the normal messages to a robotic client that spews the most horrible ill-formed junk frequently and in large volumes. It is the server's job to decide what it should do. For example, consider a website that has a form for users to fill out. The form has javascript, which executes on the client, that helps to validate the data by refusing to submit the form unless the user has filled in required fields, etc. This is client-side validation (analagous to authentication). It is trivial for an attacker to force the form to submit without filling in required fields. Now if the server didn't bother to do its own validation but just inserted a new record into the database with whatever came in from the form submission, on the assumption that the client-side validation was sufficient, this would constitute a serious flaw. (If you wonder then why bother putting in client-side validation at all - two reasons are that it enhances the user experience and that it reduces the average load on the server.) 2. If you're moving security and business logic to the server you have to decide how to implement that. It is possible to rely solely on the RDBMS e.g., PostgreSQL. This has many consequences for deployment as well as development. FOr example, if you need to restrict actions based on user, you will have a different PgSQL user for every business user, and who is allowed to modify what will be a matter of PgSQL configuration. The PgSQL is mature and robust and well developed so you can rely on things to work as you tell them to. On the other hand, you (and your clients?) must be very knowledgeable about the database system to control your application. You have to be able to describe permissions in terms of the database. They have to be able to add new users to PgSQL for every new business user, and be able to adjust permissions if those change. You have to write code in the RDBMS procedural language which, well, I don't know a lot about it but I'm not to thrilled about the idea. Far more appealing is to write code in Python. Lots of other stuff. Imagine in contrast that user authentication is done in Python. In this scenario, you can have just a single PgSQL user for the application that has all access, and the Python always uses that database user but decides internally whether a given action is permitted based on the business user. Of course in this case you have to come up with your own security model which I'd imagine isn't trivial. You could also improve security by combining the approaches, e.g. have 3 database users for 3 different business roles with different database permissions, and then in Python you can decide which role applies to a business user and use the corresponding database user to send commands to the database. That could help to mitigate the risks of a flaw in the Python code. 3. You should therefore have a layer of Python that runs on the server and mediates between client and database. Here you can put authentication, validation and other security. You can also put all business logic. It receives all input with the utmost suspicion and only if everything is in order will it query the database and send information to the client. There is little or no UI stuff in this layer. To this end, you should check out Dabo at www.dabodev.com. This is an exciting Python project that I haven't used much but am really looking forward to when I have the chance, and as it becomes more developed. My impression is that it is useable right now. They basically provide a framework for a lot of stuff you seem to have done by hand, and it can give you some great ideas about how to structure your program. You may even decide to port it to Dabo. -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
On Sep 12, 2005, at 11:26 AM, Frank Millman wrote: If I move all the authentication and business logic to a program which runs on the server, it is up to the system administrator to ensure that only authorised people have read/write/execute privileges on that program. Clients will have no privileges, not even execute. They will have their own client program, which has to connect to my server program, and communicate with it in predefined ways. I *think* that in this way I can ensure that they cannot do anything outside the bounds of what I allow them. I think you have no choice but to do this. Even if you package up the program in an unmodifiable form, a competent user with a packet sniffer or even standard OS utilities can determine where you are connecting and bypass your security/logic. Only if the logic is implemented at a point beyond the user's reach can you be ensured of logic integrity. -Michael -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Frank Millman a écrit : bruno modulix wrote: Frank Millman wrote: Hi all I am writing a multi-user accounting/business system. Data is stored in a database (PostgreSQL on Linux, SQL Server on Windows). I have written a Python program to run on the client, which uses wxPython as a gui, and connects to the database via TCP/IP. The client program contains all the authentication and business logic. It has dawned on me that anyone can bypass this by modifying the program. If your program relies on a RDBMS, then it's the RDBMS job to enforce security rules. Two possible responses to this - 1. You are right (90% probability) 2. I have certain requirements which can not easily be expressed in the RDBMS, so it is easier to use the application to enforce certain rules (10% probability) easier, but with a somewhat annoying side-effect... Do you really mean easier, or do you think impossible ? Unfortunately I am stuck with number 2 at present. :-/ As it is written in Python, with source available, this would be quite easy. Then there's probably something wrong with the way you manage security. Probably - I am learning the hard way g As most of us do :-/ Having jumped directly from 2-tiers fat client apps to web apps, I really have no experience with adding a third tiers to a fat client app, but AFAICT, Python seems to have a lot to offer here. BTW, sorry if my answer seemed a bit rude, I didn't mean to be that critic. -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
On Mon, 12 Sep 2005 06:34:45 -0700, Frank Millman wrote: The client program contains all the authentication and business logic. It has dawned on me that anyone can bypass this by modifying the program. As it is written in Python, with source available, this would be quite easy. My target market extends well up into the mid-range, but I do not think that any CFO would contemplate using a program that is so open to manipulation. Ha ha ha ha! Oh, you're a funny man! How many CFOs contemplate using Windows, Internet Explorer, SQL Server, and all the other Microsoft technologies that are so open to manipulation by spyware, viruses and other malware? What you do is don't tell them that they can modify the source code. They won't think of it. And if they do, well, that isn't your problem. That's an internal problem for their IT department, precisely as it would be if they gave full read/write permission to everyone in the company instead of restricting permissions to those who need them. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Hi, Why not just releasing the *.pyc ? Regards, Philippe Frank Millman wrote: Hi all I am writing a multi-user accounting/business system. Data is stored in a database (PostgreSQL on Linux, SQL Server on Windows). I have written a Python program to run on the client, which uses wxPython as a gui, and connects to the database via TCP/IP. The client program contains all the authentication and business logic. It has dawned on me that anyone can bypass this by modifying the program. As it is written in Python, with source available, this would be quite easy. My target market extends well up into the mid-range, but I do not think that any CFO would contemplate using a program that is so open to manipulation. The only truly secure solution I can think of would involve a radical reorganisation of my program, so I am writing to see if anyone has a simpler suggestion. Here is the idea. 1. Write a socket server program that runs on the server. The socket server is the only program that connects to the database. The client program connects to the server, which authenticates the client against the database and then listens for requests from the client. 2. Devise my own protocol for communication between client and server. For selects, the client sends a request, the server checks permissions, then retrieves the data from the database and passes it to the client. For updates, the client passes up the data to be updated, the server checks it against its business logic, and then updates the database. There is the question of where state should be maintained. If on the server, I would have to keep all the client/server connections open, and maintain the state of all the sessions, which would put quite a load on the server. If on the client, I would have to reorganise my thinking even more, but this would have an advantage - I will eventually want to write a browser interface, and this would be much closer in concept, so the two approaches would be quite similar. This raises the question of whether I should even bother with a gui client, or bite the bullet and only have a browser based front end. Judging from recent comments about new technologies such as Ajax, a lot of the disadvantages have been overcome, so maybe this is the way to go. It would be a shame to scrap all the effort I have put into my wxPython-based front end. On the other hand, it would be pointless to continue with an approach that is never going to give me what I want. Any advice which helps to clarify my thinking will be much appreciated. Thanks Frank Millman -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
On Mon, 12 Sep 2005 08:33:10 -0700, Frank Millman wrote: My problem is that, if someone has access to the network and to a Python interpreter, they can get hold of a copy of my program and use it to knock up their own client program that makes a connection to the database. They can then execute any arbitrary SQL command. Why is that your problem, instead of the company's problem? It is their database server, yes? If they want to connect to it and execute arbitrary SQL commands on their own database, (1) who are you to tell them they can't? and (2) they hardly need your program to do it. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: How to protect Python source from modification
Steven D'Aprano wrote: On Mon, 12 Sep 2005 08:33:10 -0700, Frank Millman wrote: My problem is that, if someone has access to the network and to a Python interpreter, they can get hold of a copy of my program and use it to knock up their own client program that makes a connection to the database. They can then execute any arbitrary SQL command. Why is that your problem, instead of the company's problem? It is their database server, yes? If they want to connect to it and execute arbitrary SQL commands on their own database, (1) who are you to tell them they can't? and (2) they hardly need your program to do it. -- Steven If they choose to give the userid and password to an individual, they are obviously giving him permission to execute any command. On the other hand, they can reasonably expect to set up users without giving them direct access to the database, in which case I think they would be upset if the users found this restriction easy to bypass. Frank -- http://mail.python.org/mailman/listinfo/python-list