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

Security: Store datasource passwords encrypted in secureJsonData #16175

Merged
merged 16 commits into from
Apr 15, 2019

Conversation

aocenas
Copy link
Member

@aocenas aocenas commented Mar 23, 2019

Closes #10827

This got a bit wide in the sense that it needs to touch much more parts than expected. Because of that I would welcome some early feedback if the approach still makes sense.

For data sources we store passwords either in non encrypted columns or in secureJsonData which is encrypted. MSSql and Postgres already store them encrypted other datasources store them plain text. What this PR is doing. Some caveats:

  • We store passwords also for browser only datasources which need to be sent back to front end in plaintext.
  • We have a provisioning format that already uses either secureJsonData or the plain fields depending on the datasource.
  • Non core datasources can already use secureJsonData for storage.

What this PR does so far:

  • Adds helper methods on Datasource to return plaintext passwords from secureJsonData if exists with fallback to plaintext db columns.
  • Uses this to return plaintext passwords to frontend for browser access datasources.
  • Adds migration that will move passwords from plaintext fields to secureJsonData for core datasources.
  • When core datasource is provisioned, both password or secureJsonData.password can be used and both will save the password in secureJsonData so the format stays the same but the behaviour changes.

After talking to other people it will make more sense to not complicate the code with migration and provisioning changes and instead users with existing datasources can migrate by resaving their datasources or altering their provisioned files. New datasources will be created with encrypted passwords by default.

TODO:

  • Fix existing tests
  • Add unitests
  • Manual testing

@aocenas aocenas changed the title Store datasource passwords ecrypted in secureJsonData [WIP] Store datasource passwords ecrypted in secureJsonData Mar 23, 2019
pkg/plugins/plugins.go Outdated Show resolved Hide resolved
@aocenas aocenas added area/plugins area/security area/backend/config pr/early-feedback WIP state but looking for early feedback pr/needs-manual-testing Before merge some help with manual testing & verification is requested area/backend/plugins area/provisioning add to changelog and removed area/backend/config labels Mar 23, 2019
@aocenas aocenas self-assigned this Mar 25, 2019
@daniellee daniellee changed the title [WIP] Store datasource passwords ecrypted in secureJsonData [WIP] Store datasource passwords encrypted in secureJsonData Mar 26, 2019
@torkelo torkelo changed the title [WIP] Store datasource passwords encrypted in secureJsonData Security: Store datasource passwords encrypted in secureJsonData Apr 2, 2019
@marefr marefr self-requested a review April 3, 2019 12:44
Copy link
Member

@marefr marefr left a comment

Choose a reason for hiding this comment

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

Have left a few comments. Think this is a good start. Haven't tested it yet though.

pkg/models/datasource.go Outdated Show resolved Hide resolved
pkg/services/provisioning/datasources/types.go Outdated Show resolved Hide resolved
pkg/services/sqlstore/migrations/encrypt_passwords.go Outdated Show resolved Hide resolved
pkg/services/provisioning/datasources/config_reader.go Outdated Show resolved Hide resolved
pkg/services/provisioning/datasources/datasources.go Outdated Show resolved Hide resolved
pkg/services/sqlstore/migrations/encrypt_passwords.go Outdated Show resolved Hide resolved
pkg/services/provisioning/datasources/types.go Outdated Show resolved Hide resolved
@marefr marefr requested review from bergquist and xlson April 3, 2019 13:45
@aocenas aocenas removed pr/early-feedback WIP state but looking for early feedback area/provisioning labels Apr 8, 2019
@@ -184,8 +188,8 @@ Secure json data is a map of settings that will be encrypted with [secret key](/
| tlsCACert | string | *All* |CA cert for out going requests |
| tlsClientCert | string | *All* |TLS Client cert for outgoing requests |
| tlsClientKey | string | *All* |TLS Client key for outgoing requests |
| password | string | PostgreSQL | password |
| user | string | PostgreSQL | user |
Copy link
Member Author

Choose a reason for hiding this comment

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

Seems like this was an error. User is taken from user field not from secureJsonData

@@ -135,6 +137,12 @@ func (cfg *DatasourcesAsConfigV1) mapToDatasourceFromConfig(apiVersion int64) *D
Editable: ds.Editable,
Version: ds.Version,
})
if ds.Password != "" {
Copy link
Member Author

Choose a reason for hiding this comment

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

Added warnings here, thought not sure if there won't be too much of them if somebody has a lots of datasources.

@@ -178,6 +178,10 @@ func UpdateDataSource(cmd *m.UpdateDataSourceCommand) error {
sess.UseBool("basic_auth")
sess.UseBool("with_credentials")
sess.UseBool("read_only")
// Make sure password are zeroed out if empty. We do this as we want to migrate passwords from
// plain text fields to SecureJsonData.
sess.MustCols("password")
Copy link
Member Author

@aocenas aocenas Apr 9, 2019

Choose a reason for hiding this comment

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

Interestingly at the moment it is not actually possible to remove values from config. I needed to add these to be able to do that for plain text password, but otherwise no other value can be removed. Probably not a big issue but wondered how to properly handle such things. Should there be something like fieldSet bool when serialising the request? Right now we send the whole object to the API so this should not be an issue, but this won't support a partial PUT requests.

onPasswordChange: ReturnType<typeof createChangeHandler>;

constructor() {
this.onPasswordReset = createResetHandler(this, PasswordFieldEnum.Password);
Copy link
Member Author

Choose a reason for hiding this comment

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

Wanted to reuse the handler logic as it is the same everywhere but my Angular is rusty so this patter was the best I come up with.

@aocenas aocenas added this to the 6.2 milestone Apr 9, 2019
pkg/models/datasource.go Show resolved Hide resolved
pkg/services/provisioning/datasources/config_reader.go Outdated Show resolved Hide resolved
pkg/util/strings.go Outdated Show resolved Hide resolved
Copy link
Contributor

@bergquist bergquist left a comment

Choose a reason for hiding this comment

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

LGTM!

@aocenas aocenas merged commit 66f6e16 into master Apr 15, 2019
@aocenas aocenas deleted the encrypt-passwords branch April 15, 2019 09:11
ryantxu added a commit to ryantxu/grafana that referenced this pull request Apr 15, 2019
* grafana/master:
  Docs: minor docs update for old urls
  Chore: Add more explicit typing (grafana#16594)
  Chore: Lowered implicit anys limit to 5977
  Chore: Adds typings to lodash (grafana#16590)
  PanelEditor: Change Queries heading to Query (grafana#16536)
  Security: Store datasource passwords encrypted in secureJsonData (grafana#16175)
  More development dashboards (grafana#16550)
  build: upgrades to golang 1.12.4 (grafana#16545)
  Use package libfontconfig1, instead of libfontconfig (grafana#16548)
  Adjust Send on all alerts to default label (grafana#16554)
  Chore: Lower limit of implicit anys to 6676
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
add to changelog area/backend/plugins area/plugins area/security pr/needs-manual-testing Before merge some help with manual testing & verification is requested
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Encrypt Data Source Basic Auth in DB
3 participants