Repository navigation
fix(security): avoid password leaks on query logs - #5559
Conversation
Signed-off-by: Andres Correa Casablanca <castarco@coderspirit.xyz>
|
Hi @tgriesser & @kibertoad , I'm sorry for adding direct mentions, but I have the feeling that this PR fixes a serious issue, and it can be easy that it gets lost among the dozens of automated PRs produced by bots. |
Signed-off-by: Andres Correa Casablanca <castarco@coderspirit.xyz>
check for object to be defined before accessing property Signed-off-by: Andres Correa Casablanca <castarco@coderspirit.xyz>
Signed-off-by: Andres Correa Casablanca <castarco@coderspirit.xyz>
|
@castarco Thanks for the PR by the way, the error is on the "master" branch and not in your PR. |
|
Thanks @OlivierCavadenti 😃 , I was investigating now what I might have broken. It will save me some time! |
Signed-off-by: Andres Correa Casablanca <castarco@coderspirit.xyz>
|
Any news on whether this will be approved/rejected/merged? From our side it's not urgent, because we are using |
|
@OlivierCavadenti any update on this? |
|
@Eomm sorry for the delay. |
|
Is it possible that this has broken auth in 2.5.0? We've started to get auth issues for the 2.4.0 -> 2.5.0 Knex bump PR in Ghost: https://github.com/TryGhost/Ghost/actions/runs/5505546016/jobs/10033054604?pr=17254#step:11:283 |
|
I'll check. It could be related. |
Thanks ! |
Yes, it looks exactly the same as in my case 😄 |
|
I didn't had time this past night to fix it as I was low on energy, but I was walking through the code and I already have some idea of how to fix it. Hopefully today I'll be able to post a patch. Again, sorry for the disturbance. |
No problem, we all deal with our personal life, do as you can |
|
Hi, But after upgrading to v2.5.0, it fails with the error: So what's your suggestion for injecting the password? This is my knexfile.ts : import * as process from 'process';
require('ts-node/register');
import config from 'config';
export interface KnexConfig {
// knex fields
}
const originalConfig: KnexConfig = config.get('postgres');
// Create a new object with the modified password value
const postgres: KnexConfig = {
...originalConfig,
connection: {
...originalConfig.connection,
password: process.env.PG_PASSWORD,
},
};
export default postgres;Does it makes sense? |
|
Just as a note, this broke our integrations tests since we now cannot reuse the same object with the configurations between scenarios. We have to clone the object for each instantiation of knex otherwise we get Easy fix on our side, but just registering here so other might know. |
knex#5559 adjusted makeKnex to store the `password` property as non-enumerable. As a consequence, tape's `t.deepEqual` was failing when comparing the rendered config with the expectation. In the "parse connection string" test, I added an extra expectation to ensure the password was indeed correctly extracted from the connection string. In the other tests, I just removed the password property from the expectation, since they aren't testing the password specifically and we're already covered on that front.
* Update test to match both old and new error descriptions I'm assuming this test used to pass, but the error message I get from the version of oracle using the documented setup includes "or closed". Change to a regex that matches either. * MSSQL: Drop "test" table before each run For some reason, the "afterEach" hook is not enough to leave the database clean of this table which is used in the "column default handling" tests. Ensure it's removed before running the tests. * General: Drop extra integration test tables in cleanup In Oracle, dropping the "accounts" table was failing because it was referenced by the "test_foreign_table_two" table (which is created in the schema/misc tests). Ensure it is dropped so that accounts can be dropped as expected. I also identified "check_test" as another table being created by raw tests (and not the tableCreatorHelper code) and added it to the list of tables to clean up. * MySQL: ensure query contents are unique for timeout tests The last timeout test, which abandons the connection, was leaving the sleep query running. Since both "mysql" and "mysql2" drivers are connecting to the same database for integration testing, when both were executed in the same test run, some "mysql2" tests were seeing these hanging queries and failing, when they were actually started by a different test against a different database client. I added comments to the queries to ensure that they are unique per-test and per-driver, so that the timeout tests are only asserting against their own queries. * Use a proper port number for connection string parse assertions `parse-connection.js`'s `tryParse` uses `new URL` to parse URLs. Even though the "port" property of a URL instance is a string, the string is of a non-zero-prefixed integer. These tests were failing since they asserted that "0000" parsed to "0000", but in actuality they parsed to "0". Rather than adjust the test to expect "0", I changed the port to something that would result in the same thing as the input; that way, we're not testing the behavior of the URL constructor's parsing, but just that what _we_ care about is true (the port supplied in the connection string becomes the value in the object) * Fix assertions for non-enumerable password property of connection config #5559 adjusted makeKnex to store the `password` property as non-enumerable. As a consequence, tape's `t.deepEqual` was failing when comparing the rendered config with the expectation. In the "parse connection string" test, I added an extra expectation to ensure the password was indeed correctly extracted from the connection string. In the other tests, I just removed the password property from the expectation, since they aren't testing the password specifically and we're already covered on that front. * Exclude `better-sqlite3` from the db-setup tests too `sqlite3` was already excluded, because it succeeds always. I assume `better-sqlite3` was added later but not excluded from this test.
* Update test to match both old and new error descriptions I'm assuming this test used to pass, but the error message I get from the version of oracle using the documented setup includes "or closed". Change to a regex that matches either. * MSSQL: Drop "test" table before each run For some reason, the "afterEach" hook is not enough to leave the database clean of this table which is used in the "column default handling" tests. Ensure it's removed before running the tests. * General: Drop extra integration test tables in cleanup In Oracle, dropping the "accounts" table was failing because it was referenced by the "test_foreign_table_two" table (which is created in the schema/misc tests). Ensure it is dropped so that accounts can be dropped as expected. I also identified "check_test" as another table being created by raw tests (and not the tableCreatorHelper code) and added it to the list of tables to clean up. * MySQL: ensure query contents are unique for timeout tests The last timeout test, which abandons the connection, was leaving the sleep query running. Since both "mysql" and "mysql2" drivers are connecting to the same database for integration testing, when both were executed in the same test run, some "mysql2" tests were seeing these hanging queries and failing, when they were actually started by a different test against a different database client. I added comments to the queries to ensure that they are unique per-test and per-driver, so that the timeout tests are only asserting against their own queries. * Use a proper port number for connection string parse assertions `parse-connection.js`'s `tryParse` uses `new URL` to parse URLs. Even though the "port" property of a URL instance is a string, the string is of a non-zero-prefixed integer. These tests were failing since they asserted that "0000" parsed to "0000", but in actuality they parsed to "0". Rather than adjust the test to expect "0", I changed the port to something that would result in the same thing as the input; that way, we're not testing the behavior of the URL constructor's parsing, but just that what _we_ care about is true (the port supplied in the connection string becomes the value in the object) * Fix assertions for non-enumerable password property of connection config knex#5559 adjusted makeKnex to store the `password` property as non-enumerable. As a consequence, tape's `t.deepEqual` was failing when comparing the rendered config with the expectation. In the "parse connection string" test, I added an extra expectation to ensure the password was indeed correctly extracted from the connection string. In the other tests, I just removed the password property from the expectation, since they aren't testing the password specifically and we're already covered on that front. * Exclude `better-sqlite3` from the db-setup tests too `sqlite3` was already excluded, because it succeeds always. I assume `better-sqlite3` was added later but not excluded from this test.
Motivation:
We detected that under certain conditions, passwords could be leaked through logs, when executing code such as:
In our case, the logger was
Pino, this problem doesn't necessarily happen with other loggers (as they might use differentserialisation methods).
Fixes:
Changes: