use untrusted_value::derive::untrusted_inputs;
use untrusted_value::derive::UntrustedVariant;
use untrusted_value::SanitizeValue;
use untrusted_value_derive_internals::IntoUntrustedVariant;
#[derive(Debug, UntrustedVariant)] #[untrusted_derive(Clone, SanitizeValue)]
pub struct GeneralConfig {
pub network: NetworkConfig,
pub database: DatabaseConfig,
}
#[derive(Clone, Debug, UntrustedVariant)] #[untrusted_derive(Clone, SanitizeValueEnd)]
pub struct NetworkConfig {
pub port: u32,
pub listen_address: String,
}
#[derive(Clone, Debug, UntrustedVariant)]
#[untrusted_derive(Clone, SanitizeValueEnd)]
pub struct DatabaseConfig {}
impl SanitizeValue<NetworkConfig> for NetworkConfigUntrusted {
type Error = ();
fn sanitize_value(self) -> Result<NetworkConfig, Self::Error> {
Ok(NetworkConfig {
port: self.port.use_untrusted_value(),
listen_address: self.listen_address.use_untrusted_value(),
}) }
}
impl SanitizeValue<DatabaseConfig> for DatabaseConfigUntrusted {
type Error = ();
fn sanitize_value(self) -> Result<DatabaseConfig, Self::Error> {
Ok(DatabaseConfig {}) }
}
#[untrusted_inputs]
fn response_from_database(config: GeneralConfig) -> Result<GeneralConfig, ()> {
config.sanitize_value()
}
fn main() {
assert!(response_from_database(GeneralConfig {
database: DatabaseConfig {},
network: NetworkConfig {
port: 3000,
listen_address: "<script>alert('xss')</script>".to_string(),
},
})
.is_ok());
}