lnd: skip network validation when migrations are skipped
What changed, and why it matters
This change lets LND skip a safety check that prevents accidentally using a database from the wrong Bitcoin network (like mainnet vs testnet) when the user has explicitly told LND to skip SQL database migrations. The check is skipped because the table it reads may not exist in that special setup. This is a deliberate relaxation of a guardrail, not a fix for an attack, and it only affects users who opt into the 'skip migrations' mode.
Treat this as a configuration-aware behavior change rather than a vulnerability. Operators using SkipMigrations should ensure the active network is validated through external schema management or deployment controls. Reviewers may want to confirm that SkipMigrations cannot be enabled unintentionally and that the warning is surfaced in monitoring.
Security signals we found
Guardrail intentionally bypassed under operator-controlled configuration flag
Cross-network database reuse would no longer be detected in skipped-migration mode
Warning emitted to logs when validation is skipped
No input validation, authentication, or cryptographic change
Evidence from the diff
The commit modifies DefaultDatabaseBuilder.BuildDatabase in config_builder.go. Previously, after opening a native SQL backend (SQLite/Postgres), the code always called chainparams.NewStore(baseDB).ValidateNetwork to compare the on-disk chain_params value against the active network parameters. Now it inspects the SkipMigrations flag for the active backend and bypasses ValidateNetwork when migrations are skipped, logging a warning instead. This is intended for deployments where the schema is managed externally and chain_params may not yet exist.
Changed components
lnd/config_builder.goDefaultDatabaseBuilder.BuildDatabaseNative SQL backends (SQLite, Postgres)chainparams.ValidateNetworkInspect captured patch +28 / −8
diff --git a/config_builder.go b/config_builder.go
index a448235..394d379 100644
--- a/config_builder.go
+++ b/config_builder.go
@@ -1248,15 +1248,35 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
// (e.g. mainnet → testnet), which would otherwise lead to
// silent data corruption. This check applies to all native SQL
// backends.
- chainParamsStore := chainparams.NewStore(baseDB)
- err = chainParamsStore.ValidateNetwork(
- ctx, d.cfg.ActiveNetParams.Params,
- )
- if err != nil {
- cleanUp()
- d.logger.Error(err)
+ //
+ // If migrations are explicitly skipped, we also skip this check
+ // because the chain_params table may not exist yet. We check
+ // only the active backend's flag since only one backend is
+ // used at a time.
+ var skipMigrations bool
+ switch d.cfg.DB.Backend {
+ case lncfg.SqliteBackend:
+ skipMigrations = d.cfg.DB.Sqlite.SkipMigrations
+ case lncfg.PostgresBackend:
+ skipMigrations = d.cfg.DB.Postgres.SkipMigrations
+ }
- return nil, nil, err
+ if !skipMigrations {
+ chainParamsStore := chainparams.NewStore(baseDB)
+ err = chainParamsStore.ValidateNetwork(
+ ctx, d.cfg.ActiveNetParams.Params,
+ )
+ if err != nil {
+ cleanUp()
+ d.logger.Error(err)
+
+ return nil, nil, err
+ }
+ } else {
+ d.logger.Warnf("Database network validation skipped " +
+ "because SkipMigrations is enabled; " +
+ "cross-network database reuse would not be " +
+ "detected.")
}
// Create the invoice store.
Why this scored 31/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.