Skip to content

VNX-1083: Data Access from Outside Expected Data Manager Component

A Python views, routes, controllers or handlers module that opens a raw database connection or cursor, or runs raw SQL, instead of going through the data layer.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-1083
Severity Low
SARIF level note
Kind sast
Languages Python
CWE CWE-1083
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-data-layer raw-sql cwe-1083
Source internal/sast/rules/vnx-1083.rego

Overview

VNX-1083 maps to CWE-1083: Data Access from Outside Expected Data Manager Component. A Python views, routes, controllers or handlers module that opens a raw database connection or cursor, or runs raw SQL, instead of going through the data layer.

Why This Matters

Raw SQL scattered across request handlers is where unparameterised queries and missing authorisation checks hide, because nothing central reviews it. When every query goes through a repository or model layer, that layer is the one place to check parameterisation, tenancy filters and access control.

What Gets Flagged

In views.py, viewsets.py, routes.py, routers.py, controllers.py, handlers.py, endpoints.py, or any file under views/, viewsets/, routes/, routers/, controllers/, handlers/ or endpoints/:

def order_totals(request):
    with connection.cursor() as cur:                        # FLAGGED
        cur.execute("SELECT customer_id, SUM(total) FROM orders GROUP BY customer_id")

@bp.route("/reports/daily")
def daily():
    db = sqlite3.connect("app.db")                          # FLAGGED

def search(self, request):
    return User.objects.raw("SELECT * FROM users WHERE name LIKE %s", [term])   # FLAGGED

Also reported: psycopg2.connect, pymysql.connect, MySQLdb.connect, mysql.connector.connect, cx_Oracle.connect, oracledb.connect, pyodbc.connect (also through an import ... as alias or from sqlite3 import connect), connections["alias"].cursor(), Django .objects.extra(...) and RawSQL(...), and SQLAlchemy db.session.execute(...), db.engine.execute(...) and Post.query.filter(text("...")).

What Does Not Get Flagged

  • The same calls in a repository, model, db.py or service module: that is the expected data manager.
  • ORM queries in a view (Product.objects.filter(...)).
  • The calls named in comments or string literals.
  • Test files.
  • In a project that has a data manager module (a models, repositories, dao, db, database, persistence, store, crud or queries module or directory): a handler’s driver connect(), cursor(), objects.raw() and db.session.execute()/db.engine.execute() of SQL text. Those lines are reported by VNX-1057, which says the same thing for the same reason; this rule still reports them in a project with no such module, and always reports objects.extra(), RawSQL() and text() fragments.

Which module is the data manager is a project convention; the rule infers it from the file path only.

Remediation

  1. Move the query into a repository, manager or model method and call that from the view.
  2. Keep queries parameterised in that one place, and apply tenancy and permission filters there.
  3. For a deliberate exception, add # vulnetix-ignore: VNX-1083 on the line.

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-1083
// nosec vnx-1083

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

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