#[derive(Debug, Clone)]
pub struct Comparison {
pub left: ComparisonSide,
pub right: ComparisonSide,
pub operator: ComparisonOp,
pub consequence: Option<Consequence>,
pub is_swapped: bool,
}
impl Comparison {
pub fn constant_side(&self) -> Option<&ComparisonSide> {
if self.left.is_constant() {
Some(&self.left)
} else if self.right.is_constant() {
Some(&self.right)
} else {
None
}
}
pub fn variable_side(&self) -> Option<&ComparisonSide> {
if self.left.is_variable() {
Some(&self.left)
} else if self.right.is_variable() {
Some(&self.right)
} else {
None
}
}
}
#[derive(Debug, Clone)]
pub enum ComparisonSide {
ConstantRef {
name: String,
resolved_value: Option<String>,
},
StringLiteral(String),
Variable {
name: String,
source: Option<VariableSource>,
},
FieldAccess { base: String, field: String },
MethodCall {
receiver: String,
method: String,
args: Vec<String>,
},
FunctionCall { path: String, args: Vec<String> },
Other(String),
}
impl ComparisonSide {
pub fn is_constant(&self) -> bool {
matches!(self, Self::ConstantRef { .. } | Self::StringLiteral(_))
}
pub fn is_variable(&self) -> bool {
matches!(self, Self::Variable { .. } | Self::FieldAccess { .. })
}
pub fn name_for_scoring(&self) -> Option<&str> {
match self {
Self::Variable { name, .. } => Some(name),
Self::FieldAccess { field, .. } => Some(field),
Self::MethodCall { method, .. } => Some(method),
_ => None,
}
}
}
#[derive(Debug, Clone)]
pub enum VariableSource {
Parameter,
Environment,
Header,
QueryParam,
RequestBody,
FileRead,
Stdin,
Database,
Unknown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ComparisonOp {
Eq,
Ne,
MethodEq,
PatternMatch,
}
#[derive(Debug, Clone)]
pub struct Consequence {
pub block_summary: BlockSummary,
pub dangerous_ops: Vec<DangerousOp>,
pub is_benign: bool,
}
#[derive(Debug, Clone, Default)]
pub struct BlockSummary {
pub is_empty: bool,
pub only_logging: bool,
pub has_return: bool,
pub has_early_exit: bool,
pub has_mutation: bool,
pub function_calls: Vec<String>,
pub field_assignments: Vec<String>,
}
#[derive(Debug, Clone)]
pub enum DangerousOp {
AuthStateChange { field: String },
AuthFunctionCall { function: String },
ProcessControl { function: String },
DatabaseOp { operation: String },
NetworkOp { operation: String },
FileSystemOp { operation: String },
CryptoOp { operation: String },
}