90 lines
6.1 KiB
Markdown
90 lines
6.1 KiB
Markdown
# Glaz-Tech Industries — Cardholder Data Storage Finding (PCI-DSS)
|
||
|
||
**Classification:** CONFIDENTIAL — Security / PCI
|
||
**Date:** 2026-06-03
|
||
**Prepared by:** Arizona Computer Guru (Mike Swanson)
|
||
**System:** Glaztech e-commerce/customer-portal web application (server `WWW`, 192.168.8.72) and its SQL Server backend (`192.168.8.62,3436`)
|
||
**Method:** Read-only database inspection via GuruRMM. **No actual card numbers were retrieved.** All determinations were made by column **classification and aggregate counts** (length, all-digits vs. masked vs. encrypted patterns). No PAN, CVV, or cardholder value is reproduced in this report.
|
||
|
||
---
|
||
|
||
## Executive Summary
|
||
|
||
Glaztech's **internal PSA (GTIware)** stores **full credit card numbers (PAN) in plaintext** and **retains card security codes (CVV/CID)** in its SQL databases — and those databases sit on the **same SQL instance the public website connects to** (the website itself stores nothing; it is the *access path*, see the website security assessment). This is a serious PCI-DSS compliance failure and a significant breach-liability exposure. Approximately **780 saved customer cards** (card-on-file) and **tens of thousands of historical payment records** are affected, with confirmed plaintext PANs and ~hundreds of stored CVV values.
|
||
|
||
The Sage 100/MAS ERP database (`mas_gti`) is **not** the problem — its native card module is **disabled** (`CreditCardEnable = N`, 0 stored cards). **The exposure is entirely in GTIware's card-on-file tables (`cc_file` / `cof_payments_header`), which live in the same SQL instance the public website connects to.**
|
||
|
||
---
|
||
|
||
## Findings
|
||
|
||
### Finding 1 — Full PAN stored in plaintext (card-on-file) — HIGH/CRITICAL
|
||
- **Table:** `dbo.cc_file` (`cc_number varchar(50)`, `cc_exp`, `cc_name`, `cc_code`, `activate`, …), present in every per-office database.
|
||
- **Encryption:** none. Values classify as all-digits or digits-with-spaces/dashes (recoverable PAN). Zero rows contained alpha/base64 (encrypted) content.
|
||
- **Scale (`cc_file` row counts by office DB):**
|
||
|
||
| DB | rows | DB | rows |
|
||
|---|---|---|---|
|
||
| glaz_prod_elp | 179 | glaz_prod_alb | 44 |
|
||
| glaz_prod_den | 190 | glaz_prod_slc | 41 |
|
||
| glaz_prod_phx | 141 | glaz_prod_boi | 26 |
|
||
| glaz_prod_brl | 88 | glaz_prod_shp | 14 |
|
||
| glaz_prod (tuc) | 54 | glaz_prod_corp | 3 |
|
||
| **Total** | | | **≈ 780 saved cards** |
|
||
|
||
- Sample classification (`glaz_prod` / tuc, 54 rows): 29 plaintext PAN + 25 formatted PAN, **0 encrypted**, length 15–20.
|
||
- **PCI-DSS Req 3.4:** PAN must be rendered unreadable anywhere it is stored. **Violated.**
|
||
|
||
### Finding 2 — Stored CVV / card security codes — CRITICAL (indefensible)
|
||
- **Column:** `dbo.cc_file.cc_code` (`varchar(20)`).
|
||
- **Result:** populated with 3–4 digit values. In `glaz_prod` (tuc): **50 of 54 rows hold a stored CVV** (3–4 numeric digits). Other office DBs expected to mirror this.
|
||
- **PCI-DSS Req 3.2:** sensitive authentication data (CVV/CVV2/CID) must **never** be stored after authorization — **no exception, even encrypted.** This is the most serious item and the fastest to remediate.
|
||
|
||
### Finding 3 — Plaintext PAN in historical payment records — HIGH (large volume)
|
||
- **Table:** `dbo.cof_payments_header` (`cc_number varchar(50)`), per-office.
|
||
- **Scale / classification:**
|
||
- `glaz_prod_phx`: **14,496 rows — 11,794 full plaintext PANs**, ~2,700 masked/other.
|
||
- `glaz_prod` (tuc): 2,245 rows — 367 plaintext + 597 formatted + ~1,242 masked/other.
|
||
- Represents years of transaction history retained with recoverable card numbers.
|
||
|
||
### Finding 4 — Access controls / context
|
||
- The web application connects with a **single shared SQL login (`tom`)** that has **full read on the card columns** (verified: `HAS_PERMS_BY_NAME` = 1 on `cc_number` and `cc_code`). No column-level protection or data masking.
|
||
- Connection strings (with this login + password) are stored in the site `Web.config` on the web server.
|
||
- The Sage 100 DB (`mas_gti`) has its native card module **disabled** (0 stored cards) — scope of this finding is **GTIware's card-on-file tables**, which share a SQL instance with (and are reachable from) the public website.
|
||
|
||
---
|
||
|
||
## Risk & Impact
|
||
|
||
- **Breach exposure:** if the SQL server or web server is compromised, this is a reportable cardholder-data breach (full PAN + CVV in the clear).
|
||
- **Compliance:** clear violations of PCI-DSS Req 3.2 (CVV retention) and Req 3.4 (PAN protection); likely invalidates the merchant's self-assessment and exposes Glaztech to card-brand fines and liability.
|
||
- **CVV retention** specifically removes most "we were compliant" defenses in the event of a breach.
|
||
|
||
---
|
||
|
||
## Remediation Plan
|
||
|
||
**Immediate (days):**
|
||
1. **Stop writing `cc_code` (CVV)** in the application and **purge all stored CVV values** (`cc_file.cc_code`). This is the highest-priority, lowest-effort risk reduction and is indefensible to retain.
|
||
2. Inventory and restrict who/what can read `cc_file` / `cof_payments_header`.
|
||
|
||
**Short term (weeks):**
|
||
3. Stop storing raw PAN. Move card-on-file to the **CyberSource token vault** (already in use for processing) — store a token reference instead of the PAN.
|
||
4. Purge or strongly encrypt the historical `cc_number` columns in `cof_payments_header` and `cc_file` once tokenization is in place.
|
||
|
||
**Hardening:**
|
||
5. Least-privilege SQL accounts (separate read/write, no blanket card-column read), encryption at rest (TDE) as defense-in-depth, and secrets management for `Web.config` connection strings.
|
||
6. Re-scope/refresh the merchant PCI SAQ after remediation.
|
||
|
||
---
|
||
|
||
## Evidence / Methodology (PAN-free)
|
||
|
||
- Column discovery via `INFORMATION_SCHEMA.COLUMNS` (names matching card/cvv/expir/etc.).
|
||
- Storage classification via aggregate `CASE`/`COUNT` only — e.g. `SUM(CASE WHEN col NOT LIKE '%[^0-9]%' AND LEN(col) BETWEEN 13 AND 19 THEN 1 ELSE 0 END)` to count full-PAN-shaped values without selecting them.
|
||
- CVV detection via count of 3–4 digit `cc_code` values. No raw card data was selected, displayed, or stored at any point.
|
||
|
||
---
|
||
|
||
**Status:** Reported to ownership 2026-06-03. **No data was modified or deleted** — remediation pending client (Steve Eastman / Tom) direction. This finding should be raised with the client as a priority compliance/security item.
|