From d59acbaade2ff0df6e1fe6b5b57a208942ca1b36 Mon Sep 17 00:00:00 2001 From: Ruslan Pislari Date: Mon, 29 Jun 2026 13:12:44 +0300 Subject: [PATCH] feat: enhance backend host validation to support hostname extraction feat: add FastEdge app ID to outbound requests for backend correlation --- Cargo.lock | 609 +++++++----------- crates/http-backend/src/lib.rs | 211 +++++- crates/http-service/src/executor/http.rs | 5 + crates/http-service/src/executor/wasi_http.rs | 4 + crates/http-service/src/state.rs | 100 ++- crates/runtime/src/lib.rs | 6 + src/context.rs | 2 + 7 files changed, 545 insertions(+), 392 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dfc3f3c..85d615d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,9 +151,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "backon" @@ -193,9 +193,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "block-buffer" @@ -208,9 +208,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" +checksum = "2f3f6da4992df95bbcd9af42a6c7dcb994498fc9048230405f3b36ff7cd3f145" dependencies = [ "bytes", "cfg_aliases", @@ -218,9 +218,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" dependencies = [ "allocator-api2", ] @@ -253,15 +253,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" [[package]] name = "bytesize" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd91ee7b2422bcb158d90ef4d14f75ef67f340943fc4149891dcce8f8b972a3" +checksum = "49e78e506b9d7633710dab98996f22f95f3d0f488e8f1aa162830556ed9fc14d" [[package]] name = "cache" @@ -412,9 +412,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.61" +version = "1.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" dependencies = [ "find-msvc-tools", "jobserver", @@ -436,9 +436,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", @@ -578,28 +578,28 @@ dependencies = [ [[package]] name = "cranelift-assembler-x64" -version = "0.123.7" +version = "0.123.12" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.123.7" +version = "0.123.12" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.123.7" +version = "0.123.12" dependencies = [ - "cranelift-entity 0.123.7", + "cranelift-entity 0.123.12", ] [[package]] name = "cranelift-bitset" -version = "0.123.7" +version = "0.123.12" dependencies = [ "serde", "serde_derive", @@ -607,8 +607,8 @@ dependencies = [ [[package]] name = "cranelift-bitset" -version = "0.123.7" -source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#67de3b777448d4f99850e7b3848238ef387032c6" +version = "0.123.12" +source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#62166f65ac52a1f164419097a2a533ff50e4d07b" dependencies = [ "serde", "serde_derive", @@ -616,16 +616,16 @@ dependencies = [ [[package]] name = "cranelift-codegen" -version = "0.123.7" +version = "0.123.12" dependencies = [ "bumpalo", "cranelift-assembler-x64", "cranelift-bforest", - "cranelift-bitset 0.123.7", + "cranelift-bitset 0.123.12", "cranelift-codegen-meta", "cranelift-codegen-shared", "cranelift-control", - "cranelift-entity 0.123.7", + "cranelift-entity 0.123.12", "cranelift-isle", "gimli", "hashbrown 0.15.5", @@ -641,7 +641,7 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.123.7" +version = "0.123.12" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -652,37 +652,37 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.123.7" +version = "0.123.12" [[package]] name = "cranelift-control" -version = "0.123.7" +version = "0.123.12" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.123.7" +version = "0.123.12" dependencies = [ - "cranelift-bitset 0.123.7", + "cranelift-bitset 0.123.12", "serde", "serde_derive", ] [[package]] name = "cranelift-entity" -version = "0.123.7" -source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#67de3b777448d4f99850e7b3848238ef387032c6" +version = "0.123.12" +source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#62166f65ac52a1f164419097a2a533ff50e4d07b" dependencies = [ - "cranelift-bitset 0.123.7 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", + "cranelift-bitset 0.123.12 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", "serde", "serde_derive", ] [[package]] name = "cranelift-frontend" -version = "0.123.7" +version = "0.123.12" dependencies = [ "cranelift-codegen", "log", @@ -692,11 +692,11 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.123.7" +version = "0.123.12" [[package]] name = "cranelift-native" -version = "0.123.7" +version = "0.123.12" dependencies = [ "cranelift-codegen", "libc", @@ -705,7 +705,7 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.123.7" +version = "0.123.12" [[package]] name = "crc32fast" @@ -819,9 +819,9 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", @@ -856,9 +856,9 @@ checksum = "e1d926b4d407d372f141f93bb444696142c29d32962ccbd3531117cf3aa0bfa9" [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "embedded-io" @@ -1167,7 +1167,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27d12c0aed7f1e24276a241aadc4cb8ea9f83000f34bc062b7cc2d51e3b0fabd" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "debugid", "fxhash", "serde", @@ -1446,15 +1446,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", - "wasip2", - "wasip3", ] [[package]] @@ -1470,9 +1468,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.13" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" dependencies = [ "atomic-waker", "bytes", @@ -1523,9 +1521,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heck" @@ -1547,9 +1545,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ "bytes", "itoa", @@ -1651,9 +1649,9 @@ checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "hyper" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", @@ -1740,7 +1738,7 @@ dependencies = [ "displaydoc", "potential_utf", "utf8_iter", - "yoke 0.8.2", + "yoke 0.8.3", "zerofrom", "zerovec", ] @@ -1807,7 +1805,7 @@ dependencies = [ "displaydoc", "icu_locale_core", "writeable", - "yoke 0.8.2", + "yoke 0.8.3", "zerofrom", "zerotrie", "zerovec", @@ -1847,7 +1845,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", "serde", "serde_core", ] @@ -1947,13 +1945,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.97" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -1979,9 +1976,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cc46bac87ef8093eed6f272babb833b6443374399985ac8ed28471ee0918545" +checksum = "c83bff1d572d6b9aeef67ddfc8448e4a3737909cb28e81f97c791b9018703e52" [[package]] name = "leb128fmt" @@ -2013,9 +2010,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ "libc", ] @@ -2049,9 +2046,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "mach2" @@ -2079,9 +2076,9 @@ checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" [[package]] name = "memfd" @@ -2094,9 +2091,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", "stable_deref_trait", @@ -2113,9 +2110,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi", @@ -2338,15 +2335,14 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openssl" -version = "0.10.78" +version = "0.10.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38c4372413cdaaf3cc79dd92d29d7d9f5ab09b51b10dded508fb90bb70b9222" +checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "cfg-if", "foreign-types", "libc", - "once_cell", "openssl-macros", "openssl-sys", ] @@ -2370,9 +2366,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-sys" -version = "0.9.114" +version = "0.9.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13ce1245cd07fcc4cfdb438f7507b0c7e4f3849a69fd84d52374c66d83741bb6" +checksum = "b47e7e6bb2c38cd930d25a23b40fa52e068c10e85f3e03a7f5ba5aaca5713695" dependencies = [ "cc", "libc", @@ -2456,18 +2452,18 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -2538,23 +2534,13 @@ dependencies = [ "log", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "proc-macro-crate" version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.11+spec-1.1.0", + "toml_edit 0.25.12+spec-1.1.0", ] [[package]] @@ -2572,7 +2558,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "hex", "procfs-core", "rustix 0.38.44", @@ -2584,7 +2570,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "hex", ] @@ -2627,9 +2613,9 @@ dependencies = [ [[package]] name = "pulley-interpreter" -version = "36.0.7" +version = "36.0.12" dependencies = [ - "cranelift-bitset 0.123.7", + "cranelift-bitset 0.123.12", "log", "pulley-macros", "wasmtime-internal-math", @@ -2637,7 +2623,7 @@ dependencies = [ [[package]] name = "pulley-macros" -version = "36.0.7" +version = "36.0.12" dependencies = [ "proc-macro2", "quote", @@ -2672,9 +2658,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -2775,7 +2761,7 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", ] [[package]] @@ -2813,9 +2799,9 @@ checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430" [[package]] name = "redis" -version = "1.2.0" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f44e94c96d8870a387d88ce3de3fdd608cbfc0705f03cb343cdde91509d3e49a" +checksum = "bae41a63fd0b8a5372f82b21e810e09a316f5dd7efd96bf08e678fb240fc1918" dependencies = [ "arc-swap", "arcstr", @@ -2847,7 +2833,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", ] [[package]] @@ -2877,9 +2863,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.3" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" dependencies = [ "aho-corasick", "memchr", @@ -2900,9 +2886,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "ring" @@ -2945,13 +2931,13 @@ dependencies = [ "utils", "wasi-common", "wasmtime", - "wasmtime-environ 36.0.7 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", + "wasmtime-environ 36.0.12 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", "wasmtime-wasi", "wasmtime-wasi-http", - "wasmtime-wasi-io 36.0.7 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", + "wasmtime-wasi-io 36.0.12 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", "wasmtime-wasi-nn", "wat", - "wit-component 0.246.2", + "wit-component", ] [[package]] @@ -2972,7 +2958,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -2985,7 +2971,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys 0.12.1", @@ -3103,7 +3089,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "core-foundation", "core-foundation-sys", "libc", @@ -3168,9 +3154,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -3246,9 +3232,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signal-hook-registry" @@ -3268,9 +3254,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" dependencies = [ "serde", ] @@ -3287,9 +3273,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", "windows-sys 0.61.2", @@ -3315,9 +3301,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", @@ -3341,7 +3327,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec7dddc5f0fee506baf8b9fdb989e242f17e4b11c61dfbb0635b705217199eea" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "byteorder", "enum-as-inner", "libc", @@ -3355,7 +3341,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01198a2debb237c62b6826ec7081082d951f46dbb64b0e8c7649a452230d1dfc" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "byteorder", "enum-as-inner", "libc", @@ -3369,7 +3355,7 @@ version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc4592f674ce18521c2a81483873a49596655b179f71c5e05d10c1fe66c78745" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "cap-fs-ext", "cap-std", "fd-lock", @@ -3398,7 +3384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix 1.1.4", "windows-sys 0.61.2", @@ -3507,9 +3493,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.52.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -3626,14 +3612,14 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow 1.0.2", + "winnow 1.0.3", ] [[package]] @@ -3642,7 +3628,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.2", + "winnow 1.0.3", ] [[package]] @@ -3764,9 +3750,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "ug" @@ -3846,11 +3832,11 @@ dependencies = [ [[package]] name = "uuid" -version = "1.23.1" +version = "1.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "js-sys", "wasm-bindgen", ] @@ -3900,11 +3886,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi-common" -version = "36.0.7" -source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#67de3b777448d4f99850e7b3848238ef387032c6" +version = "36.0.12" +source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#62166f65ac52a1f164419097a2a533ff50e4d07b" dependencies = [ "anyhow", - "bitflags 2.11.1", + "bitflags 2.13.0", "cap-fs-ext", "cap-rand", "cap-std", @@ -3918,33 +3904,24 @@ dependencies = [ "thiserror 2.0.18", "tracing", "wasmtime", - "wiggle 36.0.7 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", + "wiggle 36.0.12 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", "windows-sys 0.60.2", ] [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.120" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -3955,9 +3932,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.120" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3965,9 +3942,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.120" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", @@ -3978,9 +3955,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.120" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] @@ -3995,16 +3972,6 @@ dependencies = [ "wasmparser 0.236.1", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser 0.244.0", -] - [[package]] name = "wasm-encoder" version = "0.246.2" @@ -4017,24 +3984,12 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.248.0" +version = "0.252.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac92cf547bc18d27ecc521015c08c353b4f18b84ab388bb6d1b6b682c620d9b6" +checksum = "8185ae345fa5687c054626ff9a50e7089797a343d9904d1dc9820eb4c4d3196f" dependencies = [ "leb128fmt", - "wasmparser 0.248.0", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder 0.244.0", - "wasmparser 0.244.0", + "wasmparser 0.252.0", ] [[package]] @@ -4055,32 +4010,20 @@ version = "0.236.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9b1e81f3eb254cf7404a82cee6926a4a3ccc5aad80cc3d43608a070c67aa1d7" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "hashbrown 0.15.5", "indexmap", "semver", "serde", ] -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.11.1", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "wasmparser" version = "0.246.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71cde4757396defafd25417cfb36aa3161027d06d865b0c24baaae229aac005d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "hashbrown 0.16.1", "indexmap", "semver", @@ -4088,11 +4031,11 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.248.0" +version = "0.252.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4439c5eee9df71ee0c6efb37f63b1fcb1fec38f85f5142c54e7ed05d33091a" +checksum = "d3eb099dcadcde5be9eef55e3a337128efd4e44b4c93122487e4d2e4e1c6627c" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "indexmap", "semver", ] @@ -4110,12 +4053,12 @@ dependencies = [ [[package]] name = "wasmtime" -version = "36.0.7" +version = "36.0.12" dependencies = [ "addr2line", "anyhow", "async-trait", - "bitflags 2.11.1", + "bitflags 2.13.0", "bumpalo", "cc", "cfg-if", @@ -4143,7 +4086,7 @@ dependencies = [ "target-lexicon", "wasm-encoder 0.236.1", "wasmparser 0.236.1", - "wasmtime-environ 36.0.7", + "wasmtime-environ 36.0.12", "wasmtime-internal-asm-macros", "wasmtime-internal-cache", "wasmtime-internal-component-macro", @@ -4163,12 +4106,12 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "cpp_demangle", - "cranelift-bitset 0.123.7", - "cranelift-entity 0.123.7", + "cranelift-bitset 0.123.12", + "cranelift-entity 0.123.12", "gimli", "indexmap", "log", @@ -4188,12 +4131,12 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "36.0.7" -source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#67de3b777448d4f99850e7b3848238ef387032c6" +version = "36.0.12" +source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#62166f65ac52a1f164419097a2a533ff50e4d07b" dependencies = [ "anyhow", - "cranelift-bitset 0.123.7 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", - "cranelift-entity 0.123.7 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", + "cranelift-bitset 0.123.12 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", + "cranelift-entity 0.123.12 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", "gimli", "indexmap", "log", @@ -4208,14 +4151,14 @@ dependencies = [ [[package]] name = "wasmtime-internal-asm-macros" -version = "36.0.7" +version = "36.0.12" dependencies = [ "cfg-if", ] [[package]] name = "wasmtime-internal-cache" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "base64", @@ -4233,7 +4176,7 @@ dependencies = [ [[package]] name = "wasmtime-internal-component-macro" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "proc-macro2", @@ -4246,17 +4189,17 @@ dependencies = [ [[package]] name = "wasmtime-internal-component-util" -version = "36.0.7" +version = "36.0.12" [[package]] name = "wasmtime-internal-cranelift" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "cfg-if", "cranelift-codegen", "cranelift-control", - "cranelift-entity 0.123.7", + "cranelift-entity 0.123.12", "cranelift-frontend", "cranelift-native", "gimli", @@ -4268,14 +4211,14 @@ dependencies = [ "target-lexicon", "thiserror 2.0.18", "wasmparser 0.236.1", - "wasmtime-environ 36.0.7", + "wasmtime-environ 36.0.12", "wasmtime-internal-math", "wasmtime-internal-versioned-export-macros", ] [[package]] name = "wasmtime-internal-fiber" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "cc", @@ -4289,7 +4232,7 @@ dependencies = [ [[package]] name = "wasmtime-internal-jit-debug" -version = "36.0.7" +version = "36.0.12" dependencies = [ "cc", "object", @@ -4299,7 +4242,7 @@ dependencies = [ [[package]] name = "wasmtime-internal-jit-icache-coherence" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "cfg-if", @@ -4309,18 +4252,18 @@ dependencies = [ [[package]] name = "wasmtime-internal-math" -version = "36.0.7" +version = "36.0.12" dependencies = [ "libm", ] [[package]] name = "wasmtime-internal-slab" -version = "36.0.7" +version = "36.0.12" [[package]] name = "wasmtime-internal-unwinder" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "cfg-if", @@ -4331,7 +4274,7 @@ dependencies = [ [[package]] name = "wasmtime-internal-versioned-export-macros" -version = "36.0.7" +version = "36.0.12" dependencies = [ "proc-macro2", "quote", @@ -4340,7 +4283,7 @@ dependencies = [ [[package]] name = "wasmtime-internal-winch" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "cranelift-codegen", @@ -4348,17 +4291,17 @@ dependencies = [ "object", "target-lexicon", "wasmparser 0.236.1", - "wasmtime-environ 36.0.7", + "wasmtime-environ 36.0.12", "wasmtime-internal-cranelift", "winch-codegen", ] [[package]] name = "wasmtime-internal-wit-bindgen" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", - "bitflags 2.11.1", + "bitflags 2.13.0", "heck", "indexmap", "wit-parser 0.236.1", @@ -4366,11 +4309,11 @@ dependencies = [ [[package]] name = "wasmtime-wasi" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "async-trait", - "bitflags 2.11.1", + "bitflags 2.13.0", "bytes", "cap-fs-ext", "cap-net-ext", @@ -4388,15 +4331,15 @@ dependencies = [ "tracing", "url", "wasmtime", - "wasmtime-wasi-io 36.0.7", - "wiggle 36.0.7", + "wasmtime-wasi-io 36.0.12", + "wiggle 36.0.12", "windows-sys 0.60.2", ] [[package]] name = "wasmtime-wasi-http" -version = "36.0.7" -source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#67de3b777448d4f99850e7b3848238ef387032c6" +version = "36.0.12" +source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#62166f65ac52a1f164419097a2a533ff50e4d07b" dependencies = [ "anyhow", "async-trait", @@ -4412,13 +4355,13 @@ dependencies = [ "tracing", "wasmtime", "wasmtime-wasi", - "wasmtime-wasi-io 36.0.7 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", + "wasmtime-wasi-io 36.0.12 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", "webpki-roots 0.26.11", ] [[package]] name = "wasmtime-wasi-io" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "async-trait", @@ -4429,8 +4372,8 @@ dependencies = [ [[package]] name = "wasmtime-wasi-io" -version = "36.0.7" -source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#67de3b777448d4f99850e7b3848238ef387032c6" +version = "36.0.12" +source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#62166f65ac52a1f164419097a2a533ff50e4d07b" dependencies = [ "anyhow", "async-trait", @@ -4441,7 +4384,7 @@ dependencies = [ [[package]] name = "wasmtime-wasi-nn" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "candle-core", @@ -4452,7 +4395,7 @@ dependencies = [ "tracing", "walkdir", "wasmtime", - "wiggle 36.0.7", + "wiggle 36.0.12", "windows", ] @@ -4467,24 +4410,24 @@ dependencies = [ [[package]] name = "wast" -version = "248.0.0" +version = "252.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acc54622ed5a5cddafcdf152043f9d4aed54d4a653d686b7dfe874809fca99d7" +checksum = "942a3449d6a593fccc111a6241c8df52bda168af30e40bf9580d4394d7374c65" dependencies = [ "bumpalo", "leb128fmt", "memchr", "unicode-width", - "wasm-encoder 0.248.0", + "wasm-encoder 0.252.0", ] [[package]] name = "wat" -version = "1.248.0" +version = "1.252.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75cd9e510603909748e6ebab89f27cd04472c1d9d85a3c88a7a6fc51a1a7934" +checksum = "c72a4ba7088f7bac94cf516e49882bdf97068904a563768cf249efc839ec42cb" dependencies = [ - "wast 248.0.0", + "wast 252.0.0", ] [[package]] @@ -4493,48 +4436,48 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.7", + "webpki-roots 1.0.8", ] [[package]] name = "webpki-roots" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" +checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf" dependencies = [ "rustls-pki-types", ] [[package]] name = "wiggle" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "async-trait", - "bitflags 2.11.1", + "bitflags 2.13.0", "thiserror 2.0.18", "tracing", "wasmtime", - "wiggle-macro 36.0.7", + "wiggle-macro 36.0.12", ] [[package]] name = "wiggle" -version = "36.0.7" -source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#67de3b777448d4f99850e7b3848238ef387032c6" +version = "36.0.12" +source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#62166f65ac52a1f164419097a2a533ff50e4d07b" dependencies = [ "anyhow", "async-trait", - "bitflags 2.11.1", + "bitflags 2.13.0", "thiserror 2.0.18", "tracing", "wasmtime", - "wiggle-macro 36.0.7 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", + "wiggle-macro 36.0.12 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", ] [[package]] name = "wiggle-generate" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "heck", @@ -4546,8 +4489,8 @@ dependencies = [ [[package]] name = "wiggle-generate" -version = "36.0.7" -source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#67de3b777448d4f99850e7b3848238ef387032c6" +version = "36.0.12" +source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#62166f65ac52a1f164419097a2a533ff50e4d07b" dependencies = [ "anyhow", "heck", @@ -4559,23 +4502,23 @@ dependencies = [ [[package]] name = "wiggle-macro" -version = "36.0.7" +version = "36.0.12" dependencies = [ "proc-macro2", "quote", "syn", - "wiggle-generate 36.0.7", + "wiggle-generate 36.0.12", ] [[package]] name = "wiggle-macro" -version = "36.0.7" -source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#67de3b777448d4f99850e7b3848238ef387032c6" +version = "36.0.12" +source = "git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0#62166f65ac52a1f164419097a2a533ff50e4d07b" dependencies = [ "proc-macro2", "quote", "syn", - "wiggle-generate 36.0.7 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", + "wiggle-generate 36.0.12 (git+https://github.com/G-Core/wasmtime.git?branch=release-36.0.0)", ] [[package]] @@ -4611,7 +4554,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winch-codegen" -version = "36.0.7" +version = "36.0.12" dependencies = [ "anyhow", "cranelift-assembler-x64", @@ -4622,7 +4565,7 @@ dependencies = [ "target-lexicon", "thiserror 2.0.18", "wasmparser 0.236.1", - "wasmtime-environ 36.0.7", + "wasmtime-environ 36.0.12", "wasmtime-internal-cranelift", "wasmtime-internal-math", ] @@ -4905,9 +4848,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] @@ -4918,86 +4861,16 @@ version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f3fd376f71958b862e7afb20cfe5a22830e1963462f3a17f49d82a6c1d1f42d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "windows-sys 0.59.0", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser 0.244.0", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata 0.244.0", - "wit-bindgen-core", - "wit-component 0.244.0", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags 2.11.1", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder 0.244.0", - "wasm-metadata 0.244.0", - "wasmparser 0.244.0", - "wit-parser 0.244.0", -] - [[package]] name = "wit-component" version = "0.246.2" @@ -5005,14 +4878,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1936c26cb24b93dc36bf78fb5dc35c55cd37f66ecdc2d2663a717d9fb3ee951e" dependencies = [ "anyhow", - "bitflags 2.11.1", + "bitflags 2.13.0", "indexmap", "log", "serde", "serde_derive", "serde_json", "wasm-encoder 0.246.2", - "wasm-metadata 0.246.2", + "wasm-metadata", "wasmparser 0.246.2", "wit-parser 0.246.2", ] @@ -5035,24 +4908,6 @@ dependencies = [ "wasmparser 0.236.1", ] -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser 0.244.0", -] - [[package]] name = "wit-parser" version = "0.246.2" @@ -5110,9 +4965,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive 0.8.2", @@ -5145,18 +5000,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" dependencies = [ "proc-macro2", "quote", @@ -5165,9 +5020,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] @@ -5186,9 +5041,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zerotrie" @@ -5197,7 +5052,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", - "yoke 0.8.2", + "yoke 0.8.3", "zerofrom", ] @@ -5207,7 +5062,7 @@ version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ - "yoke 0.8.2", + "yoke 0.8.3", "zerofrom", "zerovec-derive", ] diff --git a/crates/http-backend/src/lib.rs b/crates/http-backend/src/lib.rs index a3bd880..1ddacf5 100644 --- a/crates/http-backend/src/lib.rs +++ b/crates/http-backend/src/lib.rs @@ -44,6 +44,7 @@ const FASTEDGE_HEADER_HOSTNAME: &str = "fastedge_header_hostname"; const HOST_HEADER: &str = "host"; const CONTENT_LENGTH_HEADER: &str = "content-length"; const TRANSFER_ENCODING_HEADER: &str = "transfer-encoding"; +const FASTEDGE_APP_ID: &str = "fastedge-app-id"; // Default scheme used when an outbound URL doesn't specify one. const DEFAULT_SCHEME: &str = "http"; @@ -89,6 +90,7 @@ pub struct Backend { epoch_pause_ms: Arc, epoch_exclude_http_wait: bool, cdn_real_host: Option, + app_id: Option, } pub struct Builder { @@ -140,6 +142,7 @@ impl Builder { epoch_pause_ms: Arc::new(AtomicU64::new(0)), epoch_exclude_http_wait: false, cdn_real_host: None, + app_id: None, } } } @@ -171,6 +174,14 @@ impl Backend { self.cdn_real_host.clone() } + pub fn set_app_id(&mut self, app_id: u64) { + self.app_id = Some(app_id); + } + + pub fn app_id(&self) -> Option { + self.app_id + } + /// Set external request stats pub fn set_ext_http_stats(&mut self, stats: Arc) { self.ext_http_stats.replace(stats); @@ -285,6 +296,14 @@ impl Backend { original_host ); + if let Some(ref backend) = self.hostname { + anyhow::ensure!( + !is_backend_host(&original_host, backend.as_str()), + "direct access to backend resource is not allowed: {}", + original_host + ); + } + // When the outbound call targets the CDN "real host" (the host of the // original end-user request, carried in the `X-Cdn-Real-Host` header) on a // default port, the backend resource is the app itself. In that case route @@ -308,14 +327,12 @@ impl Backend { .filter(|(k, _)| { !matches!( k.as_str(), - HOST_HEADER - | CONTENT_LENGTH_HEADER - | TRANSFER_ENCODING_HEADER - | FASTEDGE_HOSTNAME - | FASTEDGE_SCHEME - | FASTEDGE_HEADER_HOSTNAME + HOST_HEADER | CONTENT_LENGTH_HEADER | TRANSFER_ENCODING_HEADER ) }) + // Block all internal headers with the `fastedge` prefix so + // guest modules cannot spoof routing/internal metadata. + .filter(|(k, _)| !is_fastedge_internal_header(k)) .filter(|(k, _)| { !self .propagate_header_names @@ -352,6 +369,12 @@ impl Backend { } headers.extend(self.propagate_headers_vec()); + // Inject the application identifier so the backend can + // correlate the request with the originating FastEdge app. + if let Some(app_id) = self.app_id { + headers.push((FASTEDGE_APP_ID.to_string(), app_id.to_string())); + } + let host = canonical_host_name(&headers, &original_url)?; let url = canonical_url(&original_url, &host, self.uri.path())?; @@ -587,6 +610,17 @@ impl hyper_util::client::legacy::connect::Connection for Connection { } } +/// Returns `true` if the header name uses the reserved `fastedge` prefix +/// (either `fastedge-` or `fastedge_`). These headers are internal routing +/// metadata and must not be set by guest modules. +pub fn is_fastedge_internal_header(name: &str) -> bool { + matches!( + name.get(0..9), + Some(prefix) + if prefix.eq_ignore_ascii_case("fastedge-") || prefix.eq_ignore_ascii_case("fastedge_") + ) +} + fn extract_host(addr: &str) -> &str { if addr.starts_with('[') { // IPv6 with port: [::1]:8080 @@ -609,6 +643,14 @@ pub fn is_public_host(host: &str) -> bool { } } +/// Returns `true` if the given `target_host` resolves to the same authority as +/// the backend resource URI. This is used to prevent guest modules from making +/// direct outbound requests to the internal backend, bypassing FastEdge routing. +pub fn is_backend_host(target_host: &str, backend_uri: &str) -> bool { + let target = extract_host(target_host).to_lowercase(); + target == backend_uri +} + fn is_private_ip(ip: &IpAddr) -> bool { match ip { IpAddr::V4(ipv4) => is_private_ipv4(ipv4), @@ -1451,4 +1493,161 @@ mod tests { let result = backend.make_request(req); assert!(result.is_ok()); } + + #[test] + fn test_is_backend_host() { + let backend_uri = "be.server"; + + // Exact match + assert!(is_backend_host("be.server", backend_uri)); + // Case-insensitive match + assert!(is_backend_host("BE.SERVER", backend_uri)); + // With port (host extraction strips port) + assert!(is_backend_host("be.server:9090", backend_uri)); + // Different host + assert!(!is_backend_host("example.com", backend_uri)); + // Empty URI has no authority + assert!(!is_backend_host("be.server", "")); + } + + #[test] + fn test_make_request_rejects_backend_host() { + let connector = mock_http_connector::Connector::builder().build(); + let mut backend = + Backend::::builder(BackendStrategy::FastEdge) + .hostname("be.server") + .uri("http://be.server/".parse().unwrap()) + .build(connector); + let headers = HeaderMap::new(); + backend.propagate_headers(headers).unwrap(); + + let req = Request { + method: Method::Get, + uri: "http://be.server/path".to_string(), + headers: vec![], + body: None, + }; + let result = backend.make_request(req); + assert!(result.is_err()); + assert!( + result + .unwrap_err() + .to_string() + .contains("direct access to backend resource is not allowed") + ); + } + + #[test] + fn test_is_fastedge_internal_header() { + // Headers with fastedge- prefix are internal + assert!(is_fastedge_internal_header("fastedge-hostname")); + assert!(is_fastedge_internal_header("fastedge-scheme")); + assert!(is_fastedge_internal_header("fastedge-custom")); + // Headers with fastedge_ prefix are internal + assert!(is_fastedge_internal_header("fastedge_header_hostname")); + assert!(is_fastedge_internal_header("fastedge_anything")); + // Case-insensitive + assert!(is_fastedge_internal_header("FastEdge-Secret")); + assert!(is_fastedge_internal_header("FASTEDGE_DATA")); + // Non-fastedge headers are allowed + assert!(!is_fastedge_internal_header("x-custom-header")); + assert!(!is_fastedge_internal_header("content-type")); + assert!(!is_fastedge_internal_header("host")); + } + + #[test] + fn test_make_request_strips_fastedge_prefixed_headers() { + let mut builder = mock_http_connector::Connector::builder(); + builder + .expect() + .times(1) + .with_method(http::Method::GET) + .with_uri("http://be.server/path") + .with_header("fastedge-hostname", "example.com") + .with_header("fastedge-scheme", "http") + .with_header("host", "be.server") + .with_header("x-allowed", "yes") + .returning("OK") + .unwrap(); + let connector = builder.build(); + let mut backend = + Backend::::builder(BackendStrategy::FastEdge) + .hostname("be.server") + .build(connector); + let headers = HeaderMap::new(); + backend.propagate_headers(headers).unwrap(); + + let req = Request { + method: Method::Get, + uri: "http://example.com/path".to_string(), + headers: vec![ + ("fastedge_evil".to_string(), "should-be-removed".to_string()), + ( + "fastedge-spoof".to_string(), + "should-be-removed".to_string(), + ), + ("x-allowed".to_string(), "yes".to_string()), + ], + body: None, + }; + // The request should succeed — internal headers are silently stripped, + // and the connector mock only expects "x-allowed" from app headers. + let result = backend.make_request(req); + assert!(result.is_ok()); + let built = result.unwrap(); + // Verify fastedge-prefixed app headers are not present + assert!(built.headers().get("fastedge_evil").is_none()); + assert!(built.headers().get("fastedge-spoof").is_none()); + // Verify allowed header is present + assert_eq!( + built.headers().get("x-allowed").unwrap().to_str().unwrap(), + "yes" + ); + } + + #[test] + fn test_make_request_includes_fastedge_app_id() { + let connector = mock_http_connector::Connector::builder().build(); + let mut backend = + Backend::::builder(BackendStrategy::FastEdge) + .build(connector); + backend.set_app_id(12345); + + let req = Request { + method: Method::Get, + uri: "http://example.com/path".to_string(), + headers: vec![], + body: None, + }; + let result = backend.make_request(req); + assert!(result.is_ok()); + let built = result.unwrap(); + assert_eq!( + built + .headers() + .get("fastedge-app-id") + .unwrap() + .to_str() + .unwrap(), + "12345" + ); + } + + #[test] + fn test_make_request_no_fastedge_app_id_when_unset() { + let connector = mock_http_connector::Connector::builder().build(); + let backend = Backend::::builder(BackendStrategy::FastEdge) + .build(connector); + + let req = Request { + method: Method::Get, + uri: "http://example.com/path".to_string(), + headers: vec![], + body: None, + }; + let result = backend.make_request(req); + assert!(result.is_ok()); + let built = result.unwrap(); + assert!(built.headers().get("fastedge-app-id").is_none()); + } } diff --git a/crates/http-service/src/executor/http.rs b/crates/http-service/src/executor/http.rs index a5d68a2..355244d 100644 --- a/crates/http-service/src/executor/http.rs +++ b/crates/http-service/src/executor/http.rs @@ -22,6 +22,7 @@ pub struct HttpExecutorImpl { store_builder: StoreBuilder, backend: Backend, epoch_exclude_http_wait: bool, + app_id: u64, } #[async_trait] @@ -96,6 +97,7 @@ where } let mut http_backend = self.backend; + http_backend.set_app_id(self.app_id); http_backend .propagate_headers(parts.headers.clone()) .context("propagate headers")?; @@ -182,12 +184,14 @@ where store_builder: StoreBuilder, backend: Backend, epoch_exclude_http_wait: bool, + app_id: u64, ) -> Self { Self { instance_pre, store_builder, backend, epoch_exclude_http_wait, + app_id, } } } @@ -420,6 +424,7 @@ mod tests { store_builder, self.backend(), false, + cfg.app_id, )) } } diff --git a/crates/http-service/src/executor/wasi_http.rs b/crates/http-service/src/executor/wasi_http.rs index 559f6cc..72b4d6b 100644 --- a/crates/http-service/src/executor/wasi_http.rs +++ b/crates/http-service/src/executor/wasi_http.rs @@ -26,6 +26,7 @@ pub struct WasiHttpExecutorImpl { store_builder: StoreBuilder, backend: Backend, epoch_exclude_http_wait: bool, + app_id: u64, } #[async_trait] @@ -92,6 +93,7 @@ where store_builder = store_builder.epoch_pause_ms(counter); } let mut http_backend = self.backend; + http_backend.set_app_id(self.app_id); http_backend.epoch_exclude_http_wait(self.epoch_exclude_http_wait); if let Some(counter) = epoch_pause_ms { http_backend.set_epoch_pause_ms(counter); @@ -205,12 +207,14 @@ where store_builder: StoreBuilder, backend: Backend, epoch_exclude_http_wait: bool, + app_id: u64, ) -> Self { Self { instance_pre, store_builder, backend, epoch_exclude_http_wait, + app_id, } } } diff --git a/crates/http-service/src/state.rs b/crates/http-service/src/state.rs index cd708e6..af8f553 100644 --- a/crates/http-service/src/state.rs +++ b/crates/http-service/src/state.rs @@ -3,7 +3,7 @@ use http::request::Parts; use http::uri::Scheme; use http::{HeaderMap, HeaderName, HeaderValue, Uri, header}; use http_backend::Backend; -use http_backend::is_public_host; +use http_backend::{is_backend_host, is_fastedge_internal_header, is_public_host}; use runtime::BackendRequest; use runtime::store::HasStats; use runtime::util::stats::StatsVisitor; @@ -28,6 +28,7 @@ const FASTEDGE_SCHEME: HeaderName = HeaderName::from_static("fastedge-scheme"); // lowercase form is equivalent on the wire. const FASTEDGE_HEADER_HOSTNAME: HeaderName = HeaderName::from_static("fastedge_header_hostname"); const FASTEDGE_HOSTNAME_VALUE: HeaderValue = HeaderValue::from_static("127.0.0.1"); +const FASTEDGE_APP_ID: HeaderName = HeaderName::from_static("fastedge-app-id"); impl BackendRequest for HttpState { #[instrument(skip(self, head), level = "debug", ret)] @@ -73,6 +74,19 @@ impl BackendRequest for HttpState { original_host ); + if let Some(ref hostname) = self.http_backend.hostname() { + tracing::debug!( + "backend request original url: {:?}, original host: {}", + hostname, + original_host + ); + anyhow::ensure!( + !is_backend_host(&original_host, hostname.as_str()), + "direct access to backend resource is not allowed: {}", + original_host + ); + } + // When the outbound call targets the CDN "real host" (the host of the // original end-user request, carried in the `X-Cdn-Real-Host` header) on a // default port, the backend resource is the app itself. In that case route @@ -88,17 +102,13 @@ impl BackendRequest for HttpState { port_ok && cdn_real_host.eq_ignore_ascii_case(url_host) }); - // `FASTEDGE_HEADER_HOSTNAME` is an internal routing header set by - // FastEdge below; strip any app-provided value so a guest can't spoof - // the "real host" seen by the backend. - static FILTER_HEADERS: [HeaderName; 7] = [ + // Strip internal routing headers and all headers with the + // reserved `fastedge` prefix so guests cannot spoof internal metadata. + static FILTER_HEADERS: [HeaderName; 4] = [ header::HOST, header::CONTENT_LENGTH, header::TRANSFER_ENCODING, header::UPGRADE, - FASTEDGE_HOSTNAME, - FASTEDGE_SCHEME, - FASTEDGE_HEADER_HOSTNAME, ]; // filter headers @@ -107,7 +117,9 @@ impl BackendRequest for HttpState { .into_iter() .filter_map(|(k, v)| k.map(|k| (k, v))) .filter(|(k, _)| { - !FILTER_HEADERS.contains(k) && !self.propagate_header_names.contains(k) + !FILTER_HEADERS.contains(k) + && !self.propagate_header_names.contains(k) + && !is_fastedge_internal_header(k.as_str()) }) .collect::(); @@ -137,6 +149,12 @@ impl BackendRequest for HttpState { headers.extend(self.propagate_headers.clone()); + // Inject the application identifier so the backend can + // correlate the request with the originating FastEdge app. + if let Some(app_id) = self.http_backend.app_id() { + headers.insert(FASTEDGE_APP_ID, app_id.to_string().parse()?); + } + let authority = self .http_backend .uri() @@ -358,4 +376,68 @@ mod tests { Some("example.com") ); } + + #[test] + fn direct_access_to_backend_host_is_rejected() { + let mut state = make_state(None); + let result = state.backend_request(parts("http://be.server/path", &[])); + assert!(result.is_err()); + let err_msg = result.unwrap_err().to_string(); + assert!( + err_msg.contains("direct access to backend resource is not allowed"), + "unexpected error: {}", + err_msg + ); + } + + #[test] + fn fastedge_prefixed_headers_are_stripped() { + let mut state = make_state(None); + let out = state + .backend_request(parts( + "http://example.com/path", + &[ + ("fastedge_custom_header", "should-be-removed"), + ("fastedge-secret", "should-be-removed"), + ("x-custom-header", "should-remain"), + ], + )) + .unwrap(); + // All fastedge-prefixed headers from the guest are stripped + assert_eq!(header(&out, "fastedge_custom_header"), None); + assert_eq!(header(&out, "fastedge-secret"), None); + // Non-fastedge headers pass through + assert_eq!(header(&out, "x-custom-header"), Some("should-remain")); + } + + #[test] + fn fastedge_app_id_is_injected_when_set() { + let connector = FastEdgeConnector::new("http://be.server/".parse().unwrap()); + let mut http_backend = Backend::::builder(BackendStrategy::FastEdge) + .hostname("be.server") + .uri("http://be.server/".parse().unwrap()) + .build(connector); + http_backend.set_app_id(42); + let backend_uri = http_backend.uri(); + let mut state = HttpState { + http_backend, + uri: backend_uri, + propagate_headers: HeaderMap::new(), + propagate_header_names: vec![], + stats: Arc::new(TestStats), + }; + let out = state + .backend_request(parts("http://example.com/path", &[])) + .unwrap(); + assert_eq!(header(&out, "fastedge-app-id"), Some("42")); + } + + #[test] + fn fastedge_app_id_not_present_when_unset() { + let mut state = make_state(None); + let out = state + .backend_request(parts("http://example.com/path", &[])) + .unwrap(); + assert_eq!(header(&out, "fastedge-app-id"), None); + } } diff --git a/crates/runtime/src/lib.rs b/crates/runtime/src/lib.rs index 0705ad5..3428d29 100644 --- a/crates/runtime/src/lib.rs +++ b/crates/runtime/src/lib.rs @@ -178,6 +178,12 @@ impl WasiHttpView for Data { if name.eq(&header::HOST) { return false; } + // Block all headers with the reserved `fastedge` prefix — these are + // internal routing headers that guest modules must not set. + let name_str = name.as_str(); + if name_str.starts_with("fastedge-") || name_str.starts_with("fastedge_") { + return true; + } // Fall back to wasmtime's default forbidden-header policy. wasmtime_wasi_http::types::DEFAULT_FORBIDDEN_HEADERS.contains(name) } diff --git a/src/context.rs b/src/context.rs index 9168623..8163a3d 100644 --- a/src/context.rs +++ b/src/context.rs @@ -140,6 +140,7 @@ impl ExecutorFactory>> for Context { store_builder, self.backend(), false, + app.app_id, ))) } else { Ok(RunExecutor::Http(HttpExecutorImpl::new( @@ -147,6 +148,7 @@ impl ExecutorFactory>> for Context { store_builder, self.backend(), false, + app.app_id, ))) } }