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

fix(core): censor novel secrets in querystring #526

Merged
merged 1 commit into from
Apr 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions packages/core/src/tools/create-logger.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const { Transform } = require('stream');
const { parse: querystringParse } = require('querystring');

const _ = require('lodash');

Expand All @@ -18,7 +19,10 @@ const {
recurseExtract,
} = require('@zapier/secret-scrubber');
// not really a public function, but it came from here originally
const { isUrlWithSecrets } = require('@zapier/secret-scrubber/lib/convenience');
const {
isUrlWithSecrets,
isSensitiveKey,
} = require('@zapier/secret-scrubber/lib/convenience');

// The payload size per request to stream logs. This should be slighly lower
// than the limit (16 MB) on the server side.
Expand Down Expand Up @@ -124,7 +128,13 @@ const buildSensitiveValues = (event, data) => {
const authData = bundle.authData || {};
// for the most part, we should censor all the values from authData
// the exception is safe urls, which should be filtered out - we want those to be logged
// but, we _should_ censor-no-matter-what sensitive keys, even if their value is a safe url
Copy link
Contributor Author

Choose a reason for hiding this comment

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

weirdly, the logger.safe urls test was failing for me locally, but not in CI in the last PR. Bumping secret-scrubber locally didn't seem to change that. Not sure why CI didn't flag anything ¯\_(ツ)_/¯

Copy link
Member

Choose a reason for hiding this comment

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

That's odd. It passes for me locally. Just curious, what's your failing message?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right? Weirdest thing.

Running yarn main-tests -g "safe urls" in core directory gives:

      -      "password": "https://a-url-like.password.com"
      +      "password": ":censored:31:0dbc81268a:"

Same thing happens when running the full suite.

It sort of makes sense- the value is a url and doesn't have basic auth or a querystring. So I'm not sure why the test passed before. But, I think the current behavior is what we want. If something is explicitly a sensitive key, we should censor it. If it's not (but is in auth data), it's probably safe.

// this covers the case where someone's password is a valid url ¯\_(ツ)_/¯
const sensitiveAuthData = recurseExtract(authData, (key, value) => {
if (isSensitiveKey(key)) {
return true;
}

if (isUrl(value) && !isUrlWithSecrets(value)) {
return false;
}
Expand All @@ -145,7 +155,9 @@ const buildSensitiveValues = (event, data) => {
result.push(...attemptFindSecretsInStr(data[prop]));
}
}

if (data.request_params) {
result.push(...findSensitiveValues(querystringParse(data.request_params)));
}
// unique- no point in duplicates
return [...new Set(result)];
};
Expand Down
29 changes: 20 additions & 9 deletions packages/core/test/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,29 @@ const {
} = require('../src/http-middlewares/after/log-response');

// little helper to prepare a req/res pair like the http logger does
const prepareTestRequest = (reqBody = {}, resBody = {}) =>
const prepareTestRequest = ({
reqBody = {},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Declaring params like this make them mostly function like python kwargs

resBody = {},
reqQueryParams = '',
} = {}) =>
prepareRequestLog(
{
url: 'http://example.com',
url: `http://example.com${
reqQueryParams ? '?' + querystring.stringify(reqQueryParams) : ''
}`,
method: 'POST',
headers: {
accept: 'application/json',
},
// we usually stringify this in prepare-request.coerceBody, so mirror that behavior here
body: JSON.stringify(reqBody),
},
{
status: 200,
headers: {
'content-type': 'application/json',
},
// we stringify this in prepare-request.coerceBody

content: resBody,
}
);
Expand Down Expand Up @@ -250,17 +257,18 @@ describe('logger', () => {
};
const logger = createlogger({ bundle }, options);

const { message, data } = prepareTestRequest(
{
const { message, data } = prepareTestRequest({
reqBody: {
// value appears only here; logger needs to parse this out of a string to censor it properly
access_token: 'super_secret',
refresh_token: bundle.authData.refresh_token,
},
{
resBody: {
// same here
access_token: 'some new token',
}
);
},
reqQueryParams: { api_key: 'secret-key' },
});

logger(message, data);
const response = await logger.end();
Expand All @@ -273,6 +281,7 @@ describe('logger', () => {
log_type: 'http',
request_type: 'devplatform-outbound',
request_url: 'http://example.com',
request_params: 'api_key=:censored:10:ad15d65bcc:',
request_method: 'POST',
request_headers: 'accept: application/json',
request_data:
Expand All @@ -296,7 +305,9 @@ describe('logger', () => {
const logger = createlogger({ bundle }, options);

const { message, data } = prepareTestRequest({
refresh_token: bundle.authData.refresh_token,
reqBody: {
refresh_token: bundle.authData.refresh_token,
},
});

logger(message, data);
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1590,9 +1590,9 @@
integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==

"@zapier/secret-scrubber@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@zapier/secret-scrubber/-/secret-scrubber-1.0.3.tgz#7b272ec82afdfe501d69d1c6dc046c13597137b1"
integrity sha512-RmQ3c8gh0LMsWWPDyDytn0r4xQJPhfijtd3KP07g7cUuNGLjzYDiuvZU6H21XsGSdcKu90ntcuKq1lifVH2UDg==
version "1.0.6"
resolved "https://registry.yarnpkg.com/@zapier/secret-scrubber/-/secret-scrubber-1.0.6.tgz#d10fa24c3bea1cbf307997337af4d6bc353230fa"
integrity sha512-oaqIMiQ9U0UUd+24UXsx1a+xKmmP5q6SzqwOWpZ51lCS9McvsdEmwCAC6oLf7Q2PApER6At1kbKp1RQ9M5oXTQ==
dependencies:
lodash.isplainobject "^4.0.6"

Expand Down