Avoid writing to instance storage from __check_auth until X-Ray upgrade

13 views
Skip to first unread message

Justin

unread,
Dec 2, 2025, 3:09:19 PM (5 days ago) Dec 2
to Stellar Developers
Hello Stellar Devs,

I'm sharing a message from this Github issue for visibility:

We have identified an issue in the Soroban host implemention that causes instance storage changes in `__check_auth` function to not be committed under very specific circumstances.

**Due to this issue, the recommendation for the custom account developers is to avoid modifying instance storage in `__check_auth` until the fix is rolled out in X-Ray: Protocol 25 in January.**

More specifically, if a smart contract account function modifies the instance storage *and* that function requires auth from the smart account itself *and* `__check_auth` function modifies the instance storage as well, then the instance storage changes from `__check_auth` call won't be committed to the ledger.

To the best of our understanding, there is no contract on-chain that has been affected by the issue. Moreover, only 2 contracts have been modifying the instance storage in `__check_auth`, and even for these 2 contracts there is seemingly no code path that would satisfy all the conditions.

This seems like a really rare use case that most of the developers won't encounter. Also, testing the contract in any test environment (including the local quickstart deployments) triggers the issue, so it's hopefully hard enough to deploy a vulnerable contract to the mainnet without noticing the issue (as long as some testing has been done).

Please feel free to ask any questions or raise any concerns in the #security-incidents channel.

Thank you!

Justin

unread,
Dec 3, 2025, 3:14:28 PM (4 days ago) Dec 3
to Stellar Developers
Hello again, Stellar devs,

While addressing the instance storage issue announced yesterday, another issue has been identified. Re-entrant `__check_auth` calls do not observe the changes that the parent call made to the instance storage. If an account contract modifies the instance storage, *then* calls `require_auth[_for_args]` for the current contract address, and then `__check_auth` tries to observe the modified value, it wouldn't see the modification.

**Due to this issue, we recommended to not modify custom account instance storage prior to calling `env.current_contract_address().require_auth[_for_args]()` until protocol 25 upgrade.** Note, that even after the issue is fixed in protocol 25, this usage pattern is unlikely to ever be valid - storage modifications should typically be conditioned on successful authorization.

Our analysis indicates that no contracts currently on-chain are affected. This is expected, as state modification is a privileged operation that typically follows authorization. Since modifying state before authorization represents an insecure pattern, we do not anticipate this issue impacting valid production contracts.

If you have questions, check out the Discord #security-incidents channel.  Thank you!
Reply all
Reply to author
Forward
0 new messages