Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HIVE-27308: Avoid exposing client keystore and truststore passwords in the JDBC URL #4282

Merged
merged 2 commits into from May 16, 2023

Conversation

VenuReddy2103
Copy link
Contributor

@VenuReddy2103 VenuReddy2103 commented May 2, 2023

What changes were proposed in this pull request?

Added a new property storePasswordPath to JDBC URL that point to the local JCE keystore file storing the password aliases. When an existing password property is present in URL, ignores to fetch that particular alias from local jceks(i.e., giving preference to existing password property). And if password property is not present in URL, fetches the password from local jceks file specified in storePasswordPath property. Hive JDBC can obtains the passwords with Configuration.getPassword API to read the password from jceks file.

JDBC URL would look like -
beeline -u "jdbc:hive2://kvr-host:10001/default;retries=5;ssl=true;sslTrustStore=/tmp/truststore.jks;transportMode=http;httpPath=cliservice;twoWay=true;sslKeyStore=/tmp/keystore.jks;storePasswordPath=localjceks://file/tmp/client_creds.jceks"

Why are the changes needed?

At present, we may have trustStorePassword, keyStorePassword, zooKeeperTruststorePassword, zooKeeperKeystorePassword passwords in the JDBC URL. Exposing these passwords in URL can be a security concern. We can hide all these passwords from JDBC URL when we protect these passwords in a local JCEKS keystore file and pass the JCEKS file path to URL instead.

Does this PR introduce any user-facing change?

Optional storePasswordPath property is supported in JDBC URL. Existing trustStorePassword, keyStorePassword, zooKeeperTruststorePassword, zooKeeperKeystorePassword properties continue to exist and are supported in JDBC URL without any change in their behavior. When both password(s) and storePasswordPath properties are present in URL, password(s) property is preferred. storePasswordPath property is effective only when password(s) property is not in JDBC URL.

How was this patch tested?

Tested manually

@VenuReddy2103 VenuReddy2103 changed the title [WIP]HIVE-27308: Avoid exposing client keystore and truststore passwords in the JDBC URL HIVE-27308: Avoid exposing client keystore and truststore passwords in the JDBC URL May 9, 2023
@VenuReddy2103
Copy link
Contributor Author

@saihemanth-cloudera @dengzhhu653 Could you please help review this PR

@@ -1008,6 +1016,10 @@ SSLConnectionSocketFactory getTwoWaySSLSocketFactory() throws SQLException {
JdbcConnectionParams.SUNJSSE_ALGORITHM_STRING);
String keyStorePath = sessConfMap.get(JdbcConnectionParams.SSL_KEY_STORE);
String keyStorePassword = sessConfMap.get(JdbcConnectionParams.SSL_KEY_STORE_PASSWORD);
if (keyStorePassword == null) {
keyStorePassword = Utils.getPasswordFromCredentialProvider(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we load all credentials from the same creds file, is this by design?

And we can add some comment how to use the key to generate the local creds, looks like we use JdbcConnectionParams.SSL_KEY_STORE_PASSWORD as the key.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move all these three types of passwords to a different API? This API can take in the String key as a parameter and return a string password. You can then call the API at lines #900, #1018, and #1037.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we load all credentials from the same creds file, is this by design?

And we can add some comment how to use the key to generate the local creds, looks like we use JdbcConnectionParams.SSL_KEY_STORE_PASSWORD as the key.

Yes. We store all the passwords in the same file. Will document about the generation and usage in cwiki https://cwiki.apache.org/confluence/display/Hive/HiveServer2+Clients

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move all these three types of passwords to a different API? This API can take in the String key as a parameter and return a string password. You can then call the API at lines #900, #1018, and #1037.

Done. Added an API in Utils.java that takes map and key as arguments. First tries to find the password from map. If not found, then gets it from credential provider.

public static String getPasswordFromCredentialProvider(String providerPath, String key) {
try {
if (providerPath != null) {
Configuration conf = new Configuration();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of creating a new config, can we reuse the setHiveConfs() L#326-#328?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used org.apache.hadoop.conf.Configuration object because Configuration.getPassword resolve the key as an alias through the CredentialProvider API internally. So we can avoid using the CredentialProvider APIs to fetch password explicitly in our code.

@sonarcloud
Copy link

sonarcloud bot commented May 12, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 28 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

Copy link
Contributor

@saihemanth-cloudera saihemanth-cloudera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM +1.

@saihemanth-cloudera saihemanth-cloudera merged commit 08137d7 into apache:master May 16, 2023
5 checks passed
yeahyung pushed a commit to yeahyung/hive that referenced this pull request Jul 20, 2023
…n the JDBC URL (apache#4282) (Venu Reddy, reviewed by Zhihua Deng and Sai Hemanth Gantasala)
tarak271 pushed a commit to tarak271/hive-1 that referenced this pull request Dec 19, 2023
…n the JDBC URL (apache#4282) (Venu Reddy, reviewed by Zhihua Deng and Sai Hemanth Gantasala)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants