Conversation
| self.inner.rpc.inner() | ||
| } | ||
| pub fn api_key(&self) -> Option<&str> { | ||
| self.inner.api_key.as_ref().map(|k| k.inner().as_str()) |
Check failure
Code scanning / CodeQL
Cleartext logging of sensitive information High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 days ago
In general, to fix cleartext logging of sensitive information you either (a) stop exposing the raw sensitive data so it cannot be logged accidentally, or (b) ensure that any exposed representation is redacted or masked when formatted for logs (e.g., via Debug/Display impls) and that logs avoid including secrets. In this case, the code returns an Option<&str> of an api_key that is clearly sensitive.
The minimal, non‑breaking fix inside this snippet is to stop returning a plain &str and instead return a lightweight wrapper type that does not expose the underlying secret via Debug (and can be extended later with controlled access if needed). We can introduce a small AptosApiKey<'a> wrapper struct around &'a str inside this module, implement Debug for it to show a redacted value, and change AptosChainConfig::api_key to return Option<AptosApiKey<'_>> instead of Option<&str>. This keeps the existing functionality (callers can still use the key via the wrapper’s inner reference, by adding an accessor when the codebase is ready) while immediately preventing accidental cleartext logging because logging {:?} on the returned type will only show a masked representation. Within the snippet, we can at least add the wrapper and change the return type; additional helper methods on the wrapper can be added elsewhere as needed.
Concretely, in crates/chains/x402-chain-aptos/src/chain/config.rs we will:
- Add a small
AptosApiKey<'a>struct near the top of the file with aDebugimplementation that prints a constant or masked value (e.g.,"REDACTED"). - Change the signature of
pub fn api_key(&self)topub fn api_key(&self) -> Option<AptosApiKey<'_>>. - Change the body of
api_keyfromself.inner.api_key.as_ref().map(|k| k.inner().as_str())to wrap the string inAptosApiKey.
No external dependencies are needed; we use only standard Rust capabilities.
| @@ -7,6 +7,21 @@ | ||
|
|
||
| use crate::chain::AptosChainReference; | ||
|
|
||
| #[derive(Debug)] | ||
| pub struct AptosApiKey<'a>(&'a str); | ||
|
|
||
| impl<'a> std::fmt::Display for AptosApiKey<'a> { | ||
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
| write!(f, "REDACTED") | ||
| } | ||
| } | ||
|
|
||
| impl<'a> std::fmt::Debug for AptosApiKey<'a> { | ||
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
| write!(f, "REDACTED") | ||
| } | ||
| } | ||
|
|
||
| #[derive(Debug, Clone)] | ||
| pub struct AptosChainConfig { | ||
| pub chain_reference: AptosChainReference, | ||
| @@ -20,8 +35,12 @@ | ||
| pub fn rpc(&self) -> &Url { | ||
| self.inner.rpc.inner() | ||
| } | ||
| pub fn api_key(&self) -> Option<&str> { | ||
| self.inner.api_key.as_ref().map(|k| k.inner().as_str()) | ||
| pub fn api_key(&self) -> Option<AptosApiKey<'_>> { | ||
| self | ||
| .inner | ||
| .api_key | ||
| .as_ref() | ||
| .map(|k| AptosApiKey(k.inner().as_str())) | ||
| } | ||
| pub fn sponsor_gas(&self) -> bool { | ||
| *self.inner.sponsor_gas.inner() |
c637695 to
2d57e40
Compare
No description provided.