Build1 distinct publisher3 min readPublished
PMapper writes nothing to disk until all nine edge checks finish, and one silent endpoint is enough to erase the entire account map. cloudfox, the tool that did run, still ships a privilege-escalation column, but every cell in it just points back to PMapper.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
The catch at `autoscaling_edges.py:60` was written for exactly this loop, and it is aimed one exception class too narrow. A disabled region answers you: the call comes back as an authorization or region error, botocore raises `ClientError`, PMapper logs "Continuing" and moves on. Fifteen regions did that [4][6]. me-south-1 did not answer at all, the connect attempt timed out, and `ConnectTimeoutError` is not a `ClientError`, so it walked straight past the handler and out of the process [5][6].
The second half of the failure is the write strategy. Auto Scaling edges are the first of nine edge checks, and the file is only written after the ninth returns, so the map that four minutes of read calls had assembled was still in memory when the interpreter exited [7]. The arithmetic on the wall clock: 5:52 is 352 seconds [1], the tester puts the inventory phase at roughly the first four minutes, which leaves about 112 seconds spread over sixteen region attempts, near seven seconds each [2]. Retrying buys you the same four minutes and the same crash, because any endpoint in that loop that goes quiet instead of refusing lands on the same handler, and the line has not changed on main since 2022-02-03 [10].
Every later command needs that file. Six of the seven remaining ones ended in `ValueError: Did not find file at` [8]. `graph list` exited cleanly and printed `Account IDs:` with nothing under it [9]. That command's only job is reporting what graph exists, and here it had nothing to report. Seven of the eight commands run returned nothing usable [4].
Getting to the crash costs something too. PMapper 1.1.5 will not import on Python 3.10 or later, because it does `from collections import Mapping`, while its setup metadata advertises Python 3.5+, so pip installs it without complaint and the failure surfaces at runtime; the real ceiling is 3.9, end of life since October 2025 [11]. The tester, writing on dev.to, declined to patch the import on the grounds that a patched copy is not the published tool [12]. cloudfox took under a minute: download the binary, check the hash, run it [13].
cloudfox's run is clean, and its counts describe iam-vulnerable rather than your account [1][14]. The density it reports, roughly 64 permission grants per principal [3], is a property of the lab. What transfers is the column: `CanPrivEscToAdmin?` appears 140 times and every cell reads "Skipping, no pmapper data" [15]. In the lab's three-role chain, one row says `ending-role` trusts `intermediate-role` and is admin, and the row below says `intermediate-role` trusts `starting-role`, so every step is present and the traversal is left to you [18]. A head-to-head on path finding turned into one engine plus a display layer for it [19].
Ranked by verification strength, evidence, and original report placement.
The tester deployed Bishop Fox's iam-vulnerable into a throwaway AWS account over two weekends and ran cloudfox 2.0.5 and PMapper 1.1.5 against it, grading every scenario by hand against a rubric frozen in git before deployment.
pmapper graph create, run as admin against the fresh lab account, ran for five minutes fifty-two seconds and exited with an error.
For the first four minutes PMapper pulled users, roles, groups and policies, worked out who was already admin, then started checking for links beginning with EC2 Auto Scaling, which means checking every region; the account had 17 regions enabled and AWS has many more.
Fifteen regions logged messages of the form "Unable to search region af-south-1 for launch configs. The region may be disabled, or the error may be caused by an authorization issue. Continuing."
The sixteenth region raised botocore.exceptions.ConnectTimeoutError on the endpoint URL https://autoscaling.me-south-1.amazonaws.com/, and the run died at autoscaling_edges.py:60.
The handler that catches "region didn't work, keep going" only catches a region refusing you (ClientError); the fifteen refused and were caught, while me-south-1 went silent and timed out, which is a different kind of error the catch does not handle, so the program died.
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 31, 2026
Follow any of these and your For You feed starts watching them — no settings page required.
build
Force the tool call, then hand Lightsail a long-lived key1 distinct publisher
build
CSA's 2026 threat list is a flat line, so ask which threats a config snapshot can prove1 distinct publisher
build
TerminalFix delivers its first stage through the clipboard of the person it targets1 distinct publisher
build
A cache hit is a quota refund: semantic caching with trigrams and no vector database1 distinct publisher
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Verbatim, and unreplicated
Almost nothing here is paraphrase: a timeout on a named endpoint, a failing line number, fifteen "Continuing." log lines, one ValueError shared by six commands, 140 identical column cells, a rubric locked in git before the lab existed. What is missing is a second pair of hands — one tester, one account, one run per command, no upstream issue and no maintainer reply to test the reading of that except clause against.
One lab account, plus a rival's paperwork
The only usage on the record is a throwaway AWS account worked over two weekends. The nearest thing to a field signal is second-hand: cloudfox ships a column and a sixteen-line to-do file that both route users to PMapper, which tells you who the ecosystem treats as the engine and nothing whatever about how many people run it. No downloads, no deployments, no practitioner accounts appear.
Argues itself down
The post keeps declining the bigger claim available to it: one sighting, not a rate; two tools, not a survey of the field; and the six recorded PMapper misses are withdrawn mid-post once hand-checking shows PMapper's rule — report the principal that can escalate itself — was correct all along. "Erase the entire account map" is the loudest phrase in our coverage, and the transcript earns it.
No vendor in the room
A self-published test by someone with no stated stake in either project, graded against a rubric he could not adjust after seeing results, and deliberately run against the published PMapper rather than a locally patched one. The residual pull is narrative rather than commercial: a post that opened expecting a scoreboard needed something to say instead, and duly produced four findings.
Trust the trace, not the rate
Take the crash, the discarded map and the all-skips privesc column as read: they are mechanically specific and cheap for anyone with an AWS account to reproduce. Hold looser the jump from one silent endpoint to every unreachable one, and looser still any sense of how often this bites real reviews — that rests on a single unchanged line of code and one weekend's observation.