Skip to content

Commit e90c74b

Browse files
authored
Release 3.9.1 (#1026)
### Fixes - Improve security of the `exit_to_near` precompile by [@aleksuss]. ([#1024]) [#1024]: #1024
1 parent 69a864f commit e90c74b

File tree

10 files changed

+1024
-25
lines changed

10 files changed

+1024
-25
lines changed

CHANGES.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [3.9.1] 2025-07-09
11+
12+
- Improve security of the `exit_to_near` precompile by [@aleksuss]. ([#1024])
13+
14+
[#1024]: https://github.com/aurora-is-near/aurora-engine/pull/1024
15+
1016
## [3.9.0] 2025-04-07
1117

1218
### Additions
@@ -756,7 +762,8 @@ struct SubmitResult {
756762

757763
## [1.0.0] - 2021-05-12
758764

759-
[Unreleased]: https://github.com/aurora-is-near/aurora-engine/compare/3.9.0...develop
765+
[Unreleased]: https://github.com/aurora-is-near/aurora-engine/compare/3.9.1...develop
766+
[3.9.1]: https://github.com/aurora-is-near/aurora-engine/compare/3.9.0...3.9.1
760767
[3.9.0]: https://github.com/aurora-is-near/aurora-engine/compare/3.8.0...3.9.0
761768
[3.8.0]: https://github.com/aurora-is-near/aurora-engine/compare/3.7.0...3.8.0
762769
[3.7.0]: https://github.com/aurora-is-near/aurora-engine/compare/3.6.4...3.7.0

Cargo.lock

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.9.0
1+
3.9.1

engine-precompiles/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ publish = true
1616
aurora-engine-modexp.workspace = true
1717
aurora-engine-sdk.workspace = true
1818
aurora-engine-types.workspace = true
19+
aurora-evm.workspace = true
1920
bn.workspace = true
2021
ethabi.workspace = true
21-
aurora-evm.workspace = true
2222
hex.workspace = true
2323
num.workspace = true
2424
ripemd.workspace = true
2525
sha2.workspace = true
2626
sha3.workspace = true
27+
serde.workspace = true
28+
serde_json.workspace = true
2729

2830
[dev-dependencies]
2931
aurora-engine-test-doubles.workspace = true
@@ -34,7 +36,7 @@ workspace = true
3436

3537
[features]
3638
default = ["std"]
37-
std = ["aurora-engine-types/std", "aurora-engine-sdk/std", "bn/std", "aurora-evm/std", "ripemd/std", "sha2/std", "sha3/std", "ethabi/std"]
39+
std = ["aurora-engine-types/std", "aurora-engine-sdk/std", "bn/std", "aurora-evm/std", "ripemd/std", "sha2/std", "sha3/std", "ethabi/std", "serde/std", "serde_json/std"]
3840
contract = ["aurora-engine-sdk/contract"]
3941
log = []
4042
error_refund = []

engine-precompiles/src/native.rs

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -518,11 +518,11 @@ fn exit_base_token_to_near(
518518
match exit_params.message {
519519
Some(Message::Omni(msg)) => Ok((
520520
eth_connector_account_id,
521-
format!(
522-
r#"{{"receiver_id":"{}","amount":"{}","msg":"{msg}"}}"#,
523-
exit_params.receiver_account_id,
524-
context.apparent_value.as_u128(),
525-
),
521+
ft_transfer_call_args(
522+
&exit_params.receiver_account_id,
523+
context.apparent_value,
524+
msg,
525+
)?,
526526
events::ExitToNear::Omni(ExitToNearOmni {
527527
sender: Address::new(context.caller),
528528
erc20_address: events::ETH_ADDRESS,
@@ -613,11 +613,7 @@ fn exit_erc20_token_to_near<I: IO>(
613613
// In this flow, we're just forwarding the `msg` to the `ft_transfer_call` transaction.
614614
Some(Message::Omni(msg)) => (
615615
nep141_account_id,
616-
format!(
617-
r#"{{"receiver_id":"{}","amount":"{}","msg":"{msg}"}}"#,
618-
exit_params.receiver_account_id, // the locker's account id in case of OMNI
619-
exit_params.amount.as_u128(),
620-
),
616+
ft_transfer_call_args(&exit_params.receiver_account_id, exit_params.amount, msg)?,
621617
"ft_transfer_call",
622618
None,
623619
events::ExitToNear::Omni(ExitToNearOmni {
@@ -795,6 +791,30 @@ fn parse_input(input: &[u8]) -> Result<&[u8], ExitError> {
795791
Ok(&input[1..])
796792
}
797793

794+
#[derive(serde::Serialize)]
795+
struct FtTransferCallArgs<'a> {
796+
receiver_id: &'a AccountId,
797+
amount: String,
798+
msg: &'a str,
799+
}
800+
801+
fn ft_transfer_call_args(
802+
receiver_id: &AccountId,
803+
amount: U256,
804+
msg: &str,
805+
) -> Result<String, ExitError> {
806+
if amount > U256::from(u128::MAX) {
807+
return Err(ExitError::Other(Cow::from("ERR_INVALID_AMOUNT")));
808+
}
809+
810+
serde_json::to_string(&FtTransferCallArgs {
811+
receiver_id,
812+
amount: format!("{amount}"),
813+
msg,
814+
})
815+
.map_err(|_| ExitError::Other(Cow::from("ERR_SERIALIZE_JSON")))
816+
}
817+
798818
pub struct ExitToEthereum<I> {
799819
io: I,
800820
#[cfg(not(feature = "ext-connector"))]
@@ -1274,4 +1294,38 @@ mod tests {
12741294
})
12751295
);
12761296
}
1297+
1298+
#[test]
1299+
fn test_ft_transfer_call_args() {
1300+
let receiver_id = "test.near".parse().unwrap();
1301+
let amount = U256::from(100);
1302+
let msg = "some message";
1303+
1304+
let args = super::ft_transfer_call_args(&receiver_id, amount, msg).unwrap();
1305+
let expected =
1306+
format!(r#"{{"receiver_id":"{receiver_id}","amount":"{amount}","msg":"{msg}"}}"#,);
1307+
assert_eq!(args, expected);
1308+
}
1309+
1310+
#[test]
1311+
fn test_ft_transfer_call_args_json_injection() {
1312+
let receiver_id = "test.near".parse().unwrap();
1313+
let amount = U256::from(100);
1314+
let msg = "some message\", \"amount\": \"1000"; // attempt to increase amount
1315+
1316+
let args = super::ft_transfer_call_args(&receiver_id, amount, msg).unwrap();
1317+
let expected = format!(
1318+
r#"{{"receiver_id":"{receiver_id}","amount":"{amount}","msg":"some message\", \"amount\": \"1000"}}"#
1319+
);
1320+
assert_eq!(args, expected);
1321+
}
1322+
1323+
#[test]
1324+
#[should_panic(expected = "ERR_INVALID_AMOUNT")]
1325+
fn test_ft_transfer_call_args_u256() {
1326+
let receiver_id = "test.near".parse().unwrap();
1327+
let amount = U256::from(u128::MAX) + 1;
1328+
let msg = "some message";
1329+
let _ = super::ft_transfer_call_args(&receiver_id, amount, msg).unwrap();
1330+
}
12771331
}

engine-tests-connector/src/utils.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,10 @@ impl TestContract {
7171
let worker = near_workspaces::sandbox()
7272
.await
7373
.map_err(|err| anyhow::anyhow!("Failed init sandbox: {:?}", err))?;
74-
let testnet = near_workspaces::testnet()
75-
.await
76-
.map_err(|err| anyhow::anyhow!("Failed init testnet: {:?}", err))?;
7774
let registrar: AccountId = "registrar".parse()?;
7875
let sk = SecretKey::from_seed(KeyType::ED25519, registrar.as_str());
7976
let registrar = worker
80-
.import_contract(&registrar, &testnet)
77+
.import_contract(&registrar, &worker)
8178
.transact()
8279
.await?;
8380
Self::waiting_account_creation(&worker, registrar.id()).await?;

engine-tests/src/utils/workspace.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub async fn deploy_engine_with_code(code: Vec<u8>) -> EngineContract {
2929
.with_code(code)
3030
.with_custodian_address("d045f7e19B2488924B97F9c145b5E51D0D895A65")
3131
.unwrap()
32-
.with_root_balance(NearToken::from_near(10000))
32+
.with_root_balance(NearToken::from_near(5000))
3333
.with_contract_balance(NearToken::from_near(1000))
3434
.deploy_and_init()
3535
.await

engine-workspace/src/node.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,9 @@ impl Node {
6666
.transact()
6767
.await?
6868
} else {
69-
let testnet = near_workspaces::testnet()
70-
.await
71-
.map_err(|err| anyhow::anyhow!("Failed init testnet: {:?}", err))?;
7269
let registrar = "registrar".parse()?;
7370
worker
74-
.import_contract(&registrar, &testnet)
71+
.import_contract(&registrar, worker)
7572
.transact()
7673
.await?
7774
};

engine/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "aurora-engine"
3-
version = "3.9.0"
3+
version = "3.9.1"
44
authors.workspace = true
55
edition.workspace = true
66
homepage.workspace = true

0 commit comments

Comments
 (0)