# Security Policy ## Supported Versions Security and bug fixes target the current minor release. Older minor lines receive security fixes for one minor cycle after the next minor is released; older majors are end-of-life. | Version | Supported | |---------|-----------| | 4.3.x | ✅ Active (current — fixes go here) | | 4.2.x | ✅ Security fixes | | 4.0.x – 4.1.x | ❌ End of life | | 3.x | ❌ End of life | | ≤ 2.x | ❌ End of life | ## Reporting a Vulnerability If you discover a security vulnerability in PgClone, please report it responsibly: 1. **Do not** open a public GitHub issue for security vulnerabilities 2. Email the maintainer directly or use GitHub's private vulnerability reporting feature 3. Include a clear description of the vulnerability and steps to reproduce We will acknowledge your report within 48 hours and provide a timeline for a fix. ## Security Considerations PgClone operates with **superuser** privileges and handles database connections. Users should be aware of the following: ### Connection Strings Connection strings passed to pgclone functions may contain passwords in plaintext. To avoid exposing credentials: - Use `.pgpass` files or the `PGPASSFILE` environment variable instead of inline passwords - Restrict access to pgclone functions to trusted users only - Avoid logging connection strings in application logs As of v4.3.1, pgclone re-parses every source `conninfo` via `PQconninfoParse` and reconnects via `PQconnectdbParams` to inject TCP keepalive defaults (issue #9). The conninfo is never serialised back to a single string for logging or storage, and any password parameter is handled exclusively through libpq's parameter array — never echoed by pgclone at `LOG` level or above. If `PQconninfoParse` itself rejects a malformed conninfo, pgclone propagates only libpq's parser message via `ereport(ERROR, ...)`; pgclone does not directly include the raw conninfo in the error. Operators relying on this property should still use `.pgpass` rather than inline passwords, since libpq's own parser message can in rare malformed-syntax cases include short fragments of the input. ### SQL Injection — WHERE Clause The `"where"` option in JSON parameters is validated against SQL injection patterns (DDL/DML keywords and semicolons are rejected) and executed inside a `READ ONLY` transaction on the source database. This provides two layers of protection: - Only use `WHERE` filters with trusted input - Do not pass user-supplied strings directly into the `"where"` option - The keyword validation and read-only transaction wrapping (v2.2.1) prevent most injection attacks, but defense-in-depth is recommended ### Network Security pgclone connects to remote PostgreSQL instances using `libpq`. Ensure: - Firewall rules restrict which hosts can be reached - Use SSL connections where possible (`sslmode=require` in connection strings) - Source databases should grant minimal required privileges (read-only access is sufficient for cloning) ### Shared Memory Async job state is stored in PostgreSQL shared memory. Job metadata (schema names, table names, progress) is visible to all database users who can call `pgclone_progress()` or query `pgclone_jobs_view`. This is expected behavior but should be considered in multi-tenant environments.