Skip to content

fix(lang): validate program_id in CPI Return<T>::get()#4411

Merged
jamie-osec merged 6 commits into
otter-sec:masterfrom
jamie-osec:fix/cpi-return-validate-program-id
Apr 16, 2026
Merged

fix(lang): validate program_id in CPI Return<T>::get()#4411
jamie-osec merged 6 commits into
otter-sec:masterfrom
jamie-osec:fix/cpi-return-validate-program-id

Conversation

@jamie-osec

Copy link
Copy Markdown
Collaborator

Based on #4231 but with some small tweaks
Closes #4232

Thanks for the PR @rz1989s!

@vercel

vercel Bot commented Apr 16, 2026

Copy link
Copy Markdown

@jamie-osec is attempting to deploy a commit to the Solana Foundation Team on Vercel.

A member of the Team first needs to authorize it.

@0x4ka5h

0x4ka5h commented Apr 16, 2026

Copy link
Copy Markdown
Collaborator

the pr lgtm, would be good to have a changelog aswell! Also please address failed CI

rz1989s and others added 4 commits April 16, 2026 17:47
Return<T>::get() calls get_return_data() which returns (program_id, data),
but the program_id was discarded via `let (_key, data) = ...` without
validation. This allows return data spoofing if another program calls
set_return_data() between the CPI and the get() call.

The fix stores the expected program_id (from CpiContext) in the Return<T>
struct and validates it in get(). A new get_unchecked() method preserves
the old behavior for cases where cross-program return data is intentional.

Applied to both codegen paths:
- lang/syn/src/codegen/program/cpi.rs (standard #[program])
- lang/attribute/program/src/declare_program/mods/cpi.rs (declare_program!)

Includes PoC test demonstrating the spoofing attack with 3 programs
(caller, callee, malicious) in tests/cpi-returns/.
@jamie-osec jamie-osec force-pushed the fix/cpi-return-validate-program-id branch from 43018fb to 9728979 Compare April 16, 2026 16:48
@jamie-osec jamie-osec force-pushed the fix/cpi-return-validate-program-id branch from 9728979 to 4cc63cd Compare April 16, 2026 16:56
@jamie-osec jamie-osec merged commit f634129 into otter-sec:master Apr 16, 2026
60 of 61 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CPI Return<T>::get() does not validate program_id from get_return_data()

3 participants