Inspiration
More and more, an AI agent is the first voice a customer hears when they call your company.
That same phone line is where scammers do their best work. Voice phishing, or vishing, is the fastest-growing way into a company.
- Vishing attacks rose 442% between the first and second half of 2024, according to CrowdStrike's 2025 Global Threat Report.
- On November 6, US prosecutors charged three men with using AI-cloned voices of CEOs and attorneys on live calls to steal about $129 million.
- Microsoft researchers showed a voice can be cloned from three seconds of audio.
- Deloitte projects fraud driven by generative AI will reach $40 billion a year in the US by 2027.
Every one of those attacks worked on a person who believed what they heard. Now the agent answering is an AI, and teams give it more permissions every month. It takes calls from strangers, at any hour, and it's built to be helpful. It never gets suspicious and it never gets tired. The caller needs no exploit. They only have to keep talking until the agent says yes.
Are you building a voice agent? Do you want to give it privileged permissions? Scary. Let's fix that.
We vish your voice agents with other voice agents.
What it does
WisprNo lets developers stress test a voice agent in a sandbox: fake customers, fake accounts, isolated sessions. Nothing real is at risk, and every result comes with evidence.
It runs a suite of red-team calls against your agent:
- Map. It reads your agent's tools and shows which record each one can change and what guards it.
- Attack. AI callers with different tactics ask for things they aren't entitled to. When the agent refuses, they try another way in.
- Prove. A breach counts only when a tool fires and the backend record changes. What the agent says is never evidence.
- Shrink. It finds the shortest call that still works and counts how often it works.
- Fix and retest. It proposes a check, you approve it, and the same attack replays. Normal calls rerun too, so a fix can't lock out real customers.
So when you want to give your agent a new permission, you can first see how that permission could be exploited, and whether your fix holds.
Are you a business owner? Hold your developers accountable. Ask to see the test report before a voice agent gets access to accounts. Are you a developer? Secure your voice agent now, before someone else tests it for you.
How we built it
The engine is TypeScript on Node 24. Every call is written as an ordered event log, and the UI, the reports and the database all read that one format.
Connecting an agent takes four steps:
- Choose your agent's source folder and review which files get uploaded.
- Point WisprNo at your running agent, on the server or on your own computer. For a laptop agent, a small companion script pairs with a single-use code and makes outbound connections only.
- WisprNo validates the agent read-only, then shows you the policy it will judge against and the normal calls it expects to succeed.
- It runs a compatibility check against a disposable copy with a scripted model, so nothing is spent and nothing real changes.
Any agent that exposes our small bridge contract can be tested. We built three more agents on different designs (a pharmacy, a utility and a clinic) to check that WisprNo wasn't fitted to one system.
The parts:
- Attacker and fixer: language models. The attacker picks its next tactic from the agent's last refusal.
- Scorer: fixed rules over the account record, with no AI in that step.
- Judge: a model from a different vendor reads transcripts for spoken leaks. It agreed with our hand labels on 19 of 20.
- Gemini: reads the agent's source and explains what each tool can change. Every claim must quote a real source line or we reject the answer.
- Voice: real SIP calls on our own test line to an open-source receptionist built on LiveKit and OpenAI Realtime.
We report every rate as a count with a Wilson interval, because small samples can flatter you:
$$ \frac{\hat{p} + \frac{z^2}{2n}}{1 + \frac{z^2}{n}} \;\pm\; \frac{z}{1 + \frac{z^2}{n}} \sqrt{\frac{\hat{p}(1-\hat{p})}{n} + \frac{z^2}{4n^2}} $$
A fix that holds 0 of 20 times still has an upper bound near 16%. We show that number next to the zero.
How we used Vultr
WisprNo runs on one Vultr cloud instance at wisprno.us. We put the attacker and the agents it attacks on the same machine for a reason: the test agents never face the internet. They listen on loopback only, and WisprNo calls them from inside the server.
- Six services, six accounts. The WisprNo app, four test agents (a credit union, a pharmacy, a utility and a clinic) and a spend ledger each run as a separate systemd service under its own unprivileged user.
- Three model vendors side by side. The pharmacy agent runs on Gemini, the utility on OpenAI and the clinic on Anthropic, so we can attack different models from one place.
- A small public surface. Only SSH, HTTP and HTTPS are open. Caddy handles HTTPS and streams live call events to the browser without buffering.
- A spend ledger that fails closed. Every model request reserves its maximum cost before it's sent. Each vendor has a hard dollar ceiling. If the ledger is down or the cap is reached, the request is refused.
- Safe deploys. The deploy script refuses to run during an active investigation, never copies a secrets file or a database, and keeps every release so a rollback is one symlink.
We ran a real-model investigation from the server: our attacker spent 12 turns trying to get a card reported lost, and the agent held.
How we used Tiger Data
Every WisprNo call is a stream of timestamped events: a caller line, an agent reply, a tool call, a verdict. The questions we care about are questions over time. Is this version of the agent safer than the last one? Did a breach we closed come back?
- A hypertable of call events. 64,620 events from our experiment, one row each, with the raw event kept alongside so nothing is lost.
- A continuous aggregate. It rolls events up by agent version and test case into counts of breached, held and inconclusive calls, plus how many normal callers finished. Our outcomes chart reads from it.
- A table of fix attempts. Every proposed fix, whether the replay accepted it, and why.
- Automatic sync for new runs. When an investigation finishes, WisprNo saves it locally first, then syncs it to Tiger Data as one bundle with a content hash. Syncing twice never duplicates a row. If the database is unreachable, the run stays safe on disk and the Past analyses page offers a retry.
- Simulated and real runs kept apart. Each run is labelled with how it was produced, so a scripted rehearsal can never be counted as a real result.
Tiger Data is what turns one test into a history. A team can run WisprNo on every release and see the trend.
What we found
- A two-sentence call locked a stranger's debit card 10 times out of 10 on our baseline agent.
- We let a model rewrite the agent's prompt after each breach. 12 of 13 rewrites failed the replay.
- In a separate run, one server-side check took a card-lock attack to 0 of 20, and 20 of 20 normal callers still finished.
- On a live phone call, the receptionist filed a message under another person's name because the caller claimed to be her. A second call held for all five turns.
These numbers describe our test agents across about 2,400 calls. They are not a claim about voice agents in general.
Challenges
- Trusting the verdict. A transcript can read as a refusal while a tool has already fired. We rebuilt scoring around the record before and after each call.
- Flaky reproductions. Models don't repeat themselves. A breach that worked once often failed on replay, so every claim needed 10 or 20 runs behind it.
- Fixes that hurt customers. Several fixes stopped the attack and also blocked legitimate callers. We reject any fix that costs more than one normal call in 20.
- Connecting agents we didn't write. A hosted tool can't reach an agent on your laptop. We wrote a bridge contract and a pairing script so the agent never has to open a port.
- Spending. Thousands of model calls add up. Every run has a hard cap, and paid runs need explicit approval.
What we learned
Our first idea was hardware. In 2017, researchers at Zhejiang University published DolphinAttack. They put voice commands on an ultrasonic carrier above 20 kHz, too high for people to hear. A quirk in microphone hardware turned the signal back into speech, so Siri, Alexa and Google Assistant obeyed commands that nobody in the room could hear. We wanted to build a device like that for voice agents: sounds a phone could pick up and a person couldn't, which would mean the AI hears an instruction the human never does.
Then we looked at how a phone call carries sound. A standard call keeps roughly 300 to 3,400 Hz and throws the rest away. Ultrasound never reaches the agent on the other end. An inaudible attack needs a speaker near the microphone, so it threatens smart speakers and kiosks far more than a hotline.
That pushed us to the attack that does travel over any phone line: the conversation itself. It turned out to be the bigger problem, because it needs no hardware and no skill beyond persistence.
A prompt is a suggestion. A persistent caller can talk past it. The checks that held were the ones the server enforced.
Missing evidence is not a pass. When we couldn't confirm what happened, we marked the run inconclusive.
What's next
- CI/CD. Every breach already saves as a regression test. Next, those tests run on every change to an agent, and a new permission can't merge until they pass.
- Real-model attacks on the three new agents.
- Voice delivery as an attack. The same words, spoken calmly and frantically.
There's no SOC 2 for voice agents yet. We want WisprNo to become the check every voice agent passes before it's trusted with real permissions.