Skip to content

VNX-1057: Data Access Operations Outside of Expected Data Manager Component

Reports raw database access (driver connect, cursor(), cursor.execute, Model.objects.raw, execute() or fetch() with SQL text) in a Python view, route, handler or controller module of a project that has a models/repositories/dao/db component. ORM queries, calls into the data layer, SQL inside the data layer, projects without one and tests are not reported.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-1057
Severity Low
SARIF level note
Kind sast
Languages Python
CWE CWE-1057
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L
Tags data-access-outside-mgr layering sql cwe-1057
Source internal/sast/rules/vnx-1057.rego

Overview

VNX-1057 maps to CWE-1057: Data Access Operations Outside of Expected Data Manager Component. It reports raw database access in a Python request-handling module when the project has a data manager component that should own it.

  • Handler module: named or placed as a view, route, handler, controller, endpoint, resolver or API module (views.py, routes/, handlers.py, api/), or one that declares routes (@app.route, @bp.get, @router.post, @api_view) or Django views (def name(request, ...)).
  • Data manager component: another scanned file under a models, repositories, dao, db, database, persistence, store, crud or queries module.
  • Raw access: a DB-API driver connect(), a .cursor() call, Django Model.objects.raw(), cursor.execute/executemany/executescript, and execute(), fetch(), fetchrow(), fetchval(), fetch_all() or fetch_one() (DB-API, asyncpg, databases) on a connection, db, session or engine handle whose argument is SQL text, text(...), or a name assigned SQL text a few lines above.

Why This Matters

When handlers write their own SQL, the protections the data layer applies (parameterisation, tenant scoping, authorisation filters, auditing) are applied only where someone remembered them. Raw SQL scattered through views is also where injection bugs collect.

Not reported: ORM queries (Model.objects.filter, session.query, select()), calls into the data manager’s functions, raw SQL inside the data manager modules, projects with no data manager component, test files, comments and SQL written in string literals that are not executed.

What Gets Flagged

def product_list(request):
    category = request.GET.get("category", "all")
    products = Product.objects.raw("SELECT * FROM shop_product WHERE category = %s", [category])
@bp.post("/<int:post_id>/delete")
def delete(post_id):
    get_db().execute("DELETE FROM post WHERE id = ?", (post_id,))

Not flagged:

products = Product.objects.filter(active=True).order_by("name")

Remediation

  1. Move the query into the repository, model manager or DAO and call that function from the handler.
  2. Keep connection handling (connect, cursor) inside the data layer.

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-1057
// nosec vnx-1057

Or record an ignore rule: vulnetix ignore add --rule vnx-1057 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-1057.rego, cli/internal/sast/docs/vnx-1057.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.