Class: Hone::Patterns::TaintTrackingBase

Inherits:
Base
  • Object
show all
Defined in:
lib/hone/patterns/taint_tracking_base.rb

Overview

Base class for patterns that need to track data flow through variables.

Provides "taint tracking" - the ability to mark variables with metadata about their origin and propagate that information through assignments.

Subclasses should:

  1. Override taint_from_call to mark variables when assigned from specific calls
  2. Override check_tainted_usage to detect problematic uses of tainted variables

Examples:

Tracking .chars allocations

class CharsTracking < TaintTrackingBase
  def taint_from_call(call_node)
    return nil unless call_node.name == :chars
    { type: :chars, source: call_node.receiver&.slice }
  end

  def check_tainted_usage(call_node, taint_info)
    if call_node.name == :[] && taint_info[:type] == :chars
      report_finding(...)
    end
  end
end

Direct Known Subclasses

CharsToVariableTainted

Defined Under Namespace

Classes: TaintInfo

Instance Attribute Summary

Attributes inherited from Base

#findings

Instance Method Summary collapse

Methods inherited from Base

#add_finding, inherited, scan_file

Constructor Details

#initialize(file_path) ⇒ TaintTrackingBase

Returns a new instance of TaintTrackingBase.



36
37
38
39
# File 'lib/hone/patterns/taint_tracking_base.rb', line 36

def initialize(file_path)
  super
  @taint_scopes = []
end

Instance Method Details

#visit_block_node(node) ⇒ Object



47
48
49
# File 'lib/hone/patterns/taint_tracking_base.rb', line 47

def visit_block_node(node)
  with_taint_scope(inherit: true) { super }
end

#visit_call_node(node) ⇒ Object

Track call nodes for both tainting and usage checking



90
91
92
93
# File 'lib/hone/patterns/taint_tracking_base.rb', line 90

def visit_call_node(node)
  super
  check_tainted_call(node)
end

#visit_class_node(node) ⇒ Object



55
56
57
# File 'lib/hone/patterns/taint_tracking_base.rb', line 55

def visit_class_node(node)
  with_taint_scope { super }
end

#visit_def_node(node) ⇒ Object

Scope Management ===



43
44
45
# File 'lib/hone/patterns/taint_tracking_base.rb', line 43

def visit_def_node(node)
  with_taint_scope { super }
end

#visit_instance_variable_write_node(node) ⇒ Object

Track instance variable assignments



72
73
74
75
# File 'lib/hone/patterns/taint_tracking_base.rb', line 72

def visit_instance_variable_write_node(node)
  super
  track_assignment(node.name, node.value, node, scope: :instance)
end

#visit_lambda_node(node) ⇒ Object



51
52
53
# File 'lib/hone/patterns/taint_tracking_base.rb', line 51

def visit_lambda_node(node)
  with_taint_scope { super }
end

#visit_local_variable_read_node(node) ⇒ Object

Track variable reads (for propagation detection)



96
97
98
99
# File 'lib/hone/patterns/taint_tracking_base.rb', line 96

def visit_local_variable_read_node(node)
  super
  # Subclasses can override to track reads
end

#visit_local_variable_write_node(node) ⇒ Object

Track local variable assignments



66
67
68
69
# File 'lib/hone/patterns/taint_tracking_base.rb', line 66

def visit_local_variable_write_node(node)
  super
  track_assignment(node.name, node.value, node)
end

#visit_module_node(node) ⇒ Object



59
60
61
# File 'lib/hone/patterns/taint_tracking_base.rb', line 59

def visit_module_node(node)
  with_taint_scope { super }
end

#visit_multi_write_node(node) ⇒ Object

Track multiple assignment (a, b = x, y)



78
79
80
81
82
83
84
85
86
87
# File 'lib/hone/patterns/taint_tracking_base.rb', line 78

def visit_multi_write_node(node)
  super
  # For simplicity, clear taints for multi-assigned variables
  node.lefts.each do |target|
    case target
    when Prism::LocalVariableTargetNode
      clear_taint(target.name)
    end
  end
end