Fix secret validation (hopefully)

main
trivernis 1 year ago
parent 74661986f2
commit bef104ead5
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG Key ID: DFFFCC2C7A02DB45

@ -57,8 +57,8 @@ hooks = {pre_action = "echo 'before something bad happens'"}
path = "error" path = "error"
action = "echo '{{$.books.*.title}}'" action = "echo '{{$.books.*.title}}'"
# Validate secrets according to different parsing rules # Validate secrets according to different parsing rules
# Currently only GitHub secrets are supported # Currently only HMac based secrets with sha256 are supported
secret = { value = "my secret", format = "GitHub"} secret = { value = "my secret", format = "HMac"}
[endpoints.testscript] [endpoints.testscript]
path = "script" path = "script"

@ -1,28 +0,0 @@
use crate::secret_validation::SecretValidator;
use hmac::{Hmac, Mac};
use hyper::HeaderMap;
use sha2::Sha256;
pub struct GithubSecretValidator;
static X_HUB_SIGNATURE_256_HEADER: &str = "X-Hub-Signature-256";
impl SecretValidator for GithubSecretValidator {
fn validate(&self, headers: &HeaderMap, body: &[u8], secret: &[u8]) -> bool {
log::debug!("Validating GitHub Secret");
if let Some(github_sum) = headers.get(X_HUB_SIGNATURE_256_HEADER) {
let mut mac = Hmac::<Sha256>::new_from_slice(secret).unwrap();
mac.update(body);
let decoded_secret = if let Ok(decoded) = hex::decode(github_sum) {
decoded
} else {
return false;
};
mac.verify_slice(&decoded_secret).is_ok()
} else {
log::debug!("Missing Signature Header");
false
}
}
}

@ -0,0 +1,43 @@
use crate::secret_validation::SecretValidator;
use hmac::{Hmac, Mac};
use hyper::HeaderMap;
use sha2::Sha256;
pub struct HMacSecretValidator;
static SUM_HEADERS: &[&str] = &[
"X-Forgejo-Signature",
"X-Gitea-Signature",
"X-Gogs-Signature",
"X-Hub-Signature-256",
];
impl SecretValidator for HMacSecretValidator {
fn validate(&self, headers: &HeaderMap, body: &[u8], secret: &[u8]) -> bool {
log::debug!("Validating HMac Secret");
let header = headers
.iter()
.filter(|(name, _)| SUM_HEADERS.iter().find(|h| **name == **h).is_some())
.next();
if let Some((_, sum)) = header {
let mut mac = Hmac::<Sha256>::new_from_slice(secret).unwrap();
mac.update(body);
let Ok(sum) = sum.to_str() else {
log::error!("Received signature is not a valid string");
return false;
};
let Ok(decoded_secret) = hex::decode(sum.trim_start_matches("sha256=")) else {
log::error!("Received signature cannot be decoded from hex");
return false;
};
log::debug!("Verifying found signature");
mac.verify_slice(&decoded_secret).is_ok()
} else {
log::error!("Missing Signature Header");
false
}
}
}

@ -1,18 +1,18 @@
mod github; mod hash_mac;
use crate::secret_validation::github::GithubSecretValidator; use crate::secret_validation::hash_mac::HMacSecretValidator;
use hyper::HeaderMap; use hyper::HeaderMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub enum SecretFormat { pub enum SecretFormat {
GitHub, HMac,
} }
impl SecretFormat { impl SecretFormat {
pub fn validator(&self) -> impl SecretValidator { pub fn validator(&self) -> impl SecretValidator {
match self { match self {
SecretFormat::GitHub => GithubSecretValidator, SecretFormat::HMac => HMacSecretValidator,
} }
} }
} }

Loading…
Cancel
Save