Scope
This guide covers how to identify and prioritize security-relevant code changes that ship without CVE assignments or security advisories. You'll learn to build a process that catches exploitable bugs hiding in routine dependency updates, feature releases, and "bug fix" commits.
What's covered:
- Evaluating non-security patches for exploitability
- Building detection workflows for unmarked vulnerabilities
- Integrating this process with existing patch management
- Compliance mapping (PCI DSS v4.0.1, NIST 800-53 Rev 5)
What's not covered:
- Zero-day response procedures
- Vendor relationship management
- Penetration testing methodologies
Key Concepts
Unmarked Security Fix: A code change that resolves an exploitable condition but ships without a CVE identifier, security advisory, or CVSS score. For example, GitLab patched a memory corruption bug in the Oj JSON parser without classifying it as a security issue. The exploit became public weeks after the patch, affecting teams that didn't recognize the update's significance.
Dependency Transitive Risk: Your application doesn't call the vulnerable code directly, but a library you depend on does. GitLab's use of Oj for JSON parsing created exposure even though application code never touched the parser's memory management functions.
Classification Gap: The window between when a maintainer fixes exploitable code and when the security community recognizes it as such. This gap exists because maintainers may not recognize security implications or lack resources for CVE assignment.
Requirements Breakdown
PCI DSS v4.0.1 Implications
Requirement 6.3.3 mandates security patches be installed within one month of release for internet-facing systems. "Security patch" isn't defined by CVE presence. If an unmarked fix addresses an exploitable condition in your cardholder data environment, the one-month clock started when the fix shipped, not when an exploit was published.
Requirement 6.4.3 requires tracking security vulnerabilities using industry-recognized sources. Your assessor will ask: what's your process for identifying security-relevant changes in sources that don't publish security advisories?
NIST 800-53 Rev 5 Mapping
SI-2 (Flaw Remediation) requires you to identify, report, and correct system flaws. Control enhancement SI-2(2) specifically calls for automated mechanisms to determine system component state. You need tooling that diffs changelogs, commit messages, and issue trackers, not just CVE feeds.
RA-5 (Vulnerability Monitoring and Scanning) extends beyond known CVEs. If your dependency ships a fix for memory corruption, use-after-free, or authentication bypass, you're expected to evaluate applicability regardless of advisory presence.
Implementation Guidance
Build a Three-Tier Review Process
Tier 1: Automated Changelog Analysis
Set up monitoring for keywords in dependency changelogs and commit messages:
- Memory safety: "use-after-free", "buffer overflow", "heap corruption", "double free"
- Authentication: "bypass", "privilege escalation", "authentication check"
- Injection: "command injection", "SQL injection", "path traversal"
- Cryptography: "timing attack", "weak random", "insecure cipher"
When your scanner flags a match, automatically create a review ticket. Don't wait for a CVE.
Tier 2: Diff-Based Triage
For flagged updates, pull the actual code changes. Look for:
- New input validation on previously unvalidated fields
- Added bounds checking in parsers or serializers
- Changes to authentication or authorization logic
- Modifications to cryptographic operations
The Oj fix would've shown up here: memory management changes in a JSON parser that handles user input.
Tier 3: Exploit Surface Mapping
Ask: does our application expose this code path to untrusted input? For the GitLab case, authenticated users could trigger JSON parsing of attacker-controlled data, making the Oj bugs exploitable. If your application only parses JSON from trusted internal sources, the risk calculation changes.
Integration Points
With Dependency Scanning
Your existing tools (Dependabot, Snyk, Grype) flag CVE-assigned vulnerabilities. Add a parallel workflow:
- Dependency update proposed
- Changelog scraped and analyzed
- If security keywords detected → Tier 2 review
- If exploit surface confirmed → treat as security patch
With Patch Management
Don't create a separate "unmarked vulnerability" process. Extend your existing patch workflow:
- Critical security patches: 7-day SLA
- CVE-assigned vulnerabilities: 30-day SLA (per PCI DSS)
- Unmarked security fixes: 30-day SLA after confirmation
- Feature/bug releases: Standard deployment cycle
Tooling Requirements
You need:
- Changelog aggregation: RSS feeds, GitHub release monitoring, or vendor mailing lists
- Keyword detection: Simple grep works; ML-based classification is overkill
- Diff retrieval: GitHub API, GitLab API, or package repository metadata
- Ticket integration: Auto-create issues in Jira/Linear/etc when keywords match
Common Pitfalls
Treating "Bug Fix" as Non-Security
Maintainers use inconsistent terminology. "Fixed crash in parser" might mean "fixed exploitable memory corruption". Never assume a non-security label means non-exploitable.
Ignoring Transitive Dependencies
You're responsible for vulnerabilities in dependencies of your dependencies. The GitLab team had to track Oj updates even though application code never imported the library directly.
Waiting for Proof-of-Concept
By the time someone publishes a PoC, you're six weeks behind teams who evaluated the patch on its technical merits. Exploits in the wild mean you're in incident response, not patch management.
Over-Relying on CVSS
No CVE means no CVSS score. You'll need internal severity classification based on:
- Authentication required? (GitLab: yes, authenticated users)
- Network accessible? (GitLab: yes, remote code execution)
- Exploit complexity? (GitLab: required chaining multiple bugs)
- Impact scope? (GitLab: command execution as 'git' user)
Skipping the "Why No CVE?" Question
When you find an unmarked security fix, ask the maintainer why no CVE was assigned. Answers reveal process gaps:
- "We didn't think it was exploitable" → They might be wrong
- "We don't have resources for CVE assignment" → Expect more unmarked fixes
- "It only affects edge cases" → Verify the edge case doesn't apply to you
Quick Reference Table
| Signal | Action | Timeline | Owner |
|---|---|---|---|
| Changelog contains memory safety keywords | Create Tier 2 review ticket | Within 24h of release | Security team |
| Code diff shows auth/validation changes | Exploit surface analysis | Within 3 days | AppSec engineer |
| Confirmed exploitable, no CVE | Treat as security patch | 30-day deployment SLA | Patch management |
| Vendor confirms "not a security issue" | Document risk acceptance or deploy anyway | Per risk tolerance | CISO + Engineering lead |
| Community publishes PoC for unmarked fix | Emergency patch process | Per incident response plan | Incident commander |
| Dependency update with no changelog | Request details from maintainer | Before approving update | Development team |
Compliance Checklist:
- Automated changelog monitoring configured for all production dependencies
- Keyword detection rules documented and version-controlled
- Tier 2 review SLA defined and tracked
- Process documented for PCI DSS assessor review
- Quarterly review of missed unmarked vulnerabilities (retrospective metric)
When to Escalate:
- Memory corruption in internet-facing parser: Immediate
- Authentication bypass in internal service: 24-hour decision window
- Cryptographic weakness in data-at-rest encryption: 72-hour assessment
- Race condition in logging library: Standard triage process
You can't rely on CVE assignment to define your patch scope. Build the muscle to evaluate every dependency update on its technical merits, not its advisory presence.



