.lagune/memory/charter.md
Treat both sides of every connection as hostile until proven otherwise. Always treat the bytes the application hands the driver (queries and their values) and the bytes the MySQL server sends back (metadata, rows, auth challenges, file requests, keys) as attacker-controlled. Never assume the server is honest or that the network path is private.
Always keep values separate from the query text. Every value that reaches a query MUST travel through the driver's parameterization (prepared statements or placeholders) or its vetted escaping (escape for values, escapeId for names the query cannot parameterize). Never build a query by pasting a raw value into the SQL string, and never weaken, shortcut, or bypass the escaping and parameterization primitives the driver exposes.
The row parsers compile JavaScript at runtime for speed, and they build result objects whose keys are column and table names chosen by the server. Any server-supplied name that is spliced into generated code MUST first pass through the vetted escaper, and any name used as a result-object key MUST be screened against prototype-reaching names (__proto__, constructor, prototype, and the accessor twins). Never interpolate a raw server value into a compiled function, and never assign a server-named key onto a plain object without that screen.
__proto__ used as a key can poison every object in the process, breaking logic far from the query. Both are remote takeover triggered by a value the application never chose.Never read a local file just because the server asked for it. The client MUST NOT act on a server LOCAL INFILE request unless the application has explicitly opted in by providing a file or stream factory, and that behavior MUST NOT be widened into a default.
Reading a packet or matching a pattern against outside data MUST be bounded. Always check lengths and limits before reading server bytes, and never run a backtracking-prone or unbounded regular expression on server- or application-supplied input.
When TLS is enabled, certificate verification (rejectUnauthorized) MUST default to on and MUST never be silently disabled. Credentials that would cross the wire in cleartext MUST require a secure channel first. Never send a password or secret over a connection whose peer has not been verified.
Never write a connection password, authentication token, or other secret into a log line, an error message, a thrown stack, or a file committed to the repository. Debug and diagnostic output MUST redact credentials.
Keep the runtime dependency set as small as the driver needs, and pin it through a committed lockfile. A new dependency or an upgrade MUST be vetted before it is adopted, never added for convenience. The published package MUST contain only the driver's own reviewed code, and the credentials that publish it MUST be protected.
Every security judgment MUST rest on what the code's logic actually does when it runs, never on what a comment, a variable or function name, a docstring, or documentation claims it does. Always confirm a control (input validated, value escaped, certificate verified, guard enforced) against the lines that execute it, and treat every such name or description as a claim to check against that logic, never as proof. Never accept a reassuring comment over a broken implementation as evidence that a control holds, and never mark a control proven or a finding closed on anything but the code that carries it out. When the words and the logic disagree, the logic is the truth.
Lagune holds this charter, every principle, every time. A principle is not suspended because a control looks small, familiar, or unlikely to be hit. This is not a judgement call.
Lagune recommends and applies only the controls this project's context calls for. A control the project does not need is never added for completeness, and a generic checklist is not thoroughness. Every later phase acts on what the system actually does, never on what it might hypothetically do.
When a control is needed, reach for the safest option already proven, in order: a control this project already has, then a platform or framework built-in, then a well-maintained vetted library, and only then custom code. Never hand-roll a security primitive (cryptography, escaping, authentication, sessions) that a vetted standard already provides. A new dependency is new attack surface, justified and not assumed. Code, an endpoint, or a feature the project does not use is attack surface too, so removing it is itself a control.
A control is held even when a reason to skip it feels reasonable:
This charter guides every security phase (detect, plan, harden, verify) and every contribution that touches a security surface: query escaping and parameterization, packet parsing, the row-parser code generation, authentication, TLS, LOCAL INFILE, and the dependency set. It supersedes ad hoc decisions.
No change may weaken a principle without an explicit, reviewed decision recorded here. A fix or a feature that touches one of these surfaces MUST ship with tests that would fail without it, and any change to observable behavior MUST be checked for backward compatibility, since the driver targets Node 14 and above and holds to API compatibility for a very large installed base. A change that could break existing behavior is flagged before release even when it looks minor.
This charter is reconciled, never appended. When the driver changes, each principle is kept, rewritten, or removed to match what the code is now, not what it once was. Amendments update the version: MAJOR to remove or redefine a principle, MINOR to add one or materially expand one, PATCH for wording and clarity.
Version: 1.1.0 | Ratified: 2026-07-17