SOC L2 analyst at Jagiellonian University, Krakow. I find the access-control bugs that scanners routinely miss, then I write the tested detections that catch them.
Authorization and business-logic research on open-source software a lot of people quietly rely on: WordPress, Elastic, GitLab, Matomo. Every proof of concept runs in a local lab before anything is filed.
One audit of freshly added media-handling code during the 7.1 beta. Both fixed before 7.1 shipped, both paid, neither a duplicate.
| Report | Severity | What it was |
|---|---|---|
| #3931777 | CVSS 9.9, CWE-22 | The lowest role allowed to upload files could delete wp-config.php through the media finalize route. A WordPress without wp-config.php hands its installer to anyone. |
| #3931771 | CVSS 9.0, CWE-79 | The same controllable filename ran as script in any administrator's session on merely opening the media library. |
Fixed in Gutenberg 23.8 and core r63200. The write-up, with the exploit replayed: jakubkozub.com/research/wordpress-media-finalize
Most researchers do the first half of this. Most blue teams do the second. Both halves of the same finding are public here.
detections carries the Sigma rules for what that 9.9 leaves in the logs, with the log lines that must fire them and the ones that must not. Every request in the chain is authenticated, authorised and successful, so there is no request signature to match: the rules watch a sequence, an outcome and a state change instead. Each rule is rendered for Splunk, Elastic ES|QL and Kusto, and every rendering was run against the same fixtures on the real engines (Elasticsearch 8.19.4, Splunk 9.4.3 and the Kusto emulator).
Contract work, taken alongside my job and independently of my employer. Three things:
- Access-control review of one application, plugin, internal tool or REST API. You get the entry points a request can reach, ranked by who can reach them, and a report per confirmed finding.
- Vulnerability research on one open-source component you depend on, audited the way the 9.9 was found: recent changes first, one attacker-controlled value followed across subsystems. Coordinated disclosure to the maintainer where the code is not yours.
- Detection engineering: a finding, an incident or a threat model turned into rules that run on your own log sources, each with the log sources it needs and tests against traffic you already have.
Scope, deliverables and how an engagement runs: jakubkozub.com/#services Email: contact@jakubkozub.com
Python, standard library only, offline by design, MIT. No telemetry, nothing leaves the machine.
Find the reachable code
- wp-authz-audit: maps the WordPress plugin
code an attacker can reach and the guard on each path, catching a nonce standing in for
authorization and a capability check standing in for an ownership check. Its
diffmode compares two releases, so a version bump touching hundreds of lines reports only what became reachable or lost a guard. - wp-hook-guard: maps every server-side entry
point a plugin exposes (
wp_ajax_,wp_ajax_nopriv_,admin_post_,register_rest_route,inithandlers that read the request) and flags those with no capability check, nonce or permission callback behind them. A hand-written PHP lexer keeps hooks in comments and strings out of the results.
Prove the gap
- authz-differ: replays one request under several identities, the owner, another user, nobody, then diffs the responses. Same 200 and same body for the wrong identity is the IDOR. One request per identity, never a scanner, every credential redacted to a non-reversible fingerprint.
Get the evidence out safely
- har-sanitizer: redacts cookies, bearer and
JWT tokens, API keys and PII from a HAR, a raw request or a curl command while keeping the
request reproducible.
--strictre-scans its own output and fails closed on any high-entropy token the structured pass did not reach. - evidence-redaction-gate: a fail-closed gate that refuses to let secrets or PII leave inside evidence. Built after I measured that two detectors in my own workflow had silently drifted apart, 9 of 31 and 13 of 31 on realistic secret shapes. One shared module and an adversarial corpus took it to 31 of 31 with no false alarms.
- redact-request: prints the shape of a captured request and never its contents, so a request can be discussed without handing over the session. Its tests are written as leak tests: they assert on what must be absent.
Scope it and write it up
- scope-sentinel: answers whether a target is actually in scope before any request goes out, where out of scope always beats in scope. Its exit codes make it a gate in front of a script.
- finding-forge: turns a confirmed finding into a report a triager can act on, with a CVSS 3.1 scorer that matches the FIRST calculator to the decimal and a lint that fails the draft on an empty section or a leaked secret.
eWPTX, eCTHP, CDSA, BTL2. Approved Wordfence researcher. 4x CTF podium (2x first), Vision One European CTF finalist. MSc Information Technology (AHE Lodz). Postgraduate cybersecurity and MA English Philology (University of Warsaw).
- Portfolio: jakubkozub.com
- HackerOne: hackerone.com/jakubk
Authorized testing only, inside an agreed scope. Vendor first, coordinated disclosure. Nothing is filed until it is rebuilt in a lab, and I report only what I measured, including where the impact stops.

