Two reports this week point the same way. OpenAI says its new security model found 81 previously unknown high-severity flaws in Firefox and built working exploits for 948 Linux kernel bugs. A day later, IBM and Red Hat described a repair effort racing to keep up with what AI is finding. If you ship a web app or an AI product on a few hundred open-source packages, that means more advisories against your dependency tree, rated higher, faster than you can work through them in date order. This article covers what the two reports say and how we would pick which advisories get fixed this week: by whether your code can actually reach the vulnerable function.

What the reports say

OpenAI introduced GPT-6 Cyber on November 5. Its researchers used it to "identify 81 previously unknown high-severity vulnerabilities in Firefox, despite extensive prior testing with frontier models", and it "showed that an additional 30 known issues were more severe than previously reported". On Linux, the model "reproduced 1,724 vulnerabilities and developed working exploits for 948", and OpenAI "disclosed 304 critical findings to maintainers with candidate patches".

IBM Think covered the other side on November 6. IBM and Red Hat's Lightwell initiative has repaired more than 400 previously unknown vulnerabilities in widely used Java libraries. An October IBM X-Force analysis found that publicly disclosed vulnerabilities across Microsoft, Oracle, Google Chrome and Apache "rose 578% in the first nine months of 2026 compared with the same period in 2025". The researchers said AI-assisted discovery could help explain the rise, but "could not determine precisely how much it contributed."

Ben Breard of Red Hat put the mood plainly: "The unknown is way worse than we thought." And on the work ahead: "We have to now look back over 10, 15, 20 years of software and go fix it."

Severity alone will not sort the pile

The same X-Force analysis found "55.2% of 223 AI-discovered vulnerabilities received high or critical severity ratings", and classified 91% as remotely accessible. When more than half of the new findings arrive rated high or critical, the rating no longer tells you what to do first.

Breard offered the better filter. According to IBM, he cautioned that a flaw in a library does not put every application using it at the same risk: the consequences depend on "how developers use the software and whether attackers can reach the vulnerable code." He also noted that automated reports need checking before anyone writes a fix: "We have to do an upfront quality check to validate that these are real."

OpenAI's Brotli case shows why the dependency tree matters. Its researchers showed how a flaw in Brotli, "a compression library used by Node.js and other software", could enable remote code execution in downstream applications. Few teams ever chose Brotli. It arrives underneath something they did choose.

Sort by reach, then by severity

We would put every advisory into one of three tiers before looking at its score:

  1. Reachable: your code calls the vulnerable function, from a public route, a queue consumer or an upload handler. Fix it this week.
  2. Imported: you depend on the package directly, but you do not call the named function from an exposed path. Patch it on the normal cycle.
  3. Transitive: it sits under another package. Push the upstream bump, and pin or override the version if upstream is slow.

Here is a sketch of how we would rank them, given the advisory list and a scan of what your code imports and calls:

type Severity = "critical" | "high" | "medium" | "low";
type Advisory = { id: string; pkg: string; severity: Severity;
  symbols: string[] }; // functions the advisory names, if any

type Usage = {
  direct: Set<string>;          // packages our code imports
  calls: Map<string, string[]>; // package -> functions we call
  exposed: Set<string>;         // packages used on a public path
};

type Tier = "reachable" | "imported" | "transitive";

function tier(a: Advisory, u: Usage): Tier {
  const called = u.calls.get(a.pkg) ?? [];
  // No named function: assume the worst until a person reads it.
  const hit = a.symbols.length === 0
    || a.symbols.some((s) => called.includes(s));
  if (u.direct.has(a.pkg) && hit && u.exposed.has(a.pkg)) {
    return "reachable";
  }
  return u.direct.has(a.pkg) ? "imported" : "transitive";
}

const order = { reachable: 0, imported: 1, transitive: 2 };
const sev = { critical: 0, high: 1, medium: 2, low: 3 };

export function triage(list: Advisory[], u: Usage) {
  const tiered = Array.from(list, (a) => ({ ...a, tier: tier(a, u) }));
  return tiered.sort((x, y) => order[x.tier] - order[y.tier]
    || sev[x.severity] - sev[y.severity]);
}

What to notice: severity only breaks ties inside a tier, so a medium flaw on your upload handler outranks a critical one in a package you never call. And an advisory that names no function is treated as reachable, because guessing low is the expensive mistake.

Where this costs you

Static reachability misses dynamic calls: a function picked by name from config, a plugin system, reflection. We would treat "not reachable" as a judgement that expires, and re-run the scan on every merge, since one new call can move a flaw up a tier.

The sketch only sees calls your own code makes. A transitive package can still be reached through a direct one, the way compression middleware might hand your responses to Brotli. Catching that needs a call graph through your dependencies, which is more setup and slower to run.

Many advisories name no function at all. Someone has to read them and confirm the finding is real, which is the upfront check Breard describes, and it is human time. And none of this shrinks the backlog: it only decides the order, so the reachable tier still needs a person and a deploy this week.

What to take from this

  1. Expect more advisories against your dependency tree, rated higher, for some time.
  2. Sort them by whether your code can reach the vulnerable function first, and by severity second.
  3. Treat an advisory that names no function as reachable until someone has read it.
  4. Re-run the reachability scan on every merge, and push upstream bumps for the transitive tier.

If you want a second pair of eyes on a dependency backlog that keeps growing, book a conversation.

Sources