Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code accepts inconsistent serialised ChainId objects #996

Closed
mina86 opened this issue Nov 29, 2023 · 2 comments · Fixed by #1013
Closed

Code accepts inconsistent serialised ChainId objects #996

mina86 opened this issue Nov 29, 2023 · 2 comments · Fixed by #1013
Assignees
Labels
A: bug Admin: something isn't working

Comments

@mina86
Copy link
Contributor

mina86 commented Nov 29, 2023

Bug Summary

It’s possible to craft JSON or Borsh serialised object which deserialises into an inconsistent ChainId object which has invalid revision_number field.

Demonstration

use borsh::BorshDeserialize;
use ibc_core_host_types::identifiers::ChainId;

fn evil_borsh() -> ChainId {
    ChainId::try_from_slice(b"\x06\0\0\0foo-42\x45\0\0\0\0\0\0\0").unwrap()
}

fn evil_json() -> ChainId {
    serde_json::from_str(r#"{"id": "foo-42", "revision_number": 69}"#).unwrap()
}

fn show(id: ChainId) {
    println!("id: {}; revision: {}", id.as_str(), id.revision_number());
        // → id: foo-42; revision: 69
    let other = ChainId::new(id.as_str()).unwrap();
    println!("id: {}; revision: {}", other.as_str(), other.revision_number());
        // → id: foo-42; revision: 42
    // assert_eq!(id, other); // → panics
}

fn main() {
    show(evil_borsh());
    show(evil_json());
}

Solution

Either serialisation format should change or deserialisation should verify the object is valid.

IMO ideally ChainId would be serialised as a String without the revision_number and the revision would be filled in when deserialising. Alas, this would be an ABI breaking change.

ABI-stable alternative is for deserialise implementations to verify that the parsed object is correct.

(Side note: IMO revision_number shouldn’t even be a field in ChainId and instead it should be parsed when requested but that’s a separate matter).

Version

ibc-core-host-types = { version = "0.48.1", features = ["serde", "borsh"] }
@Farhad-Shabani
Copy link
Member

Awesome info @mina86! Thanks for flagging this. We'll dive into it and figure out the best way to tackle the situation.
I have a hunch that it might be the case for other identifiers too.

@Farhad-Shabani Farhad-Shabani added the A: bug Admin: something isn't working label Dec 1, 2023
@mina86
Copy link
Contributor Author

mina86 commented Dec 1, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A: bug Admin: something isn't working
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

3 participants