Cloud Cost Security

What is a denial-of-wallet attack and how do you defend against it?

A denial-of-wallet (DoW) attack is an exploit where an attacker pumps traffic through your pay-as-you-go infrastructure to rack up massive bills on your credit card rather than knock your servers offline. While a traditional DDoS targets availability, DoW exploits cost-per-use architectures where services scale seamlessly while your liability grows at rates like $0.20 per 1 million AWS Lambda requests or $0.30 per million Cloudflare Worker calls.

According to OWASP LLM10:2025, "By initiating a high volume of operations, attackers exploit the cost-per-use model of cloud-based AI services, leading to unsustainable financial burdens on the provider and risking financial ruin." Because modern clouds scale out by default, defending against it requires setting strict usage boundaries before an automated bot runs through your bank account.

How Denial-of-Wallet Attacks Target Modern Stacks

DoW attacks hit wherever pricing meters individual invocations, compute time, or carrier fees. The attacker doesn't need to break your encryption or exploit zero-days; they just need an open endpoint that does expensive work behind the scenes.

Serverless compute and event loops

In serverless environments, every invocation costs money. AWS Lambda Event Functions bill based on requests and duration measured in GB-seconds. In US East (N. Virginia), you pay $0.20 per 1 million requests and $0.0000166667 per GB-second on x86 ($0.0000133334 on ARM), calculated from execution start until termination rounded up to the nearest 1 ms. If an endpoint allocates 10,240 MB of memory and runs near the standard 900-second maximum timeout, a flood of concurrent requests burns cash fast.

Worse, architectures that chain services together can create accidental amplification loops. Lambda includes recursive loop detection that stops invocations if a function runs approximately 16 times in the same chain across Amazon SQS, S3, SNS, and EventBridge Custom event buses. But it has blind spots:

  • Lambda cannot detect loops if Amazon DynamoDB forms part of the chain.
  • Notifications via the AWS Health Dashboard and email can take up to 3.5 hours to arrive after Lambda halts an invocation.
  • Lambda sends at most one recursive loop alert per function every 24 hours.

LLM APIs and Unbounded Consumption

OWASP LLM10:2025 classifies excessive, uncontrolled inferences as Unbounded Consumption. It maps to MITRE CWE-400 (Uncontrolled Resource Consumption), MITRE ATLAS AML.T0029 (Denial of ML Service), and MITRE ATLAS AML.T0034 (Cost Harvesting). Attack vectors include:

  • Variable-Length Input Flood: Overloading the model with inputs of varying lengths to exploit processing inefficiencies and deplete resources.
  • Continuous Input Overflow: Continuously sending inputs that exceed the model's context window to trigger high computational use.
  • Resource-Intensive Queries: Submitting complex queries with intricate language patterns that drive up token processing times.

Because LLM providers charge by the token, an unauthenticated chat route allows attackers to use your account for arbitrary computation.

SMS pumping and toll fraud

If your app has a phone verification form, attackers can exploit it via SMS pumping fraud. Fraudsters trigger one-time passcodes (OTPs) to ranges controlled by a mobile network operator that shares the revenue with them. Related to this is toll fraud, or International Revenue Sharing Fraud (IRSF), where attackers trigger automated voice calls to international premium rate numbers. The victim bears the full financial responsibility for every minute of fraudulent calls.

Layer 1: Edge Rate Limiting and WAF Rules

Your first line of defense is stopping garbage traffic before it hits billed compute.

Cloudflare WAF rate limiting rules let you define an expression, an action, characteristics, period, requests per period, and duration (mitigation timeout). On the Free plan, you get 1 rule tracking by IP, with a 10-second period and a 10-second timeout. Higher tiers add IP with NAT support, and Enterprise with Advanced Rate Limiting allows complexity score models. Be aware that Cloudflare rules have a delay of up to a few seconds between detecting a request and updating counters, meaning excess requests can reach your origin before the block triggers.

AWS WAF uses rate-based rules that count and aggregate requests over an evaluation window. A base rate-based rule statement costs 2 WCUs (Web ACL Capacity Units), plus 30 WCUs for each custom aggregation key, plus whatever scope-down statements you add. You can also rate limit using the targeted protection level of Bot Control, though that adds extra fees.

On Vercel, the platform-wide firewall includes free automated DDoS and TCP flood mitigation on all plans. You can also turn on Vercel Attack Mode, which is available on all plans at no cost. Attack Mode forces visitors to complete a security challenge, allows known search bots and webhooks through, and incurs zero costs for blocked traffic. If you're seeing bot floods hitting edge functions, see our guide on how do I stop bots and DDoS traffic from running up my Vercel bill?

Provider / FeatureFree Tier LimitsMetered Cost Beyond BaseMitigation Delay / Caveats
AWS Lambda (N. Virginia)1,000,000 requests, 400,000 GB-s per month$0.20 per 1M requests, $0.0000166667 per GB-s (x86)Default 1,000 regional concurrent executions; max 900s timeout
Cloudflare Workers100,000 requests/day, 10ms CPU timePaid: 10M requests and 30M CPU ms included; +$0.30 per 1M requests, +$0.02 per 1M CPU ms30s default max CPU time (configurable to 5m)
Cloudflare WAF Rate Limits1 rule, IP tracking only, 10s periodRequires paid plans for custom characteristicsDelays of up to a few seconds allow brief origin leak
Vercel Attack ModeFree on all plansFree and unlimited mitigationsChallenges browser traffic; standalone APIs may fail
Twilio Verify Fraud GuardBasic, Standard, Max levelsStandard has <1% false positives; Max <2%Protects SMS only; Voice channel is unsupported

Layer 2: Application Throttling and SMS Hardening

Edge firewalls don't catch low-and-slow attacks, so you must implement internal quotas and validate inputs.

OWASP LLM10:2025 recommends applying strict input validation so inputs don't exceed size limits, setting timeouts and throttling for heavy operations, and restricting the number of queued and total actions while using dynamic scaling. If you're building LLM features, check token counts and reject oversized payloads before calling the upstream model.

For SMS and voice, Twilio provides Verify Fraud Guard, which analyzes historical traffic and blocks destination prefixes when it spots pumping patterns. It protects SMS only (not Voice) across three protection levels:

  • Basic: Cautious blocking, best for North American domestic traffic.
  • Standard: Default setting, moderate blocking with less than 1% false positives.
  • Max: Aggressive blocking with under 2% false positives, suited for high-risk regions.

When Fraud Guard blocks a message, it logs Error 60410. Newly created Twilio accounts restrict SMS to your verified home country by default; sending to disabled regions returns Error 21408. For details on locking down telephony, read our breakdown on how do I stop SMS pumping and toll fraud on Twilio?.

To stop toll fraud, disable the Voice channel in the Twilio Console if you don't use it, or hide any "Call me instead" button until a user completes 3 time-delayed SMS attempts. Monitor your OTP conversion rate (validated OTPs divided by sent OTPs); if conversion drops sharply in an unexpected country, alert your team.

# Disable an AWS Lambda event source mapping when an input queue runs out of control
aws lambda list-event-source-mappings --function-name MyFunction
aws lambda update-event-source-mapping --uuid "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111" --no-enabled

Layer 3: Concurrency Limits and Provider Spend Caps

Alerts are useful, but hard caps prevent bankruptcy. Don't rely solely on informational notices. Cloudflare budget alerts, for example, send a single email notification when account-wide spend crosses a dollar threshold, but they are informational only and never pause usage.

Instead, enforce system caps that refuse traffic when reached:

Lambda Concurrency Caps

By default, AWS Lambda allows 1,000 concurrent executions per Region. You can set reserved concurrency on individual Event Functions to act as both a floor and ceiling at no extra cost. Setting a function's reserved concurrency to 0 immediately throttles it and halts event processing. You can allocate up to your Unreserved account concurrency minus 100 (which AWS keeps for unreserved functions).

# Cap a Lambda function to 100 concurrent executions
aws lambda put-function-concurrency --function-name my-function --reserved-concurrent-executions 100

# Emergency stop: throttle function to 0 executions
aws lambda put-function-concurrency --function-name my-function --reserved-concurrent-executions 0

For Lambda Web Functions, you can configure throttleConfig.rateLimit per endpoint; setting it to 0 blocks all incoming traffic.

Cloudflare Spend Policies

Cloudflare lets you configure spend policies for workers and durable_objects using POST /accounts/{account_id}/billing/spend-policies. You specify threshold_cents (minimum 1 cent). Setting the action to usage_block will cut off the product until the billing cycle ends when the threshold is reached. Each account can only have one enabled usage_block policy per product (a second returns HTTP 409). Note that evaluated balances are asynchronous estimates rather than real-time synchronous checks.

Vercel Spend Management

On Vercel Pro and Enterprise Flexible Commitment plans, owners can set an On-Demand Budget with Pause Production Deployments enabled:

# Set a $200 budget that pauses production when reached
vercel billing budgets set --amount 200 --pause --webhook https://example.com/spend

When paused, your production deployments return a 503 DEPLOYMENT_PAUSED error. Webhooks trigger at 50%, 75%, and 100% of the threshold. Remember: Vercel evaluates metered usage every few minutes, so pausing can trigger several minutes after crossing the mark, and it does not halt ongoing storage charges, AI Gateway API key calls, or v0 usage.

Layer 4: Monitoring and the Killswitch Strategy

When an attack bypasses rate limits or an API key leaks, you need a mechanism to cut access immediately. For emergency response steps if credentials get exposed, read what should I do in the first hour after an API key leaks?.

Most cloud consoles make emergency shutdowns painful because you have to navigate nested menus across different dashboards while your invoice ticks up. Having a predefined killswitch cuts reaction time from hours to seconds. To understand how to design one, read what is a cloud killswitch, and should I have one?.

Costbrake provides cross-provider budget monitoring and an opt-in, reversible killswitch called brakes. It tracks spend across 23 providers - including AWS, Cloudflare, Vercel, OpenAI, Anthropic, and Twilio. Checks run hourly on the Free plan, every 5 minutes on Pro ($12/month) and Team ($39/month), and speed up to every 1 minute during a spike (defined as an hour costing more than 3x the 7-day baseline and at least $5 above normal).

When a bill runs out of control, an admin can trigger a brake with two clicks. A brake only runs when confirmed; Costbrake never executes one automatically. Brakes pause or cap services without deleting infrastructure:

  • AWS: Throttles a Lambda function to 0, stops an EC2 instance, turns off an IAM key, or blocks Bedrock for a user.
  • Vercel: Pauses projects (returning 503 on production) or enables Attack Challenge Mode.
  • Cloudflare: Detaches domains, pauses queue deliveries, caps CPU time, or sets spend policies.
  • OpenAI / xAI: Freezes OpenAI monthly hard spend limits at $0.01 (paid requests fail with a 429 once OpenAI enforces it, usually within minutes), or disables an xAI API key and freezes xAI invoiced billing at $0.01.
  • Anthropic / OpenRouter: Disables specific API keys or sets limits to $0.
  • Twilio: Blocks high-risk voice destinations or suspends subaccounts.

You can wire it up by telling your agent to follow the agent setup instructions, or connect your keys directly.

Questions and answers

Can a DDoS attack increase my cloud bill?

Yes. If you run pay-per-request infrastructure like AWS Lambda, Vercel Serverless Functions, or unauthenticated LLM endpoints, a distributed flood translates directly into billable invocations and compute duration.

How does a denial-of-wallet attack differ from a traditional DDoS?

A standard DDoS aims to exhaust server resources so legitimate users cannot access the service. A denial-of-wallet attack exploits auto-scaling features so the service stays online while generating unsustainable operational costs for the account owner.

Does setting a billing alert protect me from denial-of-wallet attacks?

No. Standard alerts from providers like AWS, Cloudflare, or Twilio are informational notices sent by email or webhook. They inform you after spend occurs but do not automatically throttle services or stop requests on their own.

How fast can serverless recursive loops run up a bill?

Very quickly. While AWS Lambda halts loops across certain services after roughly 16 invocations in a chain, loops involving untracked services like DynamoDB will run continuously, and AWS dashboard notifications can take up to 3.5 hours to appear.

Does pausing Vercel deployments stop all billing?

No. Enabling Pause Production Deployments stops production web traffic with a 503 error, but it does not stop charges for AI Gateway API key calls, v0 usage, or existing storage assets like Vercel Blob and Container Registry images.

Sources

Updated