escape backticks in schema name for drop schema statement
What changed, and why it matters
This commit fixes a bug where a wallet name containing a backtick character could break or manipulate the SQL command used to delete a wallet account. The fix both prevents users from typing backticks into wallet names and safely escapes any backtick that already exists before running the database command. This is a defensive hardening change rather than a confirmed remote attack.
Review whether other dynamic schema/table/column identifiers built from wallet names are similarly quoted and escaped. Prefer using the database's built-in identifier-quoting APIs or bound identifiers rather than string concatenation for SQL identifiers.
Security signals we found
SQL identifier escaping hardening in DROP SCHEMA
Backtick character added to wallet-name sanitization regex
Backtick doubling applied to existing schema names before SQL execution
No vendor security advisory or CVE referenced in commit
Evidence from the diff
The patch addresses SQL identifier escaping in a DROP SCHEMA statement. Wallet names are used as H2 schema names, and the code previously quoted the schema name with backticks but did not escape embedded backticks. A wallet name containing a backtick could prematurely terminate the identifier, altering the SQL syntax. The change (1) adds backtick to the regex of forbidden characters in WalletNameDialog so new names cannot contain it, and (2) escapes any existing backtick by doubling it before constructing the DROP SCHEMA string. This is a partial fix because it hardens one specific statement rather than moving to parameterized/identifier-binding APIs.
Changed components
WalletNameDialog.javaDbPersistence.javaInspect captured patch +2 / −2
diff --git a/src/main/java/com/sparrowwallet/sparrow/control/WalletNameDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/WalletNameDialog.java
index 7971771..7956714 100644
--- a/src/main/java/com/sparrowwallet/sparrow/control/WalletNameDialog.java
+++ b/src/main/java/com/sparrowwallet/sparrow/control/WalletNameDialog.java
@@ -73,7 +73,7 @@ public class WalletNameDialog extends Dialog<WalletNameDialog.NameAndBirthDate>
name = (CustomTextField)TextFields.createClearableTextField();
name.setText(initialName);
name.setTextFormatter(new TextFormatter<>((change) -> {
- change.setText(change.getText().replaceAll("[\\\\/:*?\"<>|;]", "_"));
+ change.setText(change.getText().replaceAll("[\\\\/:*?\"<>|;`]", "_"));
return change;
}));
content.getChildren().add(name);
diff --git a/src/main/java/com/sparrowwallet/sparrow/io/db/DbPersistence.java b/src/main/java/com/sparrowwallet/sparrow/io/db/DbPersistence.java
index d93494c..3567491 100644
--- a/src/main/java/com/sparrowwallet/sparrow/io/db/DbPersistence.java
+++ b/src/main/java/com/sparrowwallet/sparrow/io/db/DbPersistence.java
@@ -215,7 +215,7 @@ public class DbPersistence implements Persistence {
WalletDao walletDao = handle.attach(WalletDao.class);
try {
if(dirtyPersistables.deleteAccount && !wallet.isMasterWallet()) {
- handle.execute("drop schema `" + getSchema(wallet) + "` cascade");
+ handle.execute("drop schema `" + getSchema(wallet).replace("`", "``") + "` cascade");
return;
}
Why this scored 59/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.