-
Notifications
You must be signed in to change notification settings - Fork 993
Extend query config with query.masked config with Type.PASSWORD for secure query masking #1593
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
base: 10.9.x
Are you sure you want to change the base?
Conversation
…ecure query masking
|
🎉 All Contributor License Agreements have been signed. Ready to merge. |
| orderInGroup = defineIncrementTimestampConfigs(config, orderInGroup); | ||
| orderInGroup = defineQueryAndQuoteConfigs(config, orderInGroup); | ||
| defineTransactionAndRetryConfigs(config, orderInGroup); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extend this Options method, because of falling to checkstyle error of exceeding 128 lines in a method.
|
|
||
| return true; | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a validation in order to limit using of either of query or query.masked config.
| String msg = | ||
| "Do not specify table filtering configs with 'query' or 'query.masked'. " | ||
| + "Remove table.whitelist / table.blacklist / table.include.list / " | ||
| + "table.exclude.list."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either of table.filtering.options or query should be provided as the connector would work in table.mode or query.mode and not both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few things @KGaneshDatta
- Since query was never exposed on cloud before this, we should perform some manual testing to understand/validate the behaviour. (How frequently will the query be executed, What if the query is taking too long to exceute ? do we have any observability into this ? Can multiple queries be provided (
select * from table1;select* from table2;)) - If user has specified both table include/exclude list and query, we don't know which way they wanna go. The validation exception message currently instructs them to remove table include/exclude configs. Which might be other way round also.
| private boolean hasAnyQueryConfig() { | ||
| String query = config.getString(JdbcSourceConnectorConfig.QUERY_CONFIG); | ||
| Password queryMasked = | ||
| config.getPassword(JdbcSourceConnectorConfig.QUERY_MASKED_CONFIG); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you make config.getQuery return optional, then this hasAnyQueryConfig method will not be needed.
…on to allow only select queries in query configs
…masked has been set
src/main/java/io/confluent/connect/jdbc/source/JdbcSourceConnectorConfig.java
Show resolved
Hide resolved
src/main/java/io/confluent/connect/jdbc/source/JdbcSourceConnectorConfig.java
Outdated
Show resolved
Hide resolved
| } else if (mode.equals(JdbcSourceTaskConfig.MODE_INCREMENTING)) { | ||
| tableQueue.add( | ||
| new TimestampIncrementingTableQuerier( | ||
| config, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
config is unused in the passed class. What's the need of this new param in the constructor ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The config object has been used in TableQuerier class in order to check for query config has been set or not. As, TimestampIncrementingTableQuerier is referencing TableQuerier as super class, it is definitely required to include all the arguments.
| this.lastUpdate = 0; | ||
| this.suffix = suffix; | ||
| this.attemptedRetries = 0; | ||
| this.shouldTrimSensitiveLogs = config.isQueryMasked(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Directly pass the config.isQueryMasked value, rather than whole config object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, agree. But if we pass the config object, then it would be used for all other methods in future instead of each argument for each usecase.
src/main/java/io/confluent/connect/jdbc/source/TableQuerierProcessor.java
Outdated
Show resolved
Hide resolved
| TableQuerier querier, SQLNonTransientException sqle) { | ||
| SQLException trimmedException = shouldTrimSensitiveLogs | ||
| ? LogUtil.trimSensitiveData(sqle) : sqle; | ||
| String querierLog = getQuerierLogString(querier); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rather than redacting the whole querier, simply redact the query member var in the toString for querier object.
src/main/java/io/confluent/connect/jdbc/source/TableQuerierProcessor.java
Show resolved
Hide resolved
|
akanimesh7
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing validation -- If mode is query and timestamp.initial is provided validation passes.
| ); | ||
| } | ||
|
|
||
| protected Map<String, Object> computeInitialOffset( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactor -- don't enter this function if we are in query mode. Offsets are always null for query mode. And hence no need to redact here since it will always be table name.
| } | ||
| } | ||
|
|
||
| protected String getQuerierLogString(String query) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be shortened as suggested previously
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this function, can't we simply replace this function call with LogUtil.sensitiveLog(shouldTrimSensitiveLogs, query) ?
|
|
||
| } | ||
| /** Validate that provided query strings start with a SELECT statement. */ | ||
| private boolean validateSelectStatement(String statement, String configKey) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
String configKey is unncessary. It can be removed. There is only one possible value -- query
| <version>1.7</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.apache.commons</groupId> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?


Problem
Type.Passwordto ensure secure logging by masking sensitive values and preventing accidental exposure.table.modeorquery.mode.Solution
Does this solution apply anywhere else?
If yes, where?
Test Strategy
Testing done:
Release Plan