feat: redact secrets in sql when logging (#2141)

This commit is contained in:
LFC
2023-08-14 14:40:00 +08:00
committed by GitHub
parent d0b3607633
commit 606b489d53
7 changed files with 63 additions and 46 deletions

View File

@@ -16,6 +16,7 @@ datatypes = { workspace = true }
hex = "0.4"
itertools.workspace = true
once_cell.workspace = true
regex.workspace = true
snafu = { version = "0.7", features = ["backtraces"] }
sqlparser.workspace = true

View File

@@ -14,6 +14,7 @@
#![feature(box_patterns)]
#![feature(assert_matches)]
#![feature(let_chains)]
#![feature(lazy_cell)]
pub mod ast;
pub mod dialect;

View File

@@ -13,9 +13,18 @@
// limitations under the License.
use std::collections::HashMap;
use std::sync::LazyLock;
use regex::Regex;
use sqlparser::ast::{SqlOption, Value};
static SQL_SECRET_PATTERNS: LazyLock<Vec<Regex>> = LazyLock::new(|| {
vec![
Regex::new(r#"(?i)access_key_id=["'](\w*)["'].*"#).unwrap(),
Regex::new(r#"(?i)secret_access_key=["'](\w*)["'].*"#).unwrap(),
]
});
pub fn parse_option_string(value: Value) -> Option<String> {
match value {
Value::SingleQuotedString(v) | Value::DoubleQuotedString(v) => Some(v),
@@ -36,3 +45,31 @@ pub fn to_lowercase_options_map(opts: &[SqlOption]) -> HashMap<String, String> {
}
map
}
/// Use regex to match and replace common seen secret values in SQL.
pub fn redact_sql_secrets(sql: &str) -> String {
let mut s = sql.to_string();
for p in SQL_SECRET_PATTERNS.iter() {
if let Some(captures) = p.captures(&s) {
if let Some(m) = captures.get(1) {
s = s.replace(m.as_str(), "******");
}
}
}
s
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_redact_sql_secrets() {
assert_eq!(
redact_sql_secrets(
r#"COPY 'my_table' FROM '/test.orc' WITH (FORMAT = 'orc') CONNECTION(ENDPOINT = 's3.storage.site', REGION = 'hz', ACCESS_KEY_ID='my_key_id', SECRET_ACCESS_KEY="my_access_key");"#
),
r#"COPY 'my_table' FROM '/test.orc' WITH (FORMAT = 'orc') CONNECTION(ENDPOINT = 's3.storage.site', REGION = 'hz', ACCESS_KEY_ID='******', SECRET_ACCESS_KEY="******");"#
);
}
}