Synapse
  1. Synapse
  2. SYNAPSE-376

Securing password in the datasource definition

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.0
    • Component/s: None
    • Labels:
      None

      Description

      Currently ,passwords in the datasource definition are in clear text format. (In synapse.properties). Those have to be encrypted.

        Activity

        Hide
        Eric Hubert added a comment -

        As stated earlier on the mailing lists I see this as very important requirement and hope you can implement this for the next version. Encrypted datasource passwords are a prerequisite for many companies to introduce any system to their live environment (part of their security policy).

        Show
        Eric Hubert added a comment - As stated earlier on the mailing lists I see this as very important requirement and hope you can implement this for the next version. Encrypted datasource passwords are a prerequisite for many companies to introduce any system to their live environment (part of their security policy).
        Hide
        indika priyantha kumara added a comment -

        I thought to completely separate the securing password and make it available for anywhere securing for plaintext want.

        Rather than using encrypted data in each location, keep encrypted text in a separate file. For example: Without setting encrypted password in configurations for each datasource,dbreport,lookup or in any place, keep every encrypted text in a single location.

        Cipher text file

        cipher-text.properties

        1. Common properties

        encryption.algorithm.default=RSA

        plaintexts=admin,password

        1. configuration per each plaintext
          admin.ciphertext=aaaxzxxs223a
          admin.encryption.algorithm=RSA

        password.ciphertext=fdgfdfga2gf

        Then, For example, if the password for dblookup mediator has to be secured

        <dblookup>
        <connection>
        <pool>
        <driver>org.apache.derby.jdbc.ClientDriver</driver>
        <url>jdbc:derby://localhost:1527/synapsedb;create=false</url>
        <user>synapse</user>
        **<password>admin</password>**
        </pool>
        .........

        Then, within dblookup mediator, before make connection, can get the decrypted password as

        DecryptedDataRegistry.get('admin');

        This is same for anywhere needs decrypted password or any decrypted text.

        In this approach, the 'admin' plaintext password is really a logical one and it only uses for lookup actual password from encrypted text file.

        Even this approaches, adds another configuration file, there are lot of benefit.

        (1) Single point of configuration for each plaintext-cipher-text pairs. Therefore, we can separately specify algorithms or any parameters for each plaintext.

        (2) We can add extra security. For example, we can sign "cipher-text.properties" file. If the encrypted texts are scatted everywhere, then adding extra security will not be feasible.

        (3) This will become a reusable component that can be used anywhere, even, with in any other projects.

        Show
        indika priyantha kumara added a comment - I thought to completely separate the securing password and make it available for anywhere securing for plaintext want. Rather than using encrypted data in each location, keep encrypted text in a separate file. For example: Without setting encrypted password in configurations for each datasource,dbreport,lookup or in any place, keep every encrypted text in a single location. Cipher text file cipher-text.properties Common properties encryption.algorithm.default=RSA plaintexts=admin,password configuration per each plaintext admin.ciphertext=aaaxzxxs223a admin.encryption.algorithm=RSA password.ciphertext=fdgfdfga2gf Then, For example, if the password for dblookup mediator has to be secured <dblookup> <connection> <pool> <driver>org.apache.derby.jdbc.ClientDriver</driver> <url>jdbc:derby://localhost:1527/synapsedb;create=false</url> <user>synapse</user> ** <password>admin</password> ** </pool> ......... Then, within dblookup mediator, before make connection, can get the decrypted password as DecryptedDataRegistry.get('admin'); This is same for anywhere needs decrypted password or any decrypted text. In this approach, the 'admin' plaintext password is really a logical one and it only uses for lookup actual password from encrypted text file. Even this approaches, adds another configuration file, there are lot of benefit. (1) Single point of configuration for each plaintext-cipher-text pairs. Therefore, we can separately specify algorithms or any parameters for each plaintext. (2) We can add extra security. For example, we can sign "cipher-text.properties" file. If the encrypted texts are scatted everywhere, then adding extra security will not be feasible. (3) This will become a reusable component that can be used anywhere, even, with in any other projects.
        Hide
        Andreas Veithen added a comment -

        When Synapse accesses the datasource it obviously needs to decrypt the password. Thus you also need to store the decryption key somewhere. To get real security (and not just security by obscurity), you would have to protect this key by password and ask the user to provide the password when starting Synapse. Is this what you suggest?

        Show
        Andreas Veithen added a comment - When Synapse accesses the datasource it obviously needs to decrypt the password. Thus you also need to store the decryption key somewhere. To get real security (and not just security by obscurity), you would have to protect this key by password and ask the user to provide the password when starting Synapse. Is this what you suggest?
        Hide
        indika priyantha kumara added a comment -

        I initially thought , both trust-store and key-store configurations to keep in the synape.properties. And 'cipher-text.properties' keep all the cipher texts that will be used in anywhere in the synapse (not just for datasource - for example , password in dblookp mediator). Now, I feel both trust-store and key-store configuration also have to be moved to 'cipher-text.properties' and both password for trust-store and key-store need to be kept on a separate file and after reading that file (in start up ) , do delete it. Then, passwords for both trust-store and key-store are one time. We can also use asking user to give password for both trust-store and key-store. But , I prefer to keep those in a file and after reading delete it.

        Then

        "cipher-text.properties" file look like

        1. Common properties

        truststore.location=./../webapp/WEB-INF/classes/conf/identity.jks
        ...... # other parameters for truststore configuration (except passwords)

        keystore.location=./../webapp/WEB-INF/classes/conf/identity.jks
        .... # other parameters for keystore configuration (except passwords)

        encryption.algorithm.default=RSA

        plaintexts=admin,password

        1. configuration per each plaintext
          admin.ciphertext=aaaxzxxs223a
          admin.encryption.algorithm=RSA

        password.ciphertext=fdgfdfga2gf

        And another one time file (on start up , after reading , do delete it)

        "keystore-truststore-password.properties"

        keystore.password=plaintext
        truststore.password=palintext

        Show
        indika priyantha kumara added a comment - I initially thought , both trust-store and key-store configurations to keep in the synape.properties. And 'cipher-text.properties' keep all the cipher texts that will be used in anywhere in the synapse (not just for datasource - for example , password in dblookp mediator). Now, I feel both trust-store and key-store configuration also have to be moved to 'cipher-text.properties' and both password for trust-store and key-store need to be kept on a separate file and after reading that file (in start up ) , do delete it. Then, passwords for both trust-store and key-store are one time. We can also use asking user to give password for both trust-store and key-store. But , I prefer to keep those in a file and after reading delete it. Then "cipher-text.properties" file look like Common properties truststore.location=./../webapp/WEB-INF/classes/conf/identity.jks ...... # other parameters for truststore configuration (except passwords) keystore.location=./../webapp/WEB-INF/classes/conf/identity.jks .... # other parameters for keystore configuration (except passwords) encryption.algorithm.default=RSA plaintexts=admin,password configuration per each plaintext admin.ciphertext=aaaxzxxs223a admin.encryption.algorithm=RSA password.ciphertext=fdgfdfga2gf And another one time file (on start up , after reading , do delete it) "keystore-truststore-password.properties" keystore.password=plaintext truststore.password=palintext
        Hide
        indika priyantha kumara added a comment -

        I hope to change ""keystore-truststore-password.properties"" to a "plain-text.properties"

        And it will look like as follows

        onetime=true| false

        keystore.password=plain text
        truststore.password=plain text

        1. passwords the you want to secure (without encrypting )

        admin= admin123

        If the ontime=true , then , after reading this file, file will be deleted. Otherwise, keep without deleting . Then, for production environments this need to be ontime=true and for developments environments ontime=false.

        Now, for securing password , there are two options - one time passwords with "paint-text.properties" and using "cipher-text.properties".

        Show
        indika priyantha kumara added a comment - I hope to change ""keystore-truststore-password.properties"" to a "plain-text.properties" And it will look like as follows onetime=true| false keystore.password=plain text truststore.password=plain text passwords the you want to secure (without encrypting ) admin= admin123 If the ontime=true , then , after reading this file, file will be deleted. Otherwise, keep without deleting . Then, for production environments this need to be ontime=true and for developments environments ontime=false. Now, for securing password , there are two options - one time passwords with "paint-text.properties" and using "cipher-text.properties".
        Hide
        Andreas Veithen added a comment -

        This looks quite good. I would add as a requirement that all this should be completely optional, i.e. people should be able to continue using plaintext passwords without the need to set up any new config files. Maybe we should have some sort of plugin system for this: there would be an interface SecretManager and two implementations PlaintextSecretManager and EncryptedSecretManager. At startup Synapse would register a PlaintextSecretManager as default. Then we can have a Startup implementation that configures an EncryptedSecretManager and replaces the default one. We only need a place to hold the reference to the configured SecretManager. SynapseConfiguration would be a good place as it is also there that we hold the reference to the Registry implementation.

        Show
        Andreas Veithen added a comment - This looks quite good. I would add as a requirement that all this should be completely optional, i.e. people should be able to continue using plaintext passwords without the need to set up any new config files. Maybe we should have some sort of plugin system for this: there would be an interface SecretManager and two implementations PlaintextSecretManager and EncryptedSecretManager. At startup Synapse would register a PlaintextSecretManager as default. Then we can have a Startup implementation that configures an EncryptedSecretManager and replaces the default one. We only need a place to hold the reference to the configured SecretManager. SynapseConfiguration would be a good place as it is also there that we hold the reference to the Registry implementation.
        Hide
        indika priyantha kumara added a comment -

        Thanks for valuable idea.

        I haven't yet decided the API for this. Once, I decide , I will publish it here . I would consider your valuable suggestion when designing API.

        Thanks
        Indika

        Show
        indika priyantha kumara added a comment - Thanks for valuable idea. I haven't yet decided the API for this. Once, I decide , I will publish it here . I would consider your valuable suggestion when designing API. Thanks Indika
        Hide
        indika priyantha kumara added a comment -

        I am going to implements this as follows .

        SecretManager - One instance that can be accessed in anywhere.

        SecretManager keeps secret as PlaintextSecrets (and / or) CipherTextSecrets . These secrets configures with one or more SecretsRepository. SecretsRepository can be any (file base, JDBC). Configuration of these have to be go somewhere (separate file or synapse config).

        Everything is optional, if there aren't any configurations, then , all works same as the current behaviour.

        Show
        indika priyantha kumara added a comment - I am going to implements this as follows . SecretManager - One instance that can be accessed in anywhere. SecretManager keeps secret as PlaintextSecrets (and / or) CipherTextSecrets . These secrets configures with one or more SecretsRepository. SecretsRepository can be any (file base, JDBC). Configuration of these have to be go somewhere (separate file or synapse config). Everything is optional, if there aren't any configurations, then , all works same as the current behaviour.
        Hide
        Andreas Veithen added a comment -

        I looks like this is now fully implemented. Indika, should we mark this issue as resolved?

        Show
        Andreas Veithen added a comment - I looks like this is now fully implemented. Indika, should we mark this issue as resolved?
        Hide
        indika priyantha kumara added a comment -

        There is a work remaining to complete in order to resolve this issue - Providing required credentials (maximum three, minimum one) root level secret repository. I hope as an initial work, doing these in three ways - JMX, one time password file, command line. For JMX, I have already added MBean. I have to add a simple MBean to manage server - later can add remote JMX connector and more JMX functionality. For command line, I expected to use Jline [1], but there was some issue in windows with that. Therefore, I will provide more configurable options.

        When, initiating synapse, if the deployment mode is 'production', check for Secret Manager's state, if it is already initialized or can be initiated (only if required credentials can be provided -For JMX, this is false - late start), synapse will be started immediately. Otherwise, using JMX, it is needed to manually initiate the secret manager and then starts the synapse.

        [1] http://jline.sourceforge.net/

        Thanks
        Indika

        Show
        indika priyantha kumara added a comment - There is a work remaining to complete in order to resolve this issue - Providing required credentials (maximum three, minimum one) root level secret repository. I hope as an initial work, doing these in three ways - JMX, one time password file, command line. For JMX, I have already added MBean. I have to add a simple MBean to manage server - later can add remote JMX connector and more JMX functionality. For command line, I expected to use Jline [1] , but there was some issue in windows with that. Therefore, I will provide more configurable options. When, initiating synapse, if the deployment mode is 'production', check for Secret Manager's state, if it is already initialized or can be initiated (only if required credentials can be provided -For JMX, this is false - late start), synapse will be started immediately. Otherwise, using JMX, it is needed to manually initiate the secret manager and then starts the synapse. [1] http://jline.sourceforge.net/ Thanks Indika
        Hide
        Eric Hubert added a comment -

        I just wanted to add that there are definitely different levels of security requirements. Some organizations do have strict requirements to use only encrypted db passwords. The level of targeted protection is rather low. They just want to take care that not every user with read permissions on some app server config files is able to access a database directly. Even if this encrypted password is created via a hard-coded passphrase in the source code of the app server everything is fine as this would take some additional overhead to find this out.

        E.g. have a look at JBoss default solution: http://kickjava.com/src/org/jboss/resource/security/SecureIdentityLoginModule.java.htm
        It is just a hard coded passphrase in the source but for some environments this is "enough" protection compared to a non-encrypted plain text password in a config file.
        Sounds strange? You call it security by obscurity? This are just my personal experiences.

        Maybe there should also be an option to go with a "default" passphrase used for password encryption? Even if a master password would be stored in some other file or keystore this might be sufficient for some users. One has to know where to find a master passphrase and more importantly how to decrypt the encrypted password (possibly by studying the source code). Much more overhead than taking the plain text db password and accessing the db straight away, although not highly secure.

        But entering a password at startup from the commandline or via jmx is certainly not an option for most of the users I'm aware of as well.

        Just my 0.2 cents.

        Show
        Eric Hubert added a comment - I just wanted to add that there are definitely different levels of security requirements. Some organizations do have strict requirements to use only encrypted db passwords. The level of targeted protection is rather low. They just want to take care that not every user with read permissions on some app server config files is able to access a database directly. Even if this encrypted password is created via a hard-coded passphrase in the source code of the app server everything is fine as this would take some additional overhead to find this out. E.g. have a look at JBoss default solution: http://kickjava.com/src/org/jboss/resource/security/SecureIdentityLoginModule.java.htm It is just a hard coded passphrase in the source but for some environments this is "enough" protection compared to a non-encrypted plain text password in a config file. Sounds strange? You call it security by obscurity? This are just my personal experiences. Maybe there should also be an option to go with a "default" passphrase used for password encryption? Even if a master password would be stored in some other file or keystore this might be sufficient for some users. One has to know where to find a master passphrase and more importantly how to decrypt the encrypted password (possibly by studying the source code). Much more overhead than taking the plain text db password and accessing the db straight away, although not highly secure. But entering a password at startup from the commandline or via jmx is certainly not an option for most of the users I'm aware of as well. Just my 0.2 cents.
        Hide
        indika priyantha kumara added a comment -

        Hi Eric

        Thanks lots for the suggestions. I will add all of these as configurable options so that client can select what he wants.

        Thanks
        Indika

        Show
        indika priyantha kumara added a comment - Hi Eric Thanks lots for the suggestions. I will add all of these as configurable options so that client can select what he wants. Thanks Indika
        Hide
        indika priyantha kumara added a comment -

        I have done the things described in the JIRA and did test too. I also update the documents.

        Any issues, improvements will be done with separate JIRAs

        Show
        indika priyantha kumara added a comment - I have done the things described in the JIRA and did test too. I also update the documents. Any issues, improvements will be done with separate JIRAs

          People

          • Assignee:
            indika priyantha kumara
            Reporter:
            indika priyantha kumara
          • Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development