Files
claudetools/clients/glaztech/reports/2026-06-03-pci-cardholder-data-finding.md
Mike Swanson 10e8d7b6bb sync: auto-sync from GURU-5070 at 2026-06-03 19:39:32
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-06-03 19:39:32
2026-06-03 19:39:36 -07:00

90 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 1520.
- **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 34 digit values. In `glaz_prod` (tuc): **50 of 54 rows hold a stored CVV** (34 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 34 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.