feat: adding examples for soroban gas abstraction#249
Conversation
| console.log('\n📦 Step 1: Creating Soroban contract invocation XDR...'); | ||
| console.log(` Contract: ${CONTRACT_ADDRESS}`); | ||
| console.log(` Function: ${FUNCTION_NAME}`); | ||
| console.log(` User: ${USER_ACCOUNT}`); |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 6 months ago
In general, to fix clear-text logging issues you either stop logging the sensitive value entirely or log only a safe, non-sensitive derivative (e.g., a truncated or hashed form) while keeping enough context for debugging. You also avoid dumping complex structures that may contain secrets, such as full environment objects.
For this specific code, the minimal, non-breaking fix is to stop printing the full USER_ACCOUNT value. Since it is only used for informational output and not for logic, we can either remove the line or replace it with a redacted version. A good balance is to log a short, non-reversible fingerprint (e.g., the first few and last few characters with the middle masked), which allows developers to distinguish accounts without exposing the full identifier. This only requires changing the console.log call around line 80 in examples/relayers/stellar/src/soroban/buildSorobanGasAbstraction.ts. No new imports or helper functions are strictly necessary: we can construct the redacted string inline, keeping the rest of the script unchanged.
Concretely, change:
console.log(` User: ${USER_ACCOUNT}`);to something like:
const redactedUser =
USER_ACCOUNT.length > 10
? `${USER_ACCOUNT.slice(0, 4)}...${USER_ACCOUNT.slice(-4)}`
: '[redacted]';
console.log(` User: ${redactedUser}`);This preserves debugging utility (you still see which account in a recognizable way) while avoiding logging the full environment-derived value.
| @@ -77,7 +77,11 @@ | ||
| console.log('\n📦 Step 1: Creating Soroban contract invocation XDR...'); | ||
| console.log(` Contract: ${CONTRACT_ADDRESS}`); | ||
| console.log(` Function: ${FUNCTION_NAME}`); | ||
| console.log(` User: ${USER_ACCOUNT}`); | ||
| const redactedUser = | ||
| USER_ACCOUNT.length > 10 | ||
| ? `${USER_ACCOUNT.slice(0, 4)}...${USER_ACCOUNT.slice(-4)}` | ||
| : '[redacted]'; | ||
| console.log(` User: ${redactedUser}`); | ||
|
|
||
| const unsignedXdr = await createSorobanInvocationXdr({ | ||
| server, |
| console.log('\n📦 Step 1: Creating Soroban contract invocation XDR...'); | ||
| console.log(` Contract: ${CONTRACT_ADDRESS}`); | ||
| console.log(` Function: ${FUNCTION_NAME}`); | ||
| console.log(` User: ${USER_ACCOUNT}`); |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 6 months ago
In general, to fix clear-text logging of sensitive information, avoid logging raw values that originate from environment variables or other sensitive sources. If the information is needed for diagnostics, log only non-sensitive derivatives (e.g., an obfuscated version, a short hash, or truncated form) that cannot be used to reconstruct the original value.
For this specific case, the minimal-impact fix is to stop logging the full USER_ACCOUNT value on line 79 and instead log either nothing about the user or a redacted/truncated representation. That preserves functionality (the environment variable is still used for the API call and XDR creation) while removing the clear-text exposure in logs. A straightforward approach is to create a local redacted string derived from USER_ACCOUNT (e.g., show only the first and last few characters) and log that instead. This change is limited to the main function in examples/relayers/stellar/src/soroban/quoteSorobanGasAbstraction.ts and does not require any new imports or modifications elsewhere.
Concretely:
- Modify the block around line 79 so that
console.log(\User: ${USER_ACCOUNT}`);is replaced with logic that computes a redacted representation and logs that instead, such asconsole.log(` User: ${redactedUserAccount}`);`. - Implement the redaction inline using basic string operations to avoid new dependencies (e.g., show only 4 starting and 4 ending characters when length permits), ensuring we do not accidentally expose the full value.
| @@ -76,7 +76,11 @@ | ||
| console.log('\n📦 Step 1: Creating Soroban contract invocation XDR...'); | ||
| console.log(` Contract: ${CONTRACT_ADDRESS}`); | ||
| console.log(` Function: ${FUNCTION_NAME}`); | ||
| console.log(` User: ${USER_ACCOUNT}`); | ||
| const redactedUserAccount = | ||
| USER_ACCOUNT.length > 10 | ||
| ? `${USER_ACCOUNT.slice(0, 4)}...${USER_ACCOUNT.slice(-4)}` | ||
| : '[redacted]'; | ||
| console.log(` User: ${redactedUserAccount}`); | ||
|
|
||
| const unsignedXdr = await createSorobanInvocationXdr({ | ||
| server, |
| console.log('\n🔨 Building Soroban invocation transaction...'); | ||
| console.log(` Contract: ${contractAddress}`); | ||
| console.log(` Function: ${functionName}`); | ||
| console.log(` Source Account: ${sourceAccount}`); |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 6 months ago
In general, to fix clear-text logging of sensitive information, you either (a) stop logging the sensitive value entirely, or (b) mask or truncate it so that it can’t be abused if logs are exposed, while still giving some debugging context (e.g., log only a short hash or the last few characters).
For this specific case, the sensitive value is the user account address coming from process.env.USER_ACCOUNT and passed as sourceAccount into createSorobanInvocationXdr. The simplest and safest change that preserves behavior is to avoid logging the full sourceAccount address in utils.ts. Since this is a utility reused by the example scripts, removing or masking this log line in createSorobanInvocationXdr eliminates the clear-text log at the sink CodeQL flagged, without affecting how the transaction is built.
Concretely:
- In
examples/relayers/stellar/src/soroban/utils.ts, adjust theconsole.logon line 72 (console.log(\Source Account: ${sourceAccount}`);`). - Either remove it or replace it with a masked version of the account (e.g., showing only the last 4 characters). To keep some debugging value and clearly avoid full disclosure, we’ll implement masking: log only the last 4 characters and the length of the account string.
- No new imports or additional helper methods are strictly necessary; a small inline masking expression suffices.
No other files need to change, because addressing this sink in utils.ts will cover the variants identified by CodeQL that all flow into this single logging statement.
| @@ -69,7 +69,11 @@ | ||
| console.log('\n🔨 Building Soroban invocation transaction...'); | ||
| console.log(` Contract: ${contractAddress}`); | ||
| console.log(` Function: ${functionName}`); | ||
| console.log(` Source Account: ${sourceAccount}`); | ||
| const maskedSourceAccount = | ||
| typeof sourceAccount === 'string' && sourceAccount.length > 8 | ||
| ? `${sourceAccount.slice(0, 4)}***${sourceAccount.slice(-4)}` | ||
| : '[redacted]'; | ||
| console.log(` Source Account: ${maskedSourceAccount}`); | ||
|
|
||
| // Create the contract instance | ||
| const contract = new Contract(contractAddress); |
Summary
Testing Process
Checklist
npx changeset add)