Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/commands/database/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@ export interface ConnectOptions {
json?: boolean
}

function redactConnectionString(connectionString: string): string {
try {
const url = new URL(connectionString)
url.username = ''
url.password = ''
return url.toString()
} catch {
return 'database'
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

export const connect = async (options: ConnectOptions, command: BaseCommand): Promise<void> => {
const buildDir = command.netlify.site.root ?? command.project.root ?? command.project.baseDirectory
if (!buildDir) {
Expand All @@ -26,7 +37,7 @@ export const connect = async (options: ConnectOptions, command: BaseCommand): Pr
return
}

log(`Connected to ${connectionString}`)
log(`Connected to ${redactConnectionString(connectionString)}`)

// --query: one-shot mode
if (options.query) {
Expand Down
11 changes: 11 additions & 0 deletions src/commands/database/db-connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ interface RawDBConnection {
}

export async function connectRawClient(buildDir: string): Promise<RawDBConnection> {
const envConnectionString = process.env.NETLIFY_DB_URL
if (envConnectionString) {
const client = new Client({ connectionString: envConnectionString })
await client.connect()
return {
client,
connectionString: envConnectionString,
cleanup: () => client.end(),
Comment on lines +32 to +35
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Prevent raw NETLIFY_DB_URL credentials from reaching command output

At Line 34, returning envConnectionString as connectionString leaks secrets downstream because connectRawClient callers print this value (see src/commands/database/connect.ts JSON and log paths). Please avoid exposing the raw DSN in returned display fields.

Proposed direction
 export async function connectRawClient(buildDir: string): Promise<RawDBConnection> {
   const envConnectionString = process.env.NETLIFY_DB_URL
   if (envConnectionString) {
     const client = new Client({ connectionString: envConnectionString })
     await client.connect()
     return {
       client,
-      connectionString: envConnectionString,
+      connectionString: redactConnectionString(envConnectionString),
       cleanup: () => client.end(),
     }
   }
// Add near this module (or shared util)
const redactConnectionString = (value: string): string => {
  try {
    const url = new URL(value)
    if (url.password) url.password = '***'
    if (url.username) url.username = '***'
    return url.toString()
  } catch {
    return '[redacted]'
  }
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/database/db-connection.ts` around lines 32 - 35, The returned
response from connectRawClient currently includes the raw envConnectionString in
the connectionString field which leaks secrets; add a redactConnectionString
helper (e.g., function redactConnectionString(value: string): string) in this
module or a shared util that masks username/password (or returns '[redacted]' on
parse failure) and use it when building the returned object so connectionString
returns the redacted value instead of envConnectionString; keep the original
client and cleanup behavior unchanged.

}
}

const state = new LocalState(buildDir)
const storedConnectionString = state.get('dbConnectionString')

Expand Down
Loading