Skip to content
Security & Trust

pyLoad-ng flaw lets any logged-in user guess admin password in tested builds

A permission check set to zero checks nothing, and the rate limit trusts a header the client controls

W
WebPulse Newsroom
AI-assisted · 4 min read
Share on X LinkedIn
pyLoad-ng flaw lets any logged-in user guess admin password in tested builds
In brief
  • The GitHub Advisory Database reports that any logged-in pyLoad-ng account, even with no permissions, can guess the administrator password; only 0.5.0b3 development builds were verified, older lines unchecked.
  • Two weak controls combine: a permission check that passes everyone, and a rate limiter that trusts a client-supplied header. The advisory reports no account lockout.
  • If you run pyLoad, check who holds accounts, whether it is internet-facing, and how strong the admin password is. The advisory names no patched release.

A permission set to zero is not a strict rule. It is no rule at all. That is the lesson in a new advisory for pyload-ng, a download manager with a web interface. The GitHub Advisory Database published it on October 9 as GHSA-68w4-83fh-f2w8. The text we reviewed lists no CVE ID.

The advisory says the lowest-privileged account is enough to go after the administrator. The attacker sends password guesses one request at a time. One right guess gives full administrative control of the pyLoad instance.

How a check that checks nothing works

pyLoad stores permissions as bits. Each method names the bits a caller must hold. The system compares the caller's bits with that list. Two methods, getUserData and get_userdata, are marked Perms.ANY. That level equals zero.

With zero required, the check works out to 0 equals 0. That is always true. Every logged-in account passes, even one with no permission bits at all.

This would not matter if the methods did nothing sensitive. But both wrap check_auth(), a function the maintainers deliberately kept for administrators. The wrappers undo that choice. The advisory describes the result as a clean yes-or-no test of the administrator password. When a guess is right, the reply also exposes the admin's ID, name, email, role and permissions.

Two safeguards that do not hold

Guessing attacks usually meet two defenses: caps on attempts and slow checks. The advisory finds the first one weak in two ways.

First, nothing in the code counts wrong passwords, adds a delay or locks the account. Each wrong guess costs the attacker one password-hash calculation.

Second, the API allows 100 requests per minute. But it sorts requests into buckets by the X-Forwarded-For header. The client sets that header. Change it on every request, and each request gets a fresh allowance.

100 requests per 60 seconds
API rate limit
Source: GitHub Advisory Database, GHSA-68w4-83fh-f2w8 (October 9, 2026)

Another function in the same file, is_loopback_request(), already treats such headers as untrustworthy. The advisory says the same caution was evidently missing from the rate limiter.

What the test showed, and what it did not

The researchers ran the attack as a user with zero permissions. They changed the header on every request. They measured 17 to 47 guesses per second per thread. They say the only real limit was password hashing. That is a deliberately slow calculation, PBKDF2-HMAC-SHA256 with 100,000 iterations.

17-47 per second per thread
Measured guess rate
Source: GitHub Advisory Database, GHSA-68w4-83fh-f2w8 (October 9, 2026)

One caveat matters. In the demonstration, the administrator password had only two characters. That proves the path works. It does not show how long a long, random password would hold out.

The version scope is also narrow. The team tested only the 0.5.0b3.dev* development builds, at commit a5b008958. Version 0.5.0b3 itself is not a release on PyPI, the Python package index. Only automatic development builds exist. The authors leave it to the maintainers to check the older 0.5.0b2 and 0.4 lines.

So we cannot say which of your installs are exposed. The source also names no patched version.

The broader lesson: a default can quietly mean public

The advisory points to a structural cause. Any method marked Perms.ANY silently becomes open to every logged-in user. This is how access control often fails. Rarely does someone remove a lock. More often a label means something different from what the next developer assumes.

For executives, the point is about internal accounts. Many organisations treat a low-level login as harmless. This flaw turns that login into a route to the top account. The risk then depends on who holds low-level accounts, not only on who holds admin.

What to ask your team

Start with inventory. Does anyone run pyLoad, and who can reach it? If it faces the internet, ask who holds accounts and whether all of them are needed.

Then check the basics. Is the administrator password long and unique? Does a reverse proxy overwrite X-Forwarded-For instead of passing it through? Do logs show bursts of calls to /api/getUserData or /api/get_userdata?

The advisory suggests several fixes. Remove the permission marker from the two methods, or drop the methods. Give Perms.ANY a real meaning. Stop trusting X-Forwarded-For by default. Add lockout or throttling for each account. Ask your vendor or the maintainers where each fix stands.

100,000 PBKDF2 iterations
Password hashing cost
Source: GitHub Advisory Database, GHSA-68w4-83fh-f2w8 (October 9, 2026)

A permission that requires nothing is a sign on an open door. Check what your own systems mean when they say "any".

Produced by the WebPulse Newsroom with AI assistance from the original reporting credited below, and checked against that source by our editorial review. How we use AI.
Original reporting: GitHub Advisory Database.

Share this insight