Buyer and security problem
DBML relation and column identifiers eventually participate in generated PostgreSQL DDL. Pull request #719 bundled a broad deny-list validator with an unrelated column-position optimization, frontend dependency drift, and other changes. That validator should not be merged incidentally: PostgreSQL permits quoted identifiers containing spaces and many punctuation characters, while a generic deny-list can both reject legitimate schemas and still miss dialect-specific construction errors.
Required bounded slice
- trace every DBML identifier from parser input through snapshot storage to every SQL/DDL rendering sink;
- keep parsing, canonical representation, and PostgreSQL rendering as separate contracts;
- reject NUL, malformed quoting, unterminated identifiers, excessive UTF-8 byte length, ambiguous path segmentation, and resource-exhaustion inputs fail-closed;
- preserve valid PostgreSQL quoted identifiers, including embedded double quotes represented by doubled quotes;
- never concatenate an unvalidated identifier directly into executable SQL;
- use one dialect-owned identifier quoting/rendering function at every DDL sink, or redesign the sink around a structured AST;
- keep values parameterized wherever bind parameters are legal;
- add realistic tests for ordinary, Unicode, reserved-word, whitespace, embedded-quote, semicolon, comment-marker, NUL, overlength, and multi-segment identifiers;
- prove generated DDL parses as one intended statement and cannot append a second statement or comment out required syntax;
- add fuzz/property tests for parse→canonicalize→render round trips;
- maintain 100% production statement/branch coverage and complete public docstrings;
- update
ARCHITECTURE.md, AGENTS.md or the authoritative security/doctoring record, and CHANGELOG.md.
Acceptance boundary
The performance-only O(N) column-position change proceeds in #746. This issue is a separate security contract and must not reintroduce #719's unrelated frontend lock drift or use a generic character deny-list as the sole defense.
Standards and primary documentation — APA 7th
Open Worldwide Application Security Project. (2026). SQL injection prevention cheat sheet. OWASP Cheat Sheet Series. https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
PostgreSQL Global Development Group. (2026). PostgreSQL 18 documentation: Lexical structure. https://www.postgresql.org/docs/18/sql-syntax-lexical.html
These sources are engineering guidance; no formal compliance claim is made.
Buyer and security problem
DBML relation and column identifiers eventually participate in generated PostgreSQL DDL. Pull request #719 bundled a broad deny-list validator with an unrelated column-position optimization, frontend dependency drift, and other changes. That validator should not be merged incidentally: PostgreSQL permits quoted identifiers containing spaces and many punctuation characters, while a generic deny-list can both reject legitimate schemas and still miss dialect-specific construction errors.
Required bounded slice
ARCHITECTURE.md,AGENTS.mdor the authoritative security/doctoring record, andCHANGELOG.md.Acceptance boundary
The performance-only O(N) column-position change proceeds in #746. This issue is a separate security contract and must not reintroduce #719's unrelated frontend lock drift or use a generic character deny-list as the sole defense.
Standards and primary documentation — APA 7th
Open Worldwide Application Security Project. (2026). SQL injection prevention cheat sheet. OWASP Cheat Sheet Series. https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
PostgreSQL Global Development Group. (2026). PostgreSQL 18 documentation: Lexical structure. https://www.postgresql.org/docs/18/sql-syntax-lexical.html
These sources are engineering guidance; no formal compliance claim is made.