Remove path from error message
What changed, and why it matters
This commit removes file paths from error messages shown to users when Monero transactions fail. The change prevents error messages from leaking internal source-code locations (like which C++ file and line number caused the error), which could help attackers learn about the app's internal structure. It also applies the same cleanup to more transaction error paths than before.
Treat as a minor hardening improvement. Review whether any other user-facing error paths in the Monero and other coin APIs still expose source paths or internal stack traces, and apply consistent sanitization. No urgent action required.
Security signals we found
Information disclosure reduction: source file paths and line numbers removed from user-facing error messages
Expanded sanitization coverage: multi-destination and commit transaction errors now also filtered
No functional transaction logic changed; only error-message formatting
Evidence from the diff
A new helper _formatTransactionError() strips C/C++ source file paths and line numbers from error strings using a regex before displaying them. It also preserves the existing ‘RPC error’ rewrite. The helper is now applied to three transaction-related error paths (createTransactionSync, createTransactionMultDest, and commitTransaction) instead of only one, reducing information disclosure in exception messages.
Changed components
cw_monero/lib/api/transaction_history.dartMonero transaction creation and commit error handlingInspect captured patch +16 / −7
diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart
index fd600414..877f0a91 100644
--- a/cw_monero/lib/api/transaction_history.dart
+++ b/cw_monero/lib/api/transaction_history.dart
@@ -17,6 +17,19 @@ import 'package:monero/src/generated_bindings_monero.g.dart' as monero_gen;
import 'package:mutex/mutex.dart';
+String _formatTransactionError(String error) {
+ final message = error.replaceAll(
+ RegExp(
+ r'(?:[A-Za-z]:)?[\\/][^\s:]*\.(?:c|cc|cpp|cxx|h|hpp|hxx):\d+:(?:[A-Za-z0-9_]+:)?\s*',
+ ),
+ '',
+ );
+ if (message.contains("RPC error")) {
+ return "Invalid node response, please try again or switch node\n\ntrace: $message";
+ }
+ return message;
+}
+
Map<int, Map<String, String>> txKeys = {};
String getTxKey(String txId) {
txKeys[currentWallet!.ffiAddress()] ??= {};
@@ -184,11 +197,7 @@ Future<PendingTransactionDescription> createTransactionSync(
})();
if (error != null) {
- String message = error;
- if (message.contains("RPC error")) {
- message = "Invalid node response, please try again or switch node\n\ntrace: $message";
- }
- throw CreationTransactionException(message: message);
+ throw CreationTransactionException(message: _formatTransactionError(error));
}
final rAmt = pendingTx.amount();
@@ -237,7 +246,7 @@ Future<PendingTransactionDescription> createTransactionMultDest(
final Wallet2PendingTransaction tx = MoneroPendingTransaction(txptr);
if (tx.status() != 0) {
- throw CreationTransactionException(message: tx.errorString());
+ throw CreationTransactionException(message: _formatTransactionError(tx.errorString()));
}
return PendingTransactionDescription(
@@ -282,7 +291,7 @@ Future<String?> commitTransaction({required Wallet2PendingTransaction tx, requir
}
if (error != null && error != "no tx keys found for this txid") {
- throw CreationTransactionException(message: error);
+ throw CreationTransactionException(message: _formatTransactionError(error));
}
unawaited(() async {
storeSync(force: true);
Why this scored 37/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.