90 lines
4.4 KiB
Rust
90 lines
4.4 KiB
Rust
// file: crates/ksp-offchain-transport-lib/tests/security_hardening.rs
|
|
// version: 2
|
|
|
|
#![warn(missing_docs)]
|
|
#![deny(unreachable_pub)]
|
|
#![forbid(unsafe_code)]
|
|
|
|
//! Adversarial security canaries for Off-chain Transport diagnostics, credentials and ownership boundaries.
|
|
|
|
#[test]
|
|
fn pre_010_keyed_settings_and_service_debug_never_expose_credentials() -> ksp_core_lib::Result<()> {
|
|
let secret = "pre010-api-key-secret-canary";
|
|
let birdeye = match ksp_offchain_transport_lib::MarketPriceBirdeyeSettings::new(true, std::option::Option::Some(secret.to_owned())) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
|
};
|
|
let coingecko = match ksp_offchain_transport_lib::MarketPriceCoinGeckoSettings::demo(true, std::option::Option::Some(secret.to_owned())) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
|
};
|
|
let coinmarketcap = match ksp_offchain_transport_lib::MarketPriceCoinMarketCapSettings::basic(true, std::option::Option::Some(secret.to_owned())) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
|
};
|
|
let jupiter = match ksp_offchain_transport_lib::MarketPriceJupiterSettings::free(true, std::option::Option::Some(secret.to_owned())) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
|
};
|
|
for debug in [std::format!("{birdeye:?}"), std::format!("{coingecko:?}"), std::format!("{coinmarketcap:?}"), std::format!("{jupiter:?}")] {
|
|
assert!(!debug.contains(secret));
|
|
assert!(debug.contains("api_key_present"));
|
|
}
|
|
let service = match ksp_offchain_transport_lib::MarketPriceService::new(std::vec![
|
|
ksp_offchain_transport_lib::MarketPriceProviderSetup::Birdeye(birdeye),
|
|
ksp_offchain_transport_lib::MarketPriceProviderSetup::CoinGecko(coingecko),
|
|
ksp_offchain_transport_lib::MarketPriceProviderSetup::CoinMarketCap(coinmarketcap),
|
|
ksp_offchain_transport_lib::MarketPriceProviderSetup::Jupiter(jupiter),
|
|
]) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
|
};
|
|
assert!(!std::format!("{service:?}").contains(secret));
|
|
return std::result::Result::Ok(());
|
|
}
|
|
|
|
#[test]
|
|
fn pre_010_market_price_sources_do_not_read_environment_or_use_float_price_truth() -> std::io::Result<()> {
|
|
let src = crate_root().join("src");
|
|
let entries = match std::fs::read_dir(src) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
|
};
|
|
for entry in entries {
|
|
let entry = match entry {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
|
};
|
|
let name = entry.file_name();
|
|
let name = name.to_string_lossy();
|
|
if !name.starts_with("market_price_") || !name.ends_with(".rs") {
|
|
continue;
|
|
}
|
|
let source = match std::fs::read_to_string(entry.path()) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
|
};
|
|
assert!(!source.contains("std::env"), "market-price source must not bypass Config environment ownership: {name}");
|
|
assert!(!source.contains("as_f64("), "market-price source must not use serde_json f64 as canonical price truth: {name}");
|
|
}
|
|
return std::result::Result::Ok(());
|
|
}
|
|
|
|
#[test]
|
|
fn pre_010_config_schema_exposes_no_provider_url_or_rate_limit_override() -> std::io::Result<()> {
|
|
let root = crate_root().join("../..");
|
|
let schema = match std::fs::read_to_string(root.join("config/schemas/std.offchain_transport.schema.json")) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
|
};
|
|
assert!(!schema.contains("base_url"));
|
|
assert!(!schema.contains("endpoint_url"));
|
|
assert!(!schema.contains("rate_limit"));
|
|
assert!(!schema.contains("requests_per"));
|
|
return std::result::Result::Ok(());
|
|
}
|
|
|
|
fn crate_root() -> std::path::PathBuf {
|
|
return std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
}
|