- A GitHub advisory reports that PraisonAI's localhost-only guard can be bypassed with a forged Host header, letting an unauthenticated caller list and run agents.
- It applies only when PRAISONAI_CALL_AUTH=disabled is set and the API is reachable over the network. It is not a default-configuration exposure.
- Check for the opt-out setting and network reach now. Authentication should rest on server-owned facts, not on request headers.
A guard that believes the visitor
A lock that asks visitors whether they belong is not a lock. A safeguard in PraisonAI's agent-calling API works much like that. One setting can switch off sign-in, but the code is meant to allow this only on a machine closed to the network. To decide whether the machine is closed, it reads a value the caller writes.
The GitHub Advisory Database published the report on October 8. It says a remote caller can send the header Host: 127.0.0.1 and pass the check. The caller can then list the agents registered on the service and run them, with no token.
How the check fails
PraisonAI serves agents over HTTP under the path /api/v1/agents. A FastAPI dependency named verify_token() runs before each request. A dependency is code that must pass before the main handler runs. The setting PRAISONAI_CALL_AUTH=disabled turns token checks off.
An earlier fix stopped the code from skipping authentication outright. It now tries to allow the opt-out only when the service is bound to localhost. Binding means which network address the server listens on. To test this, the code reads request.url.hostname. That value comes from the HTTP Host header of the current request.
The client sets the Host header. A remote caller can therefore claim to be local. The reporter states the broken rule plainly: localhost binding must be a property the server owns, set at startup or on the socket. It must not come from the request.
The reporter built a small FastAPI app around the real router, with a harmless stub agent. It received three requests with no token. With default authentication, the answer was 503. With authentication disabled and Host: external.example, the answer was also 503. With authentication disabled and Host: 127.0.0.1, the answer was 200, and the stub agent ran. The first two results act as controls. Only the forged header got through.
Who is exposed, and who is not
The reporter says this is not a default-configuration exposure. Two conditions must both hold. An operator has turned the opt-out on, and other machines can reach the API over the network.
The reporter confirmed the flaw in v4.6.62 and in the main branch at the time of the report. The reporter could not confirm whether v4.6.61 has the same guard. Version v4.6.60 had an older flaw that skipped authentication entirely. A separate advisory, GHSA-8ccj-p46r-jwqq, covers it. The advisory text we reviewed names no fixed release for this new issue.
Why an open agent door matters more
The danger is in what sits behind the check. After verify_token() passes, invoke_agent() fetches the registered agent and starts it with the caller's message. The caller is not reading a file. The caller is giving an instruction to software that acts.
The reporter says the damage depends on which agents are registered. Real deployments may give them tools, private context, links into workflows, browser, file or API access, or a paid model account. The proposed score reflects the proof: high for integrity, low for confidentiality. The reporter notes that confidentiality could be worse, depending on what the agents know.
This is the lesson for leaders. A flaw in a normal web page might expose data. A flaw in front of an agent can hand out the agent's authority. If agents may hold tools, private context or paid model access, an access check on them deserves review as carefully as the agents' own permissions.
Trust what the server knows
The fix the reporter proposes is simple in principle. The server should settle the question once, when it starts, using its own settings. One example is the address it was told to listen on through Uvicorn. If that address is not loopback, it should refuse to start with authentication off. Or remove the opt-out for network routes. The reporter also asks for tests that send real requests with a forged Host header.
In our view, the deeper point is that a convenience switch built for a developer's laptop became a security decision. The first version skipped checks everywhere. The second tried to limit the skip but used the wrong evidence. Safeguards fail when they ask the requester to describe itself.
Questions for your team
First: does any environment set PRAISONAI_CALL_AUTH=disabled? Second: can any network other than the host itself reach that service? Third: which agents are registered, and what can each one do? Fourth: are token-based settings in use instead of the opt-out? The advisory refers to CALL_SERVER_TOKEN for older releases, and says current code refuses requests when no token is set. Finally, ask your vendors for the fixed version and date once a patch is released.
An address in a header is only a claim. Authentication should rest on facts the server can check itself.
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.





