Skip to content

Instantly share code, notes, and snippets.

@timb-machine
Created April 12, 2026 21:10
Show Gist options
  • Select an option

  • Save timb-machine/5b49920133698e9e9cc796ad3103392d to your computer and use it in GitHub Desktop.

Select an option

Save timb-machine/5b49920133698e9e9cc796ad3103392d to your computer and use it in GitHub Desktop.
ChatGPT producing vulnerable COBOL
Here’s a **realistic, educational example of a vulnerable COBOL pattern**. This is simplified, but it reflects issues commonly found in legacy financial and batch-processing systems.
---
## ⚠️ Example: Unsafe input handling in a COBOL batch program
### Vulnerable COBOL code
```cobol
IDENTIFICATION DIVISION.
PROGRAM-ID. UPDATE-ACCOUNT.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-ACCOUNT-REC.
05 WS-ACCOUNT-ID PIC 9(10).
05 WS-BALANCE PIC 9(9)V99.
01 WS-INPUT-REC.
05 IN-ACCOUNT-ID PIC X(20).
05 IN-AMOUNT PIC X(15).
01 WS-AMOUNT-NUM PIC 9(9)V99.
PROCEDURE DIVISION.
MAIN-PARA.
READ INPUT-FILE INTO WS-INPUT-REC
AT END STOP RUN
END-READ
* BAD: No validation before conversion
MOVE IN-ACCOUNT-ID TO WS-ACCOUNT-ID
MOVE IN-AMOUNT TO WS-AMOUNT-NUM
ADD WS-AMOUNT-NUM TO WS-BALANCE
WRITE OUTPUT-RECORD FROM WS-ACCOUNT-REC
STOP RUN.
```
---
## 🔥 What’s vulnerable here?
### 1. **Unsafe numeric conversion**
```cobol
MOVE IN-AMOUNT TO WS-AMOUNT-NUM
```
* `IN-AMOUNT` is `PIC X(15)` (free text)
* `WS-AMOUNT-NUM` is numeric (`PIC 9(9)V99`)
### Problem:
If `IN-AMOUNT` contains:
* `"ABC"`
* `"1O00"` (letter O instead of zero)
* `"999999999999999"`
👉 COBOL may:
* silently convert garbage to 0
* produce unpredictable numeric values
* or truncate without error depending on compiler/runtime settings
**Impact:** incorrect balances without any crash.
---
### 2. **No validation on account ID**
```cobol
MOVE IN-ACCOUNT-ID TO WS-ACCOUNT-ID
```
* `IN-ACCOUNT-ID` is text
* `WS-ACCOUNT-ID` is numeric
If input contains non-numeric characters:
* conversion may fail silently or produce undefined results
**Impact:** wrong account updates (critical in banking systems).
---
### 3. **No length checks (fixed-format assumption bug)**
COBOL assumes fixed-width fields, but:
* Input may be longer than expected
* Truncation happens silently
**Example risk:**
```
IN-ACCOUNT-ID = "12345678901234567890"
```
→ gets truncated to first 10 digits
**Impact:** updates wrong account entirely.
---
### 4. **No error handling at all**
There is:
* no `ON SIZE ERROR`
* no `INVALID KEY`
* no input validation logic
So the program:
> blindly trusts upstream batch data
---
## 💥 What an attacker (or bad upstream file) can do
In real legacy environments, if someone controls or poisons the input file:
* inject malformed numeric strings
* shift account IDs via truncation
* cause mis-posting of funds
* corrupt downstream financial reports
This is especially dangerous in **batch overnight processing systems**, where errors may only be discovered after financial reconciliation.
---
## 🛠️ Safer version (what it *should* look like)
```cobol
IF IN-ACCOUNT-ID IS NUMERIC
MOVE IN-ACCOUNT-ID TO WS-ACCOUNT-ID
ELSE
DISPLAY "INVALID ACCOUNT ID"
STOP RUN
END-IF
IF IN-AMOUNT IS NUMERIC
MOVE IN-AMOUNT TO WS-AMOUNT-NUM
ELSE
DISPLAY "INVALID AMOUNT"
STOP RUN
END-IF
ADD WS-AMOUNT-NUM TO WS-BALANCE
```
Even better systems also:
* reject malformed records into a “dead-letter queue”
* log validation failures
* enforce schema validation upstream (not just in COBOL)
---
## 🧠 Key takeaway
COBOL vulnerabilities are usually:
> “The program assumes the input is already correct — and quietly does the wrong thing when it isn’t.”
---
If you want, I can also show:
* a **CICS transaction security flaw (very common in banks)**
* or how COBOL interacts with modern APIs where injection-like bugs can appear
* or real-world CVE-style examples from mainframe environments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment