Skip to content

Commit 1465e39

Browse files
authored
fix: redact RPC URLs in traces if URL is passed in directly (#9077)
redact RPC urls if string is a URL, not an alias
1 parent 97ce8c3 commit 1465e39

File tree

1 file changed

+293
-1
lines changed
  • crates/evm/traces/src/decoder

1 file changed

+293
-1
lines changed

crates/evm/traces/src/decoder/mod.rs

Lines changed: 293 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,24 @@ impl CallTraceDecoder {
516516
Some(decoded.iter().map(format_token).collect())
517517
}
518518
}
519+
"createFork" |
520+
"createSelectFork" |
521+
"rpc" => {
522+
let mut decoded = func.abi_decode_input(&data[SELECTOR_LEN..], false).ok()?;
523+
524+
// Redact RPC URL except if referenced by an alias
525+
if !decoded.is_empty() && func.inputs[0].ty == "string" {
526+
let url_or_alias = decoded[0].as_str().unwrap_or_default();
527+
528+
if url_or_alias.starts_with("http") || url_or_alias.starts_with("ws") {
529+
decoded[0] = DynSolValue::String("<rpc url>".to_string());
530+
}
531+
} else {
532+
return None;
533+
}
534+
535+
Some(decoded.iter().map(format_token).collect())
536+
}
519537
_ => None,
520538
}
521539
}
@@ -558,6 +576,7 @@ impl CallTraceDecoder {
558576
"promptSecret" | "promptSecretUint" => Some("<secret>"),
559577
"parseJson" if self.verbosity < 5 => Some("<encoded JSON value>"),
560578
"readFile" if self.verbosity < 5 => Some("<file>"),
579+
"rpcUrl" | "rpcUrls" | "rpcUrlStructs" => Some("<rpc url>"),
561580
_ => None,
562581
}
563582
.map(Into::into)
@@ -670,7 +689,7 @@ mod tests {
670689
use alloy_primitives::hex;
671690

672691
#[test]
673-
fn test_should_redact_pk() {
692+
fn test_should_redact() {
674693
let decoder = CallTraceDecoder::new();
675694

676695
// [function_signature, data, expected]
@@ -726,13 +745,286 @@ mod tests {
726745
.to_string(),
727746
]),
728747
),
748+
(
749+
// cast calldata "createFork(string)" "https://eth-mainnet.g.alchemy.com/v2/api_key"
750+
"createFork(string)",
751+
hex!(
752+
"
753+
31ba3498
754+
0000000000000000000000000000000000000000000000000000000000000020
755+
000000000000000000000000000000000000000000000000000000000000002c
756+
68747470733a2f2f6574682d6d61696e6e65742e672e616c6368656d792e636f
757+
6d2f76322f6170695f6b65790000000000000000000000000000000000000000
758+
"
759+
)
760+
.to_vec(),
761+
Some(vec!["\"<rpc url>\"".to_string()]),
762+
),
763+
(
764+
// cast calldata "createFork(string)" "wss://eth-mainnet.g.alchemy.com/v2/api_key"
765+
"createFork(string)",
766+
hex!(
767+
"
768+
31ba3498
769+
0000000000000000000000000000000000000000000000000000000000000020
770+
000000000000000000000000000000000000000000000000000000000000002a
771+
7773733a2f2f6574682d6d61696e6e65742e672e616c6368656d792e636f6d2f
772+
76322f6170695f6b657900000000000000000000000000000000000000000000
773+
"
774+
)
775+
.to_vec(),
776+
Some(vec!["\"<rpc url>\"".to_string()]),
777+
),
778+
(
779+
// cast calldata "createFork(string)" "mainnet"
780+
"createFork(string)",
781+
hex!(
782+
"
783+
31ba3498
784+
0000000000000000000000000000000000000000000000000000000000000020
785+
0000000000000000000000000000000000000000000000000000000000000007
786+
6d61696e6e657400000000000000000000000000000000000000000000000000
787+
"
788+
)
789+
.to_vec(),
790+
Some(vec!["\"mainnet\"".to_string()]),
791+
),
792+
(
793+
// cast calldata "createFork(string,uint256)" "https://eth-mainnet.g.alchemy.com/v2/api_key" 1
794+
"createFork(string,uint256)",
795+
hex!(
796+
"
797+
6ba3ba2b
798+
0000000000000000000000000000000000000000000000000000000000000040
799+
0000000000000000000000000000000000000000000000000000000000000001
800+
000000000000000000000000000000000000000000000000000000000000002c
801+
68747470733a2f2f6574682d6d61696e6e65742e672e616c6368656d792e636f
802+
6d2f76322f6170695f6b65790000000000000000000000000000000000000000
803+
"
804+
)
805+
.to_vec(),
806+
Some(vec!["\"<rpc url>\"".to_string(), "1".to_string()]),
807+
),
808+
(
809+
// cast calldata "createFork(string,uint256)" "mainnet" 1
810+
"createFork(string,uint256)",
811+
hex!(
812+
"
813+
6ba3ba2b
814+
0000000000000000000000000000000000000000000000000000000000000040
815+
0000000000000000000000000000000000000000000000000000000000000001
816+
0000000000000000000000000000000000000000000000000000000000000007
817+
6d61696e6e657400000000000000000000000000000000000000000000000000
818+
"
819+
)
820+
.to_vec(),
821+
Some(vec!["\"mainnet\"".to_string(), "1".to_string()]),
822+
),
823+
(
824+
// cast calldata "createFork(string,bytes32)" "https://eth-mainnet.g.alchemy.com/v2/api_key" 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
825+
"createFork(string,bytes32)",
826+
hex!(
827+
"
828+
7ca29682
829+
0000000000000000000000000000000000000000000000000000000000000040
830+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
831+
000000000000000000000000000000000000000000000000000000000000002c
832+
68747470733a2f2f6574682d6d61696e6e65742e672e616c6368656d792e636f
833+
6d2f76322f6170695f6b65790000000000000000000000000000000000000000
834+
"
835+
)
836+
.to_vec(),
837+
Some(vec![
838+
"\"<rpc url>\"".to_string(),
839+
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
840+
.to_string(),
841+
]),
842+
),
843+
(
844+
// cast calldata "createFork(string,bytes32)" "mainnet"
845+
// 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
846+
"createFork(string,bytes32)",
847+
hex!(
848+
"
849+
7ca29682
850+
0000000000000000000000000000000000000000000000000000000000000040
851+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
852+
0000000000000000000000000000000000000000000000000000000000000007
853+
6d61696e6e657400000000000000000000000000000000000000000000000000
854+
"
855+
)
856+
.to_vec(),
857+
Some(vec![
858+
"\"mainnet\"".to_string(),
859+
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
860+
.to_string(),
861+
]),
862+
),
863+
(
864+
// cast calldata "createSelectFork(string)" "https://eth-mainnet.g.alchemy.com/v2/api_key"
865+
"createSelectFork(string)",
866+
hex!(
867+
"
868+
98680034
869+
0000000000000000000000000000000000000000000000000000000000000020
870+
000000000000000000000000000000000000000000000000000000000000002c
871+
68747470733a2f2f6574682d6d61696e6e65742e672e616c6368656d792e636f
872+
6d2f76322f6170695f6b65790000000000000000000000000000000000000000
873+
"
874+
)
875+
.to_vec(),
876+
Some(vec!["\"<rpc url>\"".to_string()]),
877+
),
878+
(
879+
// cast calldata "createSelectFork(string)" "mainnet"
880+
"createSelectFork(string)",
881+
hex!(
882+
"
883+
98680034
884+
0000000000000000000000000000000000000000000000000000000000000020
885+
0000000000000000000000000000000000000000000000000000000000000007
886+
6d61696e6e657400000000000000000000000000000000000000000000000000
887+
"
888+
)
889+
.to_vec(),
890+
Some(vec!["\"mainnet\"".to_string()]),
891+
),
892+
(
893+
// cast calldata "createSelectFork(string,uint256)" "https://eth-mainnet.g.alchemy.com/v2/api_key" 1
894+
"createSelectFork(string,uint256)",
895+
hex!(
896+
"
897+
71ee464d
898+
0000000000000000000000000000000000000000000000000000000000000040
899+
0000000000000000000000000000000000000000000000000000000000000001
900+
000000000000000000000000000000000000000000000000000000000000002c
901+
68747470733a2f2f6574682d6d61696e6e65742e672e616c6368656d792e636f
902+
6d2f76322f6170695f6b65790000000000000000000000000000000000000000
903+
"
904+
)
905+
.to_vec(),
906+
Some(vec!["\"<rpc url>\"".to_string(), "1".to_string()]),
907+
),
908+
(
909+
// cast calldata "createSelectFork(string,uint256)" "mainnet" 1
910+
"createSelectFork(string,uint256)",
911+
hex!(
912+
"
913+
71ee464d
914+
0000000000000000000000000000000000000000000000000000000000000040
915+
0000000000000000000000000000000000000000000000000000000000000001
916+
0000000000000000000000000000000000000000000000000000000000000007
917+
6d61696e6e657400000000000000000000000000000000000000000000000000
918+
"
919+
)
920+
.to_vec(),
921+
Some(vec!["\"mainnet\"".to_string(), "1".to_string()]),
922+
),
923+
(
924+
// cast calldata "createSelectFork(string,bytes32)" "https://eth-mainnet.g.alchemy.com/v2/api_key" 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
925+
"createSelectFork(string,bytes32)",
926+
hex!(
927+
"
928+
84d52b7a
929+
0000000000000000000000000000000000000000000000000000000000000040
930+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
931+
000000000000000000000000000000000000000000000000000000000000002c
932+
68747470733a2f2f6574682d6d61696e6e65742e672e616c6368656d792e636f
933+
6d2f76322f6170695f6b65790000000000000000000000000000000000000000
934+
"
935+
)
936+
.to_vec(),
937+
Some(vec![
938+
"\"<rpc url>\"".to_string(),
939+
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
940+
.to_string(),
941+
]),
942+
),
943+
(
944+
// cast calldata "createSelectFork(string,bytes32)" "mainnet"
945+
// 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
946+
"createSelectFork(string,bytes32)",
947+
hex!(
948+
"
949+
84d52b7a
950+
0000000000000000000000000000000000000000000000000000000000000040
951+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
952+
0000000000000000000000000000000000000000000000000000000000000007
953+
6d61696e6e657400000000000000000000000000000000000000000000000000
954+
"
955+
)
956+
.to_vec(),
957+
Some(vec![
958+
"\"mainnet\"".to_string(),
959+
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
960+
.to_string(),
961+
]),
962+
),
963+
(
964+
// cast calldata "rpc(string,string,string)" "https://eth-mainnet.g.alchemy.com/v2/api_key" "eth_getBalance" "[\"0x551e7784778ef8e048e495df49f2614f84a4f1dc\",\"0x0\"]"
965+
"rpc(string,string,string)",
966+
hex!(
967+
"
968+
0199a220
969+
0000000000000000000000000000000000000000000000000000000000000060
970+
00000000000000000000000000000000000000000000000000000000000000c0
971+
0000000000000000000000000000000000000000000000000000000000000100
972+
000000000000000000000000000000000000000000000000000000000000002c
973+
68747470733a2f2f6574682d6d61696e6e65742e672e616c6368656d792e636f
974+
6d2f76322f6170695f6b65790000000000000000000000000000000000000000
975+
000000000000000000000000000000000000000000000000000000000000000e
976+
6574685f67657442616c616e6365000000000000000000000000000000000000
977+
0000000000000000000000000000000000000000000000000000000000000034
978+
5b22307835353165373738343737386566386530343865343935646634396632
979+
363134663834613466316463222c22307830225d000000000000000000000000
980+
"
981+
)
982+
.to_vec(),
983+
Some(vec![
984+
"\"<rpc url>\"".to_string(),
985+
"\"eth_getBalance\"".to_string(),
986+
"\"[\\\"0x551e7784778ef8e048e495df49f2614f84a4f1dc\\\",\\\"0x0\\\"]\""
987+
.to_string(),
988+
]),
989+
),
990+
(
991+
// cast calldata "rpc(string,string,string)" "mainnet" "eth_getBalance"
992+
// "[\"0x551e7784778ef8e048e495df49f2614f84a4f1dc\",\"0x0\"]"
993+
"rpc(string,string,string)",
994+
hex!(
995+
"
996+
0199a220
997+
0000000000000000000000000000000000000000000000000000000000000060
998+
00000000000000000000000000000000000000000000000000000000000000a0
999+
00000000000000000000000000000000000000000000000000000000000000e0
1000+
0000000000000000000000000000000000000000000000000000000000000007
1001+
6d61696e6e657400000000000000000000000000000000000000000000000000
1002+
000000000000000000000000000000000000000000000000000000000000000e
1003+
6574685f67657442616c616e6365000000000000000000000000000000000000
1004+
0000000000000000000000000000000000000000000000000000000000000034
1005+
5b22307835353165373738343737386566386530343865343935646634396632
1006+
363134663834613466316463222c22307830225d000000000000000000000000
1007+
"
1008+
)
1009+
.to_vec(),
1010+
Some(vec![
1011+
"\"mainnet\"".to_string(),
1012+
"\"eth_getBalance\"".to_string(),
1013+
"\"[\\\"0x551e7784778ef8e048e495df49f2614f84a4f1dc\\\",\\\"0x0\\\"]\""
1014+
.to_string(),
1015+
]),
1016+
),
7291017
];
7301018

7311019
// [function_signature, expected]
7321020
let cheatcode_output_test_cases = vec![
7331021
// Should redact private key on output in all cases:
7341022
("createWallet(string)", Some("<pk>".to_string())),
7351023
("deriveKey(string,uint32)", Some("<pk>".to_string())),
1024+
// Should redact RPC URL if defined, except if referenced by an alias:
1025+
("rpcUrl(string)", Some("<rpc url>".to_string())),
1026+
("rpcUrls()", Some("<rpc url>".to_string())),
1027+
("rpcUrlStructs()", Some("<rpc url>".to_string())),
7361028
];
7371029

7381030
for (function_signature, data, expected) in cheatcode_input_test_cases {

0 commit comments

Comments
 (0)