Database security
Skill ShieldNet-360/secure-vibe/dist/agent-skills/.agents/skills/database-security
SecureVibe — prevention-first security for AI-written code. Signed SKILL.md knowledge that makes AI coding assistants write secure code at generation time, plus a deterministic CI gate. Offline · keyless · Ed25519-signed. By ShieldNet360.
npx -y skills add ShieldNet-360/secure-vibe --skill database-securityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Prevent SQL injection, ORM misuse, credential leaks; enforce least-privilege DB users and safe migrations — Applies to: when generating SQL or raw query strings; when generating ORM model code or queries; when generating database migration files; when wiring connection strings or pooling
SKILL.md
3.5 KB, as published. Nobody here has run it
Database Security
Prevent SQL injection, ORM misuse, credential leaks; enforce least-privilege DB users and safe migrations
ALWAYS
- Use parameterized queries / prepared statements for any SQL that touches user-controlled values. Pass values as parameters, never via string concatenation or formatting (
%s,+, template literals). - Use the ORM's safe query API. In SQLAlchemy:
session.execute(text(":id"), {"id": user_id}). In Django: ORM methods,Model.objects.filter(...). In Sequelize / Prisma / SQLAlchemy core:.where({ ... })builders. In Go:db.QueryContext(ctx, "select ... where id = $1", id). - Validate that identifier columns / table names — which can't be parameterized — come from a hard-coded allowlist, not from user input.
- Use a dedicated database user per application with the minimum grants needed. Web apps that only read shouldn't have
INSERT/UPDATE/DELETE. Migration jobs run as a separateDDL-capable user. - Enable Row-Level Security (Postgres
CREATE POLICY/ Supabase RLS / Azure SQL RLS) for multi-tenant tables and set the tenant context per session. - Pull DB credentials from a secret manager or env var injected at start — never from a committed
database.yml/.env. Rotate on schedule. - Use TLS to the database (
sslmode=requirefor Postgres,requireSSL=truefor MySQL, encrypted connection for MSSQL). Pin the CA where the driver supports it. - Connection pooling has a max size that fits within the DB's
max_connections, with healthy back-pressure on the application.
NEVER
- Concatenate user input into SQL:
"SELECT * FROM users WHERE name='" + name + "'". Even if you "escape" it yourself — drivers escape correctly only when binding through the parameter API. - Use ORM raw query methods (
.raw(),.objects.raw(),.query(text(...))) with f-string interpolation of user input. - Run application workloads as the database superuser /
root/postgres/sa. Create a service user. - Disable TLS to the database (
sslmode=disable,useSSL=false). - Store secrets, PII, or large blobs in JSON columns without encryption-at-rest and a key rotation plan.
- Run destructive migrations (DROP TABLE, DROP COLUMN, ALTER COLUMN type changes on populated tables) inline with deploys without an expand–contract plan and a backup verified to be restorable.
- Bind an internet-exposed database listener with no allowlist; databases stay in a private network and are reached via a bastion / VPN / private link.
- Log entire SQL statements with bound values at INFO level — bound values are almost always sensitive.
KNOWN FALSE POSITIVES
- Reporting tools that run analyst-authored ad-hoc SQL legitimately interpolate identifiers; they should run against a read-only replica with a separate user whose grants prevent damage.
- Some ORMs (Django, SQLAlchemy 1.x) use
%splaceholders as parameter markers, not Python format-string placeholders — that's safe. - Health-check queries (
SELECT 1) are intentionally trivial.