New Ethereum talks, every Monday. The week's conference uploads by event, in your inbox.

Loading player…

Coinbase Security Series: Why Web2 Security Is Critical in Web3 Systems |with @HackenClubEsp

BaseSun, Nov 9, 2025, 12:00 AM

These workshops are run by our internal security team, designed to teach you best practices coming from real-world Coinbase experience. #OnchainAppInsights #web3 #accountabstraction #erc4337 #onchain #onchainApps #gasless #base #basechain #coinbasewallet #crypto #web3 #apps #blockchainrewards #coinbase #blockchain

Transcript

All right. Hello everyone. Welcome to Coinbase Security Session episode 8. Uh, thank you for tuning in. I'll be the moderator for this episode.

My name is Elias and I'm on the offensive security team here at Coinbase. Olesa Blanka is a smart contract auditor at Hackin. Today she is presenting the importance of web 2 security in the web 3 domain. Personally, one of my favorite topics. Uh, if you have any questions, please post them in the chat and we'll try to get as many as we can towards the end.

Please observe the disclaimers that will be on the bottom of the screen. And with that, Alisa, the floor is yours.

Hi, nice to meet you all. I'm going to share my screen. And today we will talk about something that often gets overlooked in web three um in web tree discussions and web three security assessments the web two lawyer. So while smart contracts are usually the main focus of audits many real bugs actually exist outside of the chain. They exist in how off-chain logic interacts with onchain systems.

If this web two lawyer is weak, contract security may be not enough. And here is what we will cover today. Firstly, we will get some context and understand the main focus of most web 3 security discussions. Then we will look uh at common failure patterns between web 2 and smart contracts. I will walk you through real world scenarios and their impact and later we will we will see how those issues were actually remediated and finally I will give you some practical recommendations and we will discuss the most interesting takeaways.

So in many security assessments the main focus is on what is deployed onchain but a typical web 3 application is not just a smart contract it's a hybrid of both smart contracts and web two components. So web two handles authentification admin panels business logic asset indexing metadata and so on. And if any of these parts is weak or if uh some of those parts are not aligned with zone chain truths, they can become the entry point for very serious exploits. And uh based on real audits, there are failure patterns seen over and over again and they are structural issues in how web 2 communicates with web 3. And today we will go through some of them.

Not all but enough to show clear real world risks. And to make it more practical and interesting, I decided to take real examples from an actual web free game where those vulnerabilities were identified and later remediated. So the first pattern is split call workflow. It happens when the business logic is split uh for between two calls. One is onchain transaction and one is for ofchain API update and if those two calls are not synchronized a window opens where the state can diverge and that's exactly the gap for the attackers and it's not a smart contract bug but the system is exploitable.

So this is an example of race condition vulnerability. Here is what it looks like in practice. Uh imagine a web free game where there is a flow of NFT importing where the first step is an NFT minting and then NFT registration to the web 2 lawyer. And this web 2 lawyer contains a lot of business logic not connected to the web 3. So like uh some bonuses and things like that uh and some gaming stuff.

So web two lawyer is uh big enough. So uh everything starts when user uh starts an assert import the onchain transaction is triggered and after that the client calls API to register the um token with its owner to update the offchain state its DB. But as we see here there is a gap between those calls and this gap is unsynchronized window where state may diverge the owner may change here but the back end will know nothing about that and here is how an attacker can abuse this gap. This is the same scenario but we have not a usual user but an attacker. So attacker calls mint then there is a call to the API and here is a gap but an attacker between those two calls sells this NFT so they uh are not owner of this NFT anymore.

They get some profit from it uh some funds some bonuses uh etc. But back end accepts this attacker address as an owner and absorts is to the database. So attacker is store as the owner of chain while it they doesn't own this entity on chain. And here what why it works the back end simply takes what client sent to it because it's like a single flow just two-step flow and it trusts it. But there is no check against the chain state which may differ already.

Here is where the problem starts. Here there is um a vulnerable back end code. The back end fully trusts the owner field provided by the client here and there is no check against the onchain state and no locking mechanism. And even if this road is protected, is access controlled, it doesn't eliminate the gap between onchain and offchain calls. Essentially, the initial NFT owner becomes the owner in the back end and this creates a race window between minting and registration that attacker can easily exploit.

To break it down, the back end trusted the owner address sent by the client. There was no check for the onchain ownership and any address was able to abuse this NFT ownership during this gap. This is a web two and web three trust boundary failure. The impact here is actually huge because NFTs can be imported without real uh owner consent and uh the uh in the database stores the attacker as an NFT owner allowing allowing them to use it as own token and real owner is blocked from using this token. So the state in product becomes inconsistent and it leaves it leads to the bro fairness and uh it may it the attacker may gain some bonuses and depending on the game state.

So the contract was not broken but the system was. Let's look at how this was fixed. Here is the original vulnerable code. Again, our goal is to remove this trust um in client input and to close this window to close this race window between onchain and offchain state. So, we need to synchronize those two steps.

This fix moves this registration logic from the client call to the trusted worker. Instead of the client calling the API directly, the beant listens to an onchain events. So once the event is confirmed uh on chain, the work queries the actual owner and only after this uh registers in it internally and abserts is to the database. That means that ownership now is derived from the blockchain not the user. Here is the observed the code for this you for this worker.

We wait for some amount of confirmations. We listen to the mint events and we perform double check and only after this we do the internal absort. Um but another important thing here that we need to handle block finalization and potential chain reorgs because events may be not valid yet and different networks have different finality guarantees. So the API we develop should be aware of that and only trust the state after it's fully finalized. So this worker approach hardens this bridge between web two and web ensures back end stage reflects on chain truth.

So very often applications break a single logical action into several steps. This creates a timing gap which u which may be abused by the attacker in case the back end or front end is slow. So our goal is to minimize these multi-step flows uh wherever possible to combine onchain and off-chain in one step. Off-chain updates should always be triggered from onchain events not client actions or not manual user actions. So we need to make sure that system uh also accounts for block finalization to ensure that we track for correct events and uh we need to remember that uh we need to set it up differently for each network because different networks finalize blocks differently.

Uh we should never trust front end timing. We need to revalidate state on action. we need to call smart contract again uh each time we do any sensitive operation and if uh the offchain state hasn't synced yet with the chain it's better to block the action because it's better to have a failed transaction or failed action than an exploitable gap. The second scenario is emosable but still very common problem here is also in hybrid web 2 web three systems but it's not about an attacker racing the system. It's about the system drifting away from the chain itself.

So whenever a product keeps asset state both onchain and offchain uh cache or database and this synchronization is delayed or unreli valid transfers can result in stale ownership or stale permissions because the back end no longer reflects the actual blockchain reality. This is the kind of code that causes it. This endpoint checks the ownership against the database only. Here there is no unchain verification. So in case database is out of sync, the product just believe it and ownership check is not correct here.

The consequences uh can be really serious here. Um it may lead to the host ownership. uh it may uh block uh correct users from uh actions they should be allowed to and the product will end up in a broken UI state often needing manual fixes and this is exactly the kind of bug that slipped through functional testing but hits production hard. Here is the example of uh such bug. For example, user A transfers NFT to user B on chain.

So on chain owner is changed but our cache is not updated yet. So back end uh still assumes that user A is an owner though user B is already an owner. That means that user A can keep performing of chain actions. They shouldn't be allowed to. So it even was not an attacker exploiting a bug, but it was a valid user who just unintentionally exploited uh this big design.

Let's fix it. The c the the core problem was not the transfer itself. It's uh the trust in stale data here. Uh so just like in the first case, the fix is to trust the chain, not the cache. And what is interesting here is that the fix here may actually be the same as in the first case.

But we can use this similarity to our advantage to dive a deeper a little deeper to understand how to design the fix properly. And once we get this pattern right, uh it may solve multiple classes of issues at once. The first step is to introduce an eventdriven worker. Just like in the first pattern, when a transfer happens, our event um and it is confirmed, event listener verifiers the owner from the smart contract and um updates the internal state. This keeps the backend state tightly coupled to the blockchain.

And here is the soda code for that. We listen to the transfer event, verify ownership and do internal things. Again, we need to make sure that the system accounts for block finalization. Here we do it, but we don't see the code because for each network, it should be done differently. So, this fix removes user input from the quotation and eliminates stale state at the source.

The second step is also very important. We shouldn't believe that we track everything. Uh even if we listen to all the events. Um we cannot rely on the cache or database. We need to recheck um we need to recheck ownership at each sensitive action.

So uh we need to call owner of token ID and based on this we need uh to decide whether we need to allow or deny based on the onchain information. So whenever a critical action happens like in our game uh use NFT uh we need to recheck revalidate the data on chain. So here even if we listen to the event we still call contract owner off and we revalidate if this step without the first one doesn't fully eliminate the drift but it prevents stale state from being exploitable. So the first step implementing uh the worker helps us to keep the data consistent and to show consistent data to store consistent data. But this step uh protects uh the system from really using incorrect data.

So it just it is a two-step protection. A lot of projects keep part of their logic both onchain and offchain. For example, ownership or pricing on the blockchain but meta data or user state in a database. And when these sources are not perfectly aligned, attackers can take advantage of the gap just like we saw before. So the first rule is to have a single source of truth for all critical checks.

And this source of truth is blockchain and onchain part. The database should only mirror what's already on chain not override it. Secondly, we need to rely on event listeners and trusted workers to front end input. So, uh this will prevent from indicating the incorrect data. Third, for each sensitive action like transfers or trades, we need to recheck the actual state from the chain in real time.

This will prevent users from using the incorrect data. And finally, as a good security practice, the drift monitoring should be set up. So from time to time, reconceal the database with the onchain state. This will prevent from prevent silent inconsistencies from becoming exploitable bugs. The third case is one of the most common architectural weaknesses we see in hippid web 2 and web 3 systems.

And we even often see this in smart contract audits. Uh here um uh here it's not a bug in the contract. It's a gap between where business rules live and where they are actually inform uh enforced. This is the most simple case. Uh this one is the most simple case but also critical.

In this setup, the critical rules live only in the back end. The contract trusts anything uh that passed to it assuming that the back end will always act as a gatekeeper. But attackers as we know can just keep the gatekeeper and talk to the contract directly. So as a result, the contract executes with completely unverified parameters. Let's move to a more interesting example.

This is a classic example of what what happens when business logic is enforced inconsistently between off-chain and onchain lawyers. Here the back end and front end enforce a price limit of 100 but smart contract has no or weak enforcement. The UI displays the expected value, but an attacker ignores the front end completely, calls the contract directly, and uses a much lower value because the contract doesn't enforce the same business rule. Then transaction goes through and that's how attackers exploit the weaker enforcement lawyer. So as a result the back end and contract states diverge, business rules break and the system may end up with corrupted listing listings or stolen value in case um limits in the back end are stricter than in smart contract.

This may lead to the broken UI weeks and to the failed transactions. Here is what happens when the back end assumes it's a source of truth. It enfors it enforces its own limit 100 but the contract doesn't necessarily follow the same rule. So this work with may this make work works fine if everyone uses the front end but attackers may not use it. So on chain the contract has a different limit uh or none at all.

the attacker just ignores the back end and calls the contract directly minted 1,000 instead of 100. So the back end thinks everything is under control but the contract accepts the transaction. This gap between offchain and onchain enforcement creates multiple attack surfaces. Firstly can completely bypass backend checks. Secondly, they can manipulate supply or other critical values directly through the contract.

This may lead to the broken transactions in case back end implements those rules incorrectly in case those rules are more strict in the backend side. Uh also this may lead to the broken business invariance because in case rules enforced off chain are not guaranteed on chain this fully breaks the system. Here is the secure version. Um here is a secure version of the contract. We just ensure that um limit is the same as in the back end and we ensure that smart contract implement the same business logic and limit as a back end.

The the remediation principles are like this cont uh web two web three systems should have single source of truths the chain or cryptographically signed messages. back end rules should be should either mirror directly the smart contract rules or just create uh signed messages which will be verified on chain and there shouldn't be no divergence between backend rules and uh onchain rules. So in many um hybrid systems the weakest point isn't um the smart contract it's a web two lawyer that connects to its teams build strong back end uh strong back end enforce limits validate inputs but if this logic is not cryptographically tied to the contract is just a suggestion not a rule because it can be easily bypassed. So once once somebody may passes the web to lawyer the contract will trust whatever comes in and that's where things break. So the first rule here is onchain rule enforcement.

All the critical rules should be enforced on chain. In case um logic has to remain offchain for business reasons. cryptographic signing should be used and contract should verify it and this cryptographic should be implemented uh correctly as well. Uh and finally uh rule alignment should be strictly followed. We need to make sure that web 2 and web 3 use the same data models and limits.

And as the last uh good security practice uh test for drift should should be done by done by by time time by time. So we should compare back end and contract enforcement pass. We should validate where the all the limits and rules are the same. To wrap this all up, even if the core logic lives fully on chain, web two remains the main attack surface in hybrid systems. Most of the real exploits we see today happen because back end or ofchain logic can be bypassed.

Every critical check must either leave onchain or be cryptographically verifiable. anything else can be forged. Also, good old web two security practices don't disappear in web 3. Authentification, input validation, login, monitoring, they all matter. And uh finally, test both web two and web three together.

Compare back end and chain if enforcement pass to make sure there is no diver chess because in the end most vulnerabilities are not in the blockchain itself but in the bridge between web two and web 3. Thank you for attention.

Amazing. Cool. Uh it looks like there was um uh one question one question that came in. So I think we can start with that. Um, they're basically wondering if removing the transfer function makes the SP token uh fully safe or if there are other ways people could try and game or exploit it.

Um, the the question itself, are there any specific checks or attack vectors to consider for non-transferable fungeable tokens that are being used as XP within our ecosystem? He removed the transfer function but wanted to better understand if there's any spe anything anything specific they should check or be on the lookout for.

Oh even in case transfer is removed we cannot rely that the owner is not changed because the contracts may be upgradable and unchain and chain is not unch state unchangeable. we still need to verify the owner of the NFT token and um even if we do not listen to events because this may waste our resources because transfer is removed we need to verify the owner for each critical operation and set the main rule because the main uh the main rule of web two and web 3 uh secure integration is the single source of truth which is onchain part so I believe that's uh the main role for for this.

Cool. Uh with a focus on you people coming into web 3, what are the best tools that you can you would recommend people use?

Oh uh that's interesting. I would recommend using uh just uh some codes editor and to try to implement some smart contracts by themsel, some uh simple um simple tokens and uh for the first tries u some remix can be used to to try to call those functions to see how state change. uh and uh after that um we can go to the foundry to the uh to to the heart head and to to try to create some coverage. So and uh basically that's that should cover all the in initial uh initial stuff.

Nice. Um, how can organizations effectively train their web 2 security teams to identify and address these web 3 specific or cross collaboration vulnerabilities that they were talking about? Uh yeah, as always, organizations should provide this security training and uh regarding the free web free security, those sessions should be provided as well and smart contract risks should be discussed there and very important, very often discussed, but still private key management should be discussed and because as far as we know a lot of a lot of The exploits happen because of weak private key management and also trust boundaries between onchain and off-chain components should be discussed and also uh when doing web free audits uh it is good for the whole team participating in it. So like when um they uh do the audit to then the whole team can read the audit report and then they will like understand better what are the main risks.

Amazing. What is the most effective strategies for fostering collaboration between web 2 and web 3 development teams to improve the overall security posture? uh the most important thing because everything starts with the design creation and uh in case design is wrong this may lead to the issues later. So when uh the design uh is created there should be shared security ownership involving both web two and web three teams. So they will create common documentation, common security standard and uh security communication channels to bridge knowledge gaps.

Each team will uh like share knowledge about risks and then the design of both will like ensure that the communication between those parts is uh good. Sometimes uh there are some tools which can be shared and uh as in the previous question training sessions can be like for can be done for both teams together.

Uh how can incident response plans be adapted to effectively address security breaches that span both web 2 and web 3 components? Oh, there should be uh like um defined steps for example key revocation in case of exploit or incident uh some smart contract pausing or emergency withdraw depending on the smart contract or some other onchain stops into a traditional web two instead pay play playbook. So um those steps should be connected and they should be like uh done together. So ensure joint response teams are trained to coordinate across centralized infrastructure and decentralized components in real time.

Perfect. I think that's all the questions we had. I'll give it maybe three more seconds of just awkward silence just to see if anything quickly comes in. Um but thank you. Thank you for for joining today's session.

Uh Alicia, thank you for your time uh presenting here. Um in two weeks, we will also have the ninth episode where Opel from Bloxseack will be presenting approaching secure signature validation and smart contracts uh going once. I'm not seeing anything new coming in. So thank you guys everyone for for tuning in and have a great rest of your day.

Automatic transcript — names and jargon may be misspelled.