Skip to content

Commit 30ada75

Browse files
feat(sdk-core): add custom logger with sensitive data sanitization
Implements custom logger to prevent token exposure in test/staging environments. Replaced 111 console statements across 52 files with logger that redacts sensitive keys (token, bearer, prv, privatekey, password, otp) and v2x bearer tokens. Technical changes: - Created sanitizeLog.ts with recursive sanitization (O(1) Set lookups) - Created logger.ts with conditional sanitization (test/staging only) - Exported logger from sdk-core for SDK-wide access - Updated 52 files across express, sdk-core, sdk-api, abstract, coin, and utility modules Ticket: WP-7503
1 parent 7cd76fc commit 30ada75

55 files changed

Lines changed: 764 additions & 126 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

modules/abstract-eth/src/abstractEthLikeNewCoins.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
InvalidAddressVerificationObjectPropertyError,
1919
IWallet,
2020
KeyPair,
21+
logger,
2122
MPCSweepRecoveryOptions,
2223
MPCSweepTxs,
2324
MPCTx,
@@ -1332,7 +1333,7 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
13321333
);
13331334
possibleConsolidationAddresses.push(forwarderAddress);
13341335
} catch (e) {
1335-
console.log(`Failed to generate forwarder address: ${e.message}`);
1336+
logger.info(`Failed to generate forwarder address: ${e.message}`);
13361337
}
13371338
}
13381339

@@ -1341,7 +1342,7 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
13411342
const derivedAddress = this.deriveAddressFromPublicKey(params.userKey, index);
13421343
possibleConsolidationAddresses.push(derivedAddress);
13431344
} catch (e) {
1344-
console.log(`Failed to generate derived address: ${e}`);
1345+
logger.info(`Failed to generate derived address: ${e}`);
13451346
}
13461347
}
13471348

@@ -3442,7 +3443,7 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
34423443
apiKey
34433444
);
34443445
const gasPrice = new BN(res.result.slice(2), 16);
3445-
console.log(` Got gas price: ${gasPrice}`);
3446+
logger.info(` Got gas price: ${gasPrice}`);
34463447
return gasPrice;
34473448
} catch (e) {
34483449
throw new Error(`Failed to get gas price. Please make sure to use the api key of ${wrongChainCoin}`);
@@ -3477,7 +3478,7 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
34773478
apiKey
34783479
);
34793480
const gasLimit = new BN(res.result.slice(2), 16);
3480-
console.log(`Got gas limit: ${gasLimit}`);
3481+
logger.info(`Got gas limit: ${gasLimit}`);
34813482
return gasLimit;
34823483
} catch (e) {
34833484
throw new Error(

modules/abstract-utxo/src/abstractUtxoCoin.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
IWallet,
2121
KeychainsTriplet,
2222
KeyIndices,
23+
logger,
2324
MismatchedRecipient,
2425
MultisigType,
2526
multisigTypes,
@@ -556,7 +557,7 @@ export abstract class AbstractUtxoCoin
556557
return decodePsbtWith(input, this.name, decodeWith);
557558
} else {
558559
if (decodeWith !== 'utxolib') {
559-
console.error('received decodeWith hint %s, ignoring for legacy transaction', decodeWith);
560+
logger.error('received decodeWith hint %s, ignoring for legacy transaction', decodeWith);
560561
}
561562
return utxolib.bitgo.createTransactionFromBuffer(input, this.network, {
562563
amountType: this.amountType,
@@ -584,7 +585,7 @@ export abstract class AbstractUtxoCoin
584585
let { decodeWith } = prebuild;
585586
if (decodeWith !== undefined) {
586587
if (typeof decodeWith !== 'string' || !isSdkBackend(decodeWith)) {
587-
console.error('decodeWith %s is not a valid value, using default', decodeWith);
588+
logger.error('decodeWith %s is not a valid value, using default', decodeWith);
588589
decodeWith = undefined;
589590
}
590591
}

modules/abstract-utxo/src/recovery/backupKeyRecovery.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
getIsUnsignedSweep,
1010
isTriple,
1111
krsProviders,
12+
logger,
1213
} from '@bitgo/sdk-core';
1314
import { getMainnet, networks } from '@bitgo/utxo-lib';
1415
import { fixedScriptWallet } from '@bitgo/wasm-utxo';
@@ -164,7 +165,7 @@ async function queryBlockchainUnspentsPath(
164165
numSequentialAddressesWithoutTxs = 0;
165166

166167
if (addrInfo.balance > 0) {
167-
console.log(`Found an address with balance: ${formattedAddress} with balance ${addrInfo.balance}`);
168+
logger.info(`Found an address with balance: ${formattedAddress} with balance ${addrInfo.balance}`);
168169
const addressUnspents = await recoveryProvider.getUnspentsForAddresses([formattedAddress]);
169170
const processedUnspents = await Promise.all(
170171
addressUnspents.map(async (u): Promise<WalletUnspent<bigint>> => {

modules/abstract-utxo/src/recovery/crossChainRecovery.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as utxolib from '@bitgo/utxo-lib';
22
import { BIP32Interface, bip32 } from '@bitgo/secp256k1';
33
import { Dimensions } from '@bitgo/unspents';
44
import { CoinName, fixedScriptWallet } from '@bitgo/wasm-utxo';
5-
import { BitGoBase, IWallet, Keychain, Triple, Wallet } from '@bitgo/sdk-core';
5+
import { BitGoBase, IWallet, Keychain, logger, Triple, Wallet } from '@bitgo/sdk-core';
66
import { decrypt } from '@bitgo/sdk-api';
77

88
import { AbstractUtxoCoin, TransactionInfo } from '../abstractUtxoCoin';
@@ -262,7 +262,7 @@ async function toWalletUnspents<TNumber extends number | bigint = number>(
262262
try {
263263
scriptId = await getScriptId(recoveryCoin, wallet, utxolib.address.toOutputScript(address, sourceCoin.network));
264264
} catch (e) {
265-
console.error(`error getting scriptId for ${address}:`, e);
265+
logger.error(`error getting scriptId for ${address}:`, e);
266266
continue;
267267
}
268268
const filteredUnspents = unspents

modules/abstract-utxo/src/transaction/fixedScript/explainTransaction.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as utxolib from '@bitgo/utxo-lib';
22
import { bip322 } from '@bitgo/utxo-core';
33
import { BIP32Interface, bip32 } from '@bitgo/secp256k1';
44
import { bitgo } from '@bitgo/utxo-lib';
5-
import { ITransactionExplanation as BaseTransactionExplanation, Triple } from '@bitgo/sdk-core';
5+
import { ITransactionExplanation as BaseTransactionExplanation, logger, Triple } from '@bitgo/sdk-core';
66
import * as utxocore from '@bitgo/utxo-core';
77

88
import type { Bip322Message } from '../../abstractUtxoCoin';
@@ -398,7 +398,7 @@ export function explainPsbt(
398398
if (strict) {
399399
throw e;
400400
}
401-
console.error(e);
401+
logger.error(e);
402402
}
403403
}
404404

modules/abstract-utxo/src/transaction/fixedScript/parseOutput.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
IRequestTracer,
66
InvalidAddressDerivationPropertyError,
77
IWallet,
8+
logger,
89
TransactionPrebuild,
910
UnexpectedAddressError,
1011
VerificationOptions,
@@ -154,8 +155,8 @@ async function handleVerifyAddressError({
154155
return { external: false };
155156
}
156157

157-
console.error('Address classification failed for address', currentAddress);
158-
console.trace(e);
158+
logger.error('Address classification failed for address', currentAddress);
159+
logger.error(e);
159160
/**
160161
* It might be a completely invalid address or a bad validation attempt or something else completely, in
161162
* which case we do not proceed and rather rethrow the error, which is safer than assuming that the address

modules/abstract-utxo/src/transaction/fixedScript/verifyTransaction.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import buildDebug from 'debug';
22
import _ from 'lodash';
33
import BigNumber from 'bignumber.js';
4-
import { BitGoBase, TxIntentMismatchError, IBaseCoin } from '@bitgo/sdk-core';
4+
import { BitGoBase, logger, TxIntentMismatchError, IBaseCoin } from '@bitgo/sdk-core';
55
import * as utxolib from '@bitgo/utxo-lib';
66

77
import { AbstractUtxoCoin, VerifyTransactionOptions } from '../../abstractUtxoCoin';
@@ -106,7 +106,7 @@ export async function verifyTransaction<TNumber extends bigint | number>(
106106
} else if (!disableNetworking) {
107107
// these keys were obtained online and their signatures were not verified
108108
// this could be dangerous
109-
console.log('unsigned keys obtained online are being used for address verification');
109+
logger.info('unsigned keys obtained online are being used for address verification');
110110
}
111111

112112
if (parsedTransaction.needsCustomChangeKeySignatureVerification) {

modules/abstract-utxo/src/verifyKey.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import buildDebug from 'debug';
99
import * as utxolib from '@bitgo/utxo-lib';
1010
import { bip32 } from '@bitgo/secp256k1';
1111
import * as bitcoinMessage from 'bitcoinjs-message';
12-
import { BitGoBase, decryptKeychainPrivateKey, KeyIndices } from '@bitgo/sdk-core';
12+
import { BitGoBase, decryptKeychainPrivateKey, KeyIndices, logger } from '@bitgo/sdk-core';
1313

1414
import { VerifyKeySignaturesOptions, VerifyUserPublicKeyOptions } from './abstractUtxoCoin';
1515
import { ParsedTransaction } from './transaction/types';
@@ -126,7 +126,7 @@ export function verifyUserPublicKey(bitgo: BitGoBase, params: VerifyUserPublicKe
126126
if (!userPrv) {
127127
const errorMessage = 'user private key unavailable for verification';
128128
if (disableNetworking) {
129-
console.log(errorMessage);
129+
logger.info(errorMessage);
130130
return false;
131131
} else {
132132
throw new Error(errorMessage);

modules/account-lib/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
BaseMessageBuilderFactory,
1111
BuildMessageError,
1212
MessageStandardType,
13+
logger,
1314
} from '@bitgo/sdk-core';
1415
import { BaseCoin as CoinConfig, CoinFeature, coins } from '@bitgo/statics';
1516
export { Ed25519BIP32, Eddsa };
@@ -456,7 +457,7 @@ export async function verifyMessage(
456457
const message = await messageBuilder.build();
457458
return await message.verifyEncodedPayload(messageEncoded, metadata);
458459
} catch (e) {
459-
console.error(`Error verifying message for coin ${coinName}:`, e);
460+
logger.error(`Error verifying message for coin ${coinName}:`, e);
460461
return false;
461462
}
462463
}

modules/blockapis/src/BaseHttpClient.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { logger } from '@bitgo/sdk-core';
12
import * as superagent from 'superagent';
23

34
export class ApiRequestError extends Error {
@@ -64,7 +65,7 @@ export class BaseHttpClient implements HttpClient {
6465
try {
6566
response = await superagent(method, url).send(requestBody as Record<string, unknown>);
6667
} catch (e) {
67-
console.error(e);
68+
logger.error(e);
6869
throw new ApiRequestError(url, e as Error);
6970
}
7071
if (!response.ok) {

0 commit comments

Comments
 (0)