Your Agent Just Paid for Nothing: 6 Attacks on x402 Payments - Ishween Kaur, SoFi https://www.youtube.com/watch?v=YU1uD_YkpjU AI Engineer · 16 min · 179 sentences · sentence-level transcript from YouTube's caption track; each line begins at the time shown [00:01] [music] [00:12] Hi everyone. [00:12] I'm Ishreen Kaur. [00:13] I work at AI evaluation and autonomous systems, but today I got interested into agentic payments and that's when I explored X402 and started to attack it in a safe environment. [00:24] X402 protocol is still in a West Wild and I can understand from the attendance of the audience that while it's still there, uh but going ahead like I would first want to understand [00:35] how many of you have paid for subscription just to use something once? [00:41] Many of us, yeah, exactly. [00:42] Now, imagine you want to watch this one movie that is available on Disney Plus. [00:47] Just this one movie. [00:48] You do not even want Disney Plus for next 6 days. [00:51] What you do today is to create an account, start a subscription, enter your payment information, watch that one movie, and you need to remember to cancel yourself. [01:00] What if internet would have made it simpler for me is to just pay, request, pay, and receive what I want. [01:07] And now replace yourself with an agent. [01:10] An agent is trying to create a report for you, and it needs one market data point that is available on this API that says, "Hey, pay me 5 cents." [01:19] Should your agent just pay? [01:21] Probably not. [01:22] It should ask, "Is this seller allowed? [01:24] Is this the amount within my budget? [01:26] Is this the data what I approved for?" [01:28] And if answers are yes, yeah, paid. [01:32] Now, HTTP had a status code 402 for decades. [01:37] It was a placeholder. [01:39] It said that payment is required, but it never said how a machine can actually pay. [01:44] And X402 started to fill that gap by explaining how a machine can actually pay. [01:51] And Cloudflare is exploring it by paper crawl where publishers are actually pushing the data with saying, "Hey, pay me these money." [01:59] And it moving beyond saying allowing or blocking. [02:02] So, it is interesting to see that software is becoming a buyer now. [02:09] Now, what is XF02, and how does it work? [02:13] It has four entities, buyer, seller, facilitator, and a chain. [02:17] The buyer asks for the data. [02:19] It represents you or your organization. [02:21] The seller has the data, and it will say 402 and the payment requirements. [02:26] The buyer is going to sign that payment. [02:29] Now, a seller is going to send that to facilitator for verification and settlement. [02:35] It sends a valid signal if verification is a success, which is essentially verifying the signature of the buyer request, and then it can send a valid signal to seller to release the data, or can say like, "Hey, wait for settlement phase to move the payments, [02:48] and then I'll send the data." [02:52] Now, the interesting thing to notice is why on chain, why not credit card? [02:56] So, if you see, these are micro payments, like 10 cents, 1 cent, 1/3 of a cent. [03:01] If the transaction fee of a credit card is more than the thing that you are trying to buy, the payment itself become expensive, and it's illogical. [03:09] And if you observe closely, the 10 cents * 10,000 calls means $1,000 of payments moving on machine. [03:18] So, your payments needs to scale with agents. [03:24] Now, if you have built agents, you would have had autonomy conversations with yourself or with your colleagues that agent writes code, human is going to approve it. [03:32] Agent is going to draft an email, human is going to review that email and click that send. [03:37] Now, put payment on the other side of this line, agent can now pay. [03:41] But, agent doesn't have to be even broken to lose money. [03:45] And so, that's when I ask myself, what happens when I let my agent pay? [03:50] So, I was able to break this entire sequence in 20 different ways, and today I'm going to speak about six on the buyer and the seller side to see what it looks like to make it into production. [04:01] I'll give a sec. [04:02] Okay. [04:05] Now, the very first attack that I did was about price manipulation. [04:08] Now, I mentioned that a buyer is going to find a seller in a directory. [04:12] Now, that seller can list I'm available for 5 cents. [04:16] But, the actual payment comes in that header when we say 402 and the payment requirement. [04:21] And that header can change the price any moment in the last seconds. [04:25] And so, what if my buyer would have said like, "Okay, I I asked 50 cents. [04:29] I listed 5 cents. [04:30] I don't care." [04:31] Now, I was running this experiment and I create my own uh observability gra- diagrams where the run one was without any guard when I didn't added guard and it actually paid settled 50 cents [04:46] when the listed price was 5 cents. [04:50] So, and the next run when I did with the guard, it actually blocked it. [04:56] The reason it blocked essentially is because the buyer knows the listed price and the seller price. [05:01] Can't I do just code check of the two fields? [05:05] And that stopped my attacks, but it also uh didn't stop other attacks which was changing the wallet or the network. [05:11] Now, today I'm on base, tomorrow I'm on Ethereum or Solana. [05:14] Then, my wallet network is changing. [05:16] My wallet address can rotate and so, I need to check each of these fields to make sure that I'm paying the right seller the right amount. [05:23] So, we paid the right amount. [05:24] What if we pay the right amount twice? [05:27] A payment number is unique on chain and a duplicate payment number gets canceled on the chain. [05:33] Now, the buyer tries to send same payment number one, let's say, five times to the seller. [05:39] Seller is going to send that request to facilitator. [05:42] On the verification phase, we will just check the signatures and it will say, "Okay, I'm I'm valid." [05:48] Like, these requests look valid, so let's deliver the data. [05:51] And the seller will deliver the data. [05:53] But, during the settlement phase, essentially, one is going to get settled and four will get rejected because payment number needs to be unique on chain. [06:03] And the fix is simple because you can just have a shared storage where you can store all your payment numbers and be like these were already done or these are in progress and if any other payment number comes for the same, I'm I can share the saved copy. [06:18] Now this matters because if you have expensive data, confidential data, licensing activation uh and you are releasing those four different data to that same buyer in these four different requests on the same payment number, you are losing your data. [06:35] Now this same attack can happen on the buyer's side also. [06:38] For the retries. [06:40] Let's say a reply a reply timed out and I am doing a retry and I have a retry limit of three, but every retry is done with the with a different payment number. [06:49] And so you are going to get three charges for one summary that might be useful for you. [06:53] So be cautious when you are doing retries to use the same payment number uh so that only one charge happens. [07:03] Now the attack three was about free shopping. [07:06] Can I get things for free? [07:07] Now the buyer sends the payment request to the seller. [07:10] Seller is good. [07:11] Facilitator says valid and you deliver the data. [07:14] But during the settlement because of some insufficient funds in the buyer or inconsistent state, the payment gets reverted. [07:23] The fix looks simple that let's wait for settlement phase actually to happen and then release the data. [07:28] But that comes with a trade-off between the latency and the risk for the business use case you want to solve. [07:33] If the data is expensive, uh it's licensing or activation, it's provisioning, it is confidential data, it needs to be generated every request, then yes, waiting for settlement phase is a good choice. [07:44] But if data is at the cost of dollar to send the data on the valid signal for performance reasons. [07:55] Now the other way that free shopping can happen, let's say if you have two pages on delivering the same report. [08:01] One is behind the paywall while another is not. [08:04] And the buyer knows about the one which is not behind the paywall and he tries to hit that endpoint which can happen which happens a lot actually in software industry. [08:13] So, the test is simple that call every endpoint that you want behind the paywall and it should give you 402. [08:21] The third way that free shopping can happen is if you have cash for performance reasons on the seller side. [08:28] Now, your buyer sent a request to the seller, the seller sends the data, but it also cached the results for performance reason. [08:36] But, this cache is by default on the public URL. [08:39] And so, any subsequent buyer can hit that public URL on the cache and get the data for free. [08:46] The fix is two parts. [08:47] To have your cache on the server be on the seller side behind the paywall. [08:52] So, that you do a price check before releasing the saved data. [08:57] The second thing is if the data is getting generated every time, it's confidential or it's expensive, don't cache it. [09:03] There is a header in the cache with a cache control saying no store, which can essentially not going to store your data in the cache. [09:13] Now, for the fourth attack, we are done with three attacks, is that you have a seller which has multiple pages behind the paywall. [09:21] But, they don't speak to each other. [09:23] They don't know about each other. [09:24] Now, you do one payment which is payment number essentially 16 in this case and you fire the same to the both the pages. [09:31] They don't know and so, they are valid. [09:34] They deliver the data. [09:36] But, during the settlement phase, we know only one going to get settled because of payment number has to be unique. [09:44] So, the fix is we Remember, we had the shared storage and in the shared storage, we can have that claim number binded with the mapping of the page that you actually delivered. [09:54] So, that if any other delivery wants to happen on the same payment number, you can say 409 conflict and your data is secured there. [10:04] Attack number five is about the malicious discovery. [10:07] Now, how does buyer finds these sellers? [10:10] Buyer finds these sellers in a directory called Bazaar in X402 and it checks for that service works, but it doesn't check who runs it and who owns the wallet. [10:20] So, what if I create a look-alike of a real seller and I have a different domain now, different wallet, different price, but similar name or same name. [10:30] And my agent tried to pick that one because it was a cheaper cost. [10:34] And what if that look-alike is an attacker to you? [10:39] And so you actually give that to an attacker. [10:42] So, this is the suggestion that to have enterprises which are conservative to have an allow list of sellers that we do to only allow those sellers that are approved by your enterprises. [10:53] But when we are trying to do agentic workflows, we want to explore new different sellers always. [10:58] And in that case, having an allow list, block list, and approbation list helps where the new sellers that you discover, you can add it to probation list. [11:06] A human can review later. [11:09] You can have a cap like 4 hours, 24 hours of how your probation list gets filled out to understand what was the buyer's intent, what did the seller responded, and which seller was called. [11:19] Because even the honest sellers, they also rotate their domains, they rotate their wallet, and they rotate their price or network and coin. [11:28] And doing a fast check always won't help in knowing that the allow list is always true. [11:34] So, keeping the allow list active is the goal here to explore the right sellers. [11:43] Now, the attack number six is I think it might bring a lot of things together also about prompt injection. [11:48] So, the reply from the seller are text. [11:51] If it says like this summary is truncated, the full version is at premium summary. [11:57] It's just a suggestion. [11:57] It doesn't said like what you need to do. [12:00] Now, while I was running, uh I actually used I Let me see if I Yeah. [12:07] Actually used Llama 3.2 and uh just want to mention that the test that I was running was on uh base Sepolia and I use x402 off facilitator uh local test net here. [12:19] So, I was using llama 3.2 to decide like what to do when the seller's reply is about the premium summary. [12:26] The agent decided to actually fetch from the premium summary and it paid again. [12:31] So, what would have costed me 5 cents actually costed me 55 cents. [12:36] So, in this run when I did without any guard, if you see there is a premium summary that gets paid here. [12:43] And so, the 5 cents and 50 cents both get settled. [12:46] But, in the second run the same thing happened where the agent agent still decided to fetch it, but it got blocked. [12:54] Now, when I was experimenting with understanding how can I block these prompt injections, is essentially I tried two other different ways before coming into this is rejects check. [13:05] So, you know some filter words filler words like pay tiers premium and if you see that in your in the seller's response, you can be like, "Okay, this is an attack to me." [13:15] But, it would not catch those quite hints like if it says analyst usually prefers quality summary go to this. [13:23] And it's not an attack direct attack to the buyer. [13:28] And the other way is to have a model to actually see whether it's an attack or not, which actually works pretty well in most of the cases, but there could be attacks [13:36] where it won't pick the it won't judge that it is an attack. [13:41] So, what I did was that I know that in this particular turn in this run, I want my buyer to call only once. [13:49] And so, it should never call twice to any other seller in this particular turn. [13:54] That reduced my risk area and that is why I locked this plan to execute only once and that's when it got blocked even if the agent decided to pay to the premium summary. [14:06] So, that brought my attacks to zero here. [14:09] Um yeah. [14:11] I think the pattern that I want to give is um the payment can look right like most of the cases my payments look right, but I got the wrong outcome. [14:20] And so checking before the buyer gives the signing of the payment or checking before the seller gives the data is essentially needed and our traces should speak about those. [14:31] So, how to actually roll out to production or like how to experiment with these when I try to do it with in 20 different ways is essentially I used one payment ID and started to log [14:42] entire sequence diagram. [14:44] So, for your specific business use case you would be having an identic system workflow. [14:49] Start with one payment ID and trace it throughout that system. [14:52] That one payment ID should give you enough traces to help you understand what was the buyer's intent, what did seller responded and which seller was called. [15:00] If it's not giving then you need to add more traces to it. [15:03] So, that answers when you get you would then go to shadow phase where you will create 20 to 25 data set of success and a failure and perform error analysis [15:13] on them. [15:14] To understand where do you need guards, where do you need alerting and where do you need blocking this. [15:20] Those error analysis will then become in enforcement where you'll add guards, you'll add alerting and then you'll perform that same mechanism of tracing every time with these 20 to 25 different data set [15:35] to understand are these guards enough? [15:38] Do we want to get more aggressive or do we want to release these guards or still add just alerts or are we lenient? [15:45] Those questions will come those answers will actually come from these questions of going through those specific business use case and this is the work that matters. [15:54] If you remember the presentation before me mentioned about 65 industry benchmarks, they did trace by trace and so each thing needs to be done trace by trace to truly understand [16:05] what it is actually trying to perform. [16:08] Um yeah, with that I think I would just say this is the handbook that I created to share it with you to like how I added the code and you can actually [16:18] run it in the base Bolyai and have your own um runs there. [16:23] Can our agents pay? [16:24] Yes, but the real question is should we let them pay? [16:28] Yes, but now you know where to look it at. [16:31] Thank you. [16:31] I'll be outside for any questions and answers. [16:35] Thank you. [16:36] [applause]