{"record":{"id":"93fbdbab99d4eb2e","repo":"t8y2/dbx","slug":"unsafe","errorCode":null,"errorMessage":"unsafe","messagePattern":"unsafe","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java","lineNumber":1462,"sourceCode":"        String schema,\n        int timeoutSecs,\n        String mode\n    ) throws Exception {\n        Connection conn = openConnection(connection);\n        applyExecutionContext(connection, conn, database, schema);\n\n        boolean autotrace = \"autotrace\".equalsIgnoreCase(mode);\n        String planText = null;\n        String dmMethod = null;\n\n        if (!autotrace && isOracleConnection(connection)) {\n            planText = getOracleExplainInfo(conn, sql, timeoutSecs);\n            dmMethod = \"oracle-plan-table\";\n        }\n\n        if (autotrace) {\n            if (!isSafeAutotraceSql(sql)) {\n                throw new IllegalArgumentException(\"unsafe\");\n            }\n            // ── Autotrace mode: execute SQL first, then getExplainInfo(stmt) ──\n            boolean monitorEnabled = false;\n            try (Statement s = conn.createStatement()) {\n                s.execute(\"SF_SET_SESSION_PARA_VALUE('MONITOR_SQL_EXEC', 1)\");\n                monitorEnabled = true;\n            } catch (Exception ignored) {}\n\n            try {\n                try (Statement stmt = conn.createStatement()) {\n                    if (timeoutSecs >= 0) {\n                        try { stmt.setQueryTimeout(timeoutSecs); } catch (SQLFeatureNotSupportedException | UnsupportedOperationException ignored) {}\n                    }\n                    boolean hasResultSet = stmt.execute(trimStatementSql(sql));\n                    if (hasResultSet) {\n                        try (ResultSet rs = stmt.getResultSet()) {\n                            while (rs.next()) { /* consume */ }\n                        }","sourceCodeStart":1444,"sourceCodeEnd":1480,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java#L1444-L1480","documentation":"In the autotrace/explain path, before executing the SQL the plugin calls isSafeAutotraceSql(sql) and rejects anything it deems unsafe with this bare IllegalArgumentException. Autotrace executes the statement and then inspects the plan, so the SQL must pass the plugin's safety check (e.g. a single top-level statement, no disallowed constructs) to avoid executing arbitrary/multi-statement input.","triggerScenarios":"Requesting autotrace (or explain with autotrace enabled) on SQL that fails isSafeAutotraceSql: multiple statements separated by semicolons, comments or trailing junk the checker doesn't accept, non-query statements, or SQL with constructs the safety regex forbids.","commonSituations":"Pasting multi-statement scripts into an autotrace request, SQL containing leading comments or newlines that break the safety pattern, ORM-generated SQL with trailing semicolons, or dialect-specific syntax the checker treats as unsafe.","solutions":["Strip comments, trailing semicolons, and extra whitespace; supply exactly one statement to autotrace.","Run autotrace on a plain single SELECT/statement that the safety checker accepts; validate your SQL against the same rules beforehand.","Split multi-statement scripts and autotrace each statement individually.","If a legitimate single statement is rejected, simplify syntax toward standard SQL or check the isSafeAutotraceSql implementation for its exact accepted pattern."],"exampleFix":"// before\nsql = \"SET enable_seqscan = off; SELECT * FROM t;\";  // multiple statements\nautotrace(conn, sql);\n// after\nsql = \"SELECT * FROM t\";                              // single safe statement\nautotrace(conn, sql);","handlingStrategy":"validation","validationCode":"// Java: pre-check that SQL is a single clean statement before autotrace\nstatic void assertAutotraceSafe(String sql) {\n    String s = sql.strip();\n    while (s.endsWith(\";\")) s = s.substring(0, s.length() - 1).strip();\n    if (s.contains(\";\")) throw new IllegalArgumentException(\"autotrace requires exactly one statement\");\n    if (!s.toUpperCase(java.util.Locale.ROOT).startsWith(\"SELECT\")\n        && !s.toUpperCase(java.util.Locale.ROOT).startsWith(\"WITH\"))\n        throw new IllegalArgumentException(\"autotrace expects a single query\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    plugin.autotrace(conn, sql);\n} catch (IllegalArgumentException e) {\n    if (\"unsafe\".equals(e.getMessage())) {\n        log.warn(\"SQL rejected by autotrace safety check: \" + summarize(sql));\n        plan = plugin.explain(conn, sql); // fall back to plain EXPLAIN\n    } else {\n        throw e;\n    }\n}","preventionTips":["Send exactly one statement, no semicolons, no leading/trailing comments to autotrace","Strip comments and whitespace before passing user-authored SQL","Never pipe multi-statement scripts into autotrace; trace each statement separately","Use plain EXPLAIN mode when you only need the plan without executing the statement"],"tags":["jdbc","sql-validation","autotrace","security"],"backgroundTag":"unsafe-sql-rejected","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}