none
How can I secure my confidential data? RRS feed

  • Question

  • Hi
     
    The issue is security and how to handle that is a Line-of-business system.

    I'm having the following given parameters (cant change those):
    • The system is a gouverment business system
    • The system has some sensitive data
    • The data must only be available for users that is granted access
    • The database is in secure zone
    • The security requirments defines that data does not have to be encrypted in the secure zone (meaning that data in db will not be encrypted)
    • The clients that will be viewing data is in the network domain
    • The network domain is not defined as secure zone
    • Single Sign On is of high importancy

    The choises made so far (can change that, but would prefer not to)
    • The system will use role based security
    • Roles will be defined as security groups in Active Directory
    • The client will be a smart client (actually a smart composit client)
    • Sensitive data will not be buffered/cached on the client
    • The above means that sensitive data will only be available when the client is online and within the domain (connected by VPN is OK)
    • Sql authentication against the database is hightly preferred above integrated security.

    Having a smart client this means that most of the business logic will be running on the client computer. My initial tought was that I would have my data access assembly on the client computer. The sql connection string would be encrypted in the config file.
    I would then use the WindowsPrincipal to verify the user and get the users role, and if the user is in the correct role I would grant him access to the secured data. I would strong name my assemblies and I would secure my connection to the database.
    This would be an easy and straight forward model to use.

    However, I now realise that this will not work. Looking at the client as a potential attacker with code running as full trust would mean that a different program could use my database assembly, probably be able to fake the WindowsIdentity (?) for the thread, override any security stuff I have added or use reflection to access my private methods and therby access my data.
    Running in full trust I expect that it will also be possible to detect and use my decryption algorithm for the database access.

    So, the "simple" question is:
    Is there any good way to secure data access in this scenario? What would you folks suggest to do?
    Also links to reference litterature on the topic is welcome.


    Best regards, TEK



    Wednesday, November 19, 2008 8:45 AM

Answers

  • Compromised windows identity is not an issue.

    If a user is running your code with a valid windows identity, then I think you have to accept that as evidence that the user is who the windows identity says they are. If somebody can fake their Windows identity, then it's pretty much game over.
    If the chain of evidence is broken, at any point, including Windows authentication, then the whole chain falls.

    But protecting a SQL connection string with a SQL authentication password is a big deal.

    You have to assume that if the user can USE the SQL connection string, then they can also get access to the plain text of the SQL connection string, and use it for direct connections without your module, by some means or another. The most difficult attack to defend against is an evil user who attaches a debugger to your running process and combs through memory for the connection string.

    Protecting and distributing the SQL authentication passwords also becomes a huge deal. What are you going to do if one of the SQL auth passwords gets compromised, and you have to change it?

    All your problems go away if you can use windows authetnication instead of SQL authentication on the database. In that case, you just permission individual tables in the database based on the role of the user as specified by the Windows login to SQL.

    • Marked as answer by Zhi-Xin Ye Tuesday, November 25, 2008 3:36 AM
    Wednesday, November 19, 2008 8:59 AM

All replies

  • Compromised windows identity is not an issue.

    If a user is running your code with a valid windows identity, then I think you have to accept that as evidence that the user is who the windows identity says they are. If somebody can fake their Windows identity, then it's pretty much game over.
    If the chain of evidence is broken, at any point, including Windows authentication, then the whole chain falls.

    But protecting a SQL connection string with a SQL authentication password is a big deal.

    You have to assume that if the user can USE the SQL connection string, then they can also get access to the plain text of the SQL connection string, and use it for direct connections without your module, by some means or another. The most difficult attack to defend against is an evil user who attaches a debugger to your running process and combs through memory for the connection string.

    Protecting and distributing the SQL authentication passwords also becomes a huge deal. What are you going to do if one of the SQL auth passwords gets compromised, and you have to change it?

    All your problems go away if you can use windows authetnication instead of SQL authentication on the database. In that case, you just permission individual tables in the database based on the role of the user as specified by the Windows login to SQL.

    • Marked as answer by Zhi-Xin Ye Tuesday, November 25, 2008 3:36 AM
    Wednesday, November 19, 2008 8:59 AM
  • Issue 1: Knowing that the user is who he says he is.

    OK, then maybe I have missed something.

    My question then is how I can check that the Principla that I'm checking against is a domain user with only the roles given by the domain administrator.

    Check out the following code

    1 [System.Security.Permissions.PrincipalPermission(System.Security.Permissions.SecurityAction.Demand, Authenticated = true, Role = "Doctors")]  
    2 public class SecureDataStorage  
    3 {      
    4     private string _secretValue = "Secured data for nobody to see";  
    5  
    6     [System.Security.Permissions.PrincipalPermission(System.Security.Permissions.SecurityAction.Demand, Authenticated = true, Role = "Administrator")]  
    7     public string GetSecureData() {  
    8         return _secretValue;  
    9     }  
    10

    Trying execute the code below from a exe file (the code above is in a separte dll) failed with a security exceotion.
    This is probably because I'm not a member of the Doctors role.
    SecureClassLibrary.SecureDataStorage ds = new SecureClassLibrary.SecureDataStorage();  
                 

    I then attemted to create a group Doctors on my computer and add my self to that group.

    However, if I did the following (after adding myself ot the Doctors role) I succeeded to create an instance of the class.
    The code for the MyPrincipal is included at the end of this post.
    System.Threading.Thread.CurrentPrincipal = new MyPrincipal();  
    SecureClassLibrary.SecureDataStorage ds = new SecureClassLibrary.SecureDataStorage(); 

    The idea with this experience is to illustrate that the .exe file is hostail code written by an employee that should not have access to the information within the SecureDataStorage.

    The MyPrincipal code:
    public class MyPrincipal : WindowsPrincipal  
        {  
            public MyPrincipal()  
                : base(new MyIdentity()) {  
            }  
            public override bool IsInRole(int rid) {  
                return true;  
            }  
            public override bool IsInRole(SecurityIdentifier sid) {  
                return true;  
            }  
            public override bool IsInRole(string role) {  
                return true;  
            }  
            public override bool IsInRole(WindowsBuiltInRole role) {  
                return true;  
            }  
            public override IIdentity Identity {  
                get {  
                    System.Diagnostics.Debug.Assert(base.Identity is MyIdentity);  
                    return base.Identity;  
                }  
            }  
        }  
        public class MyIdentity : WindowsIdentity  
        {  
            public MyIdentity()  
                : base(WindowsIdentity.GetCurrent().Token) {  
            }  
            public override bool IsAuthenticated {  
                get {  
                    return true;  
                }  
            }          
        } 
    Wednesday, November 19, 2008 2:38 PM
  • lol. Good one. (Sorry. I shouldn't laugh).

    But I do agree: you can't rely entirely on client-side role checks to hide secrets.

    Wednesday, November 19, 2008 6:07 PM