T09 · Insecure Skill Coding Practices
- Location
scripts/validate_functional.py:486- Finding
Unrestricted Execution of Source-Side Teradata Procedures
- Content
View full analysis
Vulnerability Details
File Location:
scripts/validate_functional.py, lines 486–493
Vulnerability Type: Source database write-safety bypass
Risk Level: HighVulnerable code:
python # --- TD side: CALL invocation --- try: td_sql = _SQL_CALL + ' ' + _qi(td_db) + '.' + _qi(proc_name) + '()' td_cols, td_rows = execute_td_query(td_conn, td_sql) result['td_status'] = 'success' result['td_row_count'] = len(td_rows) result['details']['td_columns'] = td_colsTechnical Analysis
Functional validation calls each discovered zero-argument procedure on the source Teradata database. The call is passed to
execute_td_query(), which invokes the database driver directly and does not applyTeradataReader._validate_readonly().Although the database and procedure identifiers are validated, identifier quoting only prevents SQL injection. It does not establish that the selected procedure is read-only. A procedure body may perform DML, DDL, transaction control, or external side effects.
This bypasses the project's stated source-read-only security boundary. The DWS procedure invocation is subsequently rolled back, but no equivalent rollback or technically enforced read-only transaction protects the Teradata invocation.
Trigger conditions:
- Functional validation is run without
--skip-procs, which is the default behavior. - The selected source database contains a callable zero-argument procedure.
- That procedure performs writes or another persistent side effect.
- The configured Teradata account has sufficient permission to perform that operation.
Attacker-controlled point: A database user able to create or modify a procedure in the selected source database can control its body. Independently of malicious modification, an existing business procedure with legitimate write behavior also triggers the unsafe path.
Trust boundary: Database-resident code crosses from met ...[truncated 1419 chars]
- Functional validation is run without
- Remediation
View remediation
Remediation Suggestions
- Do not execute source-side stored procedures during validation by default. Require an explicit opt-in for procedure execution.
- Require separate, per-procedure confirmation that clearly identifies the source procedure and warns that its body may modify production state.
- Use a dedicated Teradata account whose privileges are technically restricted to metadata and read-only data access. Do not grant execution rights on write-capable procedures.
- Inspect and classify procedure definitions before execution, rejecting any procedure that cannot be proven read-only. Static inspection should be treated as defense in depth rather than the sole control.
- Route all source operations through a common security layer instead of calling the raw driver helper directly.
- Where supported, enable a database-enforced read-only session or transaction. Do not rely solely on rollback because procedures may commit internally or produce non-transactional external side effects.
- Change procedure validation to compare definitions or migration artifacts without invoking source procedures when read-only behavior cannot be guaranteed.
- Add regression tests demonstrating that write-capable procedures are rejected and never invoked on the source system.
