Conversation
|
|
||
| balance, err := client.AccountAPTBalance(addr) | ||
| if err != nil { | ||
| s.logger.Warnw("failed to get balance for account, skipping", "account", account, "address", addr.String(), "error", err) |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 3 days ago
General approach: avoid logging the potentially sensitive authKey/account address in clear text. Keep logging contextual, non-sensitive data (e.g., the public-key identifier or error) while omitting or redacting the address. Since the functional behavior of the method is independent of logging, we can safely adjust the log message without changing logic.
Best targeted fix: in relayer/aptos_service.go, inside getAccountWithHighestBalance, modify the warning log in the error path of client.AccountAPTBalance(addr) so it no longer logs addr.String(). We can either remove the "address" field entirely or replace it with a redacted placeholder. To be conservative and minimize code changes, we’ll just drop the "address", addr.String() pair. The rest of the log (account identifier and error) remains, so operational debugging is still possible.
Concrete changes:
- File:
relayer/aptos_service.go- In
getAccountWithHighestBalance, adjust line 249 so that theWarnwcall does not includeaddr.String(). - No new imports, methods, or types are required.
- No changes are needed in
relayer/utils/address.go, since the issue is at the logging sink.
- In
| @@ -246,7 +246,7 @@ | ||
|
|
||
| balance, err := client.AccountAPTBalance(addr) | ||
| if err != nil { | ||
| s.logger.Warnw("failed to get balance for account, skipping", "account", account, "address", addr.String(), "error", err) | ||
| s.logger.Warnw("failed to get balance for account, skipping", "account", account, "error", err) | ||
| continue | ||
| } | ||
|
|
|
|
||
| acc := utils.Ed25519PublicKeyToAddress(ed25519PublicKey) | ||
| fromAddress := acc.String() | ||
| a.baseLogger.Infow("TestingAptosWriteCap: EnqueueCRE - resolved from address", "fromAddress", fromAddress) |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
Copilot Autofix
AI 3 days ago
Copilot could not generate an autofix suggestion
Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.
| fromAccountAddress := &aptos.AccountAddress{} | ||
| err = fromAccountAddress.ParseStringRelaxed(fromAddress) | ||
| if err != nil { | ||
| a.baseLogger.Errorw("TestingAptosWriteCap: EnqueueCRE - failed to parse from address", "fromAddress", fromAddress, "error", err) |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 3 days ago
In general, to fix clear-text logging of sensitive information, avoid sending full sensitive values (keys, tokens, auth-related IDs) directly to logging sinks. Instead, either omit them entirely, or log only non-sensitive derivatives (like hashes) or redacted forms (like the last few characters) that are sufficient for correlation and debugging without revealing the full value.
In this case, fromAddress is derived from the auth key and then logged twice: once at info level when resolved, and once in the error log if parsing fails. To retain debuggability while avoiding full clear-text exposure, we can log a redacted version of the address (for example, log only the first 6 and last 4 hex characters) under a different key, such as "fromAddressSuffix" or "fromAddressRedacted". This keeps the logs useful to correlate which address caused an error, but prevents dumping the entire address. Concretely, in relayer/txm/txm.go we should replace the Infow and Errorw calls that pass "fromAddress", fromAddress with ones that pass a redacted representation, implemented inline (simple string slicing) so we don't need new imports or utilities. No other functional behavior of the transaction manager or address utilities needs to change.
Specifically:
- In
relayer/txm/txm.go, around lines 279–286:- After computing
fromAddress := acc.String(), derive a redacted form (e.g.,fromAddressRedacted := redactAddress(fromAddress)implemented inline as local logic). - Update the
Infowcall at line 281 to log"fromAddressRedacted", fromAddressRedactedinstead of the fullfromAddress. - Update the
Errorwcall at line 286 to log the same redacted address instead of the fullfromAddress.
Because we cannot assume other parts of the file, we'll implement the redaction logic directly in the function body as a small helper closure or simple inline code, avoiding new package-level functions and imports.
- After computing
| @@ -278,12 +278,20 @@ | ||
|
|
||
| acc := utils.Ed25519PublicKeyToAddress(ed25519PublicKey) | ||
| fromAddress := acc.String() | ||
| a.baseLogger.Infow("TestingAptosWriteCap: EnqueueCRE - resolved from address", "fromAddress", fromAddress) | ||
|
|
||
| // Redact fromAddress in logs to avoid writing full auth-derived address in clear text. | ||
| fromAddressRedacted := fromAddress | ||
| if len(fromAddress) > 10 { | ||
| // keep first 6 and last 4 characters for correlation | ||
| fromAddressRedacted = fromAddress[:6] + "..." + fromAddress[len(fromAddress)-4:] | ||
| } | ||
|
|
||
| a.baseLogger.Infow("TestingAptosWriteCap: EnqueueCRE - resolved from address", "fromAddressRedacted", fromAddressRedacted) | ||
|
|
||
| fromAccountAddress := &aptos.AccountAddress{} | ||
| err = fromAccountAddress.ParseStringRelaxed(fromAddress) | ||
| if err != nil { | ||
| a.baseLogger.Errorw("TestingAptosWriteCap: EnqueueCRE - failed to parse from address", "fromAddress", fromAddress, "error", err) | ||
| a.baseLogger.Errorw("TestingAptosWriteCap: EnqueueCRE - failed to parse from address", "fromAddressRedacted", fromAddressRedacted, "error", err) | ||
| return fmt.Errorf("failed to parse from address: %+w", err) | ||
| } | ||
|
|
|
|
||
| select { | ||
| case a.broadcastChan <- transactionID: | ||
| ctxLogger.Infow("TestingAptosWriteCap: EnqueueCRE - tx enqueued to broadcast channel", "fromAddr", fromAddress, "transactionID", transactionID) |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 3 days ago
General fix: avoid logging the full value derived from authKey (fromAddress) in clear text. Either do not log it at all, or log only a redacted/hashed version that is not useful to an attacker but still allows operators to correlate events.
Best concrete fix here:
- Replace the info log that prints
"fromAddress"(line 281) with a version that logs a redacted form of the address (e.g., first 6 and last 4 characters, or just a hash). - In the
ctxLogger.Infowcall on line 325, stop loggingfromAddrentirely (or also use the redacted value). Since theAptosTxis already stored withFromAddress, operators can still correlate bytransactionIDwithout needing the raw address in logs. - Implement a small helper function in
relayer/utils/address.goto redact an address string, and use that intxm.go. This keeps redaction logic centralized and reusable. - Add no new external dependencies; use only standard string operations.
Specifically:
- In
relayer/utils/address.go, add aRedactAddressString(addr string) stringhelper that returns a partially masked address (if the string is long enough) or a constant like"[redacted]"if not. - In
relayer/txm/txm.go:- After computing
fromAddress, computeredactedFromAddress := utils.RedactAddressString(fromAddress)and log only the redacted value in the"resolved from address"log. - In the
ctxLogger.Infow("...tx enqueued..."call, replace"fromAddr", fromAddresswith"fromAddr", redactedFromAddress.
- After computing
This preserves existing behavior except for the content of logs, and avoids emitting the full auth-derived address.
| @@ -278,7 +278,8 @@ | ||
|
|
||
| acc := utils.Ed25519PublicKeyToAddress(ed25519PublicKey) | ||
| fromAddress := acc.String() | ||
| a.baseLogger.Infow("TestingAptosWriteCap: EnqueueCRE - resolved from address", "fromAddress", fromAddress) | ||
| redactedFromAddress := utils.RedactAddressString(fromAddress) | ||
| a.baseLogger.Infow("TestingAptosWriteCap: EnqueueCRE - resolved from address", "fromAddress", redactedFromAddress) | ||
|
|
||
| fromAccountAddress := &aptos.AccountAddress{} | ||
| err = fromAccountAddress.ParseStringRelaxed(fromAddress) | ||
| @@ -322,7 +323,7 @@ | ||
|
|
||
| select { | ||
| case a.broadcastChan <- transactionID: | ||
| ctxLogger.Infow("TestingAptosWriteCap: EnqueueCRE - tx enqueued to broadcast channel", "fromAddr", fromAddress, "transactionID", transactionID) | ||
| ctxLogger.Infow("TestingAptosWriteCap: EnqueueCRE - tx enqueued to broadcast channel", "fromAddr", redactedFromAddress, "transactionID", transactionID) | ||
| default: | ||
| // if the channel is full, we drop the transaction. | ||
| // we do this instead of setting the tx in `a.transactions` post-broadcast to avoid a race |
| @@ -30,6 +30,26 @@ | ||
| return aptos.AccountAddress(authKey) | ||
| } | ||
|
|
||
| // RedactAddressString returns a redacted representation of an address string suitable for logging. | ||
| // It avoids exposing the full authKey-derived address in clear text logs while still allowing | ||
| // basic correlation and debugging. | ||
| func RedactAddressString(addr string) string { | ||
| const redactedPlaceholder = "[redacted]" | ||
| if len(addr) <= 10 { | ||
| // Too short to safely show parts; just indicate redacted. | ||
| return redactedPlaceholder | ||
| } | ||
|
|
||
| prefixLen := 6 | ||
| suffixLen := 4 | ||
| if len(addr) < prefixLen+suffixLen { | ||
| // Fallback in unusual cases. | ||
| return redactedPlaceholder | ||
| } | ||
|
|
||
| return addr[:prefixLen] + "..." + addr[len(addr)-suffixLen:] | ||
| } | ||
|
|
||
| func HexPublicKeyToAddress(key string) (aptos.AccountAddress, error) { | ||
| publicKey, err := HexPublicKeyToEd25519PublicKey(key) | ||
| if err != nil { |
TODO:
smartcontractkit/chainlink#21431