fiber_audit 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,27 +4,51 @@ require_relative 'base'
4
4
  require_relative '../../findings/evidence'
5
5
  require_relative '../../correlation/fingerprint'
6
6
  require_relative '../../findings/finding'
7
+ require_relative '../../operation_semantics'
7
8
  require_relative '../../operation_vocabulary'
8
9
 
9
10
  module FiberAudit
10
11
  module Static
11
12
  module Rules
12
- # FA1006 Detects direct socket construction whose DNS, connection, and
13
- # later I/O require scheduler cooperation. Advisory rule with :low default.
13
+ # FA1006: Inventory and semantic classification for direct socket constructors.
14
14
  class DirectSocket < Base
15
15
  id 'FA1006'
16
16
  severity :low
17
17
  default_confidence :high
18
- description 'Direct socket paths require scheduler-aware DNS and I/O cooperation.'
18
+ description 'Direct socket constructors range from inventory-only allocation to endpoint setup.'
19
19
 
20
- TITLE = 'Direct socket creation'
20
+ TITLE = 'Direct socket construction'
21
21
  CATEGORY = :network
22
-
23
22
  EXACT = OperationVocabulary::FA1006_EXACT
24
-
25
- MESSAGE = 'This socket path may require scheduler cooperation for DNS, connection, or subsequent I/O.'
26
- REMEDIATION = 'Distinguish allocation from DNS/connect/I/O, then verify ' \
27
- 'the active scheduler hooks and runtime progress.'
23
+ CATEGORY_METADATA = {
24
+ socket_allocation: {
25
+ title: 'Direct socket allocation',
26
+ message: 'This constructor is inventory-level socket setup without a client connection; ' \
27
+ 'later accept, connect, address resolution, or I/O may require scheduler cooperation.',
28
+ remediation: 'Treat allocation as inventory and verify scheduler-aware behavior at later ' \
29
+ 'accept, connect, resolution, and I/O calls.'
30
+ },
31
+ socket_resolve_connect: {
32
+ title: 'Direct socket endpoint setup',
33
+ message: 'This constructor may resolve an address and establish a network endpoint, requiring ' \
34
+ 'scheduler cooperation from address-resolution and I/O hooks.',
35
+ remediation: 'Verify address_resolve and scheduler-aware I/O hooks, and confirm runtime progress ' \
36
+ 'for endpoint setup.'
37
+ },
38
+ socket_local_connect: {
39
+ title: 'Direct local-socket connection',
40
+ message: 'This constructor may establish a local socket connection and wait for endpoint progress.',
41
+ remediation: 'Verify runtime progress for local-socket connection and move blocking setup outside ' \
42
+ 'the fiber-scheduled path.'
43
+ },
44
+ socket_constructor_unknown: {
45
+ title: 'Direct socket subclass construction',
46
+ message: 'This IPSocket subclass constructor has unknown allocation/connect semantics and may ' \
47
+ 'require scheduler cooperation.',
48
+ remediation: 'Inspect the subclass constructor and verify scheduler-aware resolution, connection, ' \
49
+ 'and I/O behavior.'
50
+ }
51
+ }.freeze
28
52
 
29
53
  class << self
30
54
  def title = TITLE
@@ -81,27 +105,39 @@ module FiberAudit
81
105
 
82
106
  def build_finding(site, const)
83
107
  operation = "#{const}.new"
84
- ctx = site.execution_context || :unknown
108
+ profile = if EXACT.include?(const)
109
+ OperationSemantics.resolve(operation)
110
+ else
111
+ OperationSemantics.resolve_socket_constructor(operation)
112
+ end
113
+ metadata = CATEGORY_METADATA.fetch(profile.category)
85
114
 
86
115
  Finding.new(
87
116
  rule_id: self.class.id,
88
- title: self.class.title,
117
+ title: metadata.fetch(:title),
89
118
  category: self.class.category,
90
119
  severity: advisory_severity(:low),
91
120
  confidence: site.confidence,
92
121
  location: site.location,
93
122
  symbol: site.enclosing_symbol,
94
123
  operation: operation,
95
- execution_context: ctx,
96
- message: MESSAGE,
124
+ execution_context: site.execution_context || :unknown,
125
+ message: metadata.fetch(:message),
97
126
  evidence: [
98
127
  Evidence.new(
99
128
  source: 'static_analysis',
100
- message: "Direct socket creation: #{operation}",
101
- details: { receiver_constant: const, method: :new }
129
+ message: "Matched #{operation} (#{profile.category})",
130
+ details: {
131
+ receiver_constant: const,
132
+ method: :new,
133
+ semantic: profile.category,
134
+ wait_possible: profile.wait_possible,
135
+ inventory_only: profile.inventory_only,
136
+ scheduler_capability: profile.scheduler_capability
137
+ }
102
138
  )
103
139
  ],
104
- remediation: REMEDIATION
140
+ remediation: metadata.fetch(:remediation)
105
141
  )
106
142
  end
107
143
  end
@@ -9,21 +9,17 @@ require_relative '../../operation_vocabulary'
9
9
  module FiberAudit
10
10
  module Static
11
11
  module Rules
12
- # FA1004: Detect thread-variable state access.
13
- #
14
- # Detects only thread_variable_get/set operations, not Thread.current[]
15
- # index operations. Thread variables are shared across all fibers on the
16
- # same thread and may leak request-local data.
12
+ # FA1004: Detect thread-variable state access without inferring stored data.
17
13
  class ThreadCurrentState < Base
18
14
  id 'FA1004'
19
- severity :high
15
+ severity :medium
20
16
  confidence :high
21
- description 'Thread thread variables in fiber code may be shared across fibers and leak request-local data'
17
+ description 'Thread-variable access may share mutable state across fibers on one thread'
22
18
 
23
- TITLE = 'Thread thread variables in fiber code'
19
+ TITLE = 'Thread-variable access shared across fibers'
24
20
  CATEGORY = :thread_local
25
- MESSAGE = 'Thread thread variables are shared across all fibers on the same thread ' \
26
- 'and may leak request-local data between concurrent requests.'
21
+ MESSAGE = 'Thread variables are visible to fibers sharing a thread. This access may expose mutable ' \
22
+ 'state across concurrent work, but static analysis does not establish request-sensitive leakage.'
27
23
  REMEDIATION = 'Prefer fiber-local storage (Fiber[:key]) or framework-provided ' \
28
24
  'request-local state over thread_variable_get/set.'
29
25
 
@@ -73,34 +69,30 @@ module FiberAudit
73
69
 
74
70
  instance_match = site.receiver_constant == 'Thread' && site.receiver_source != 'Thread'
75
71
  current_match = site.receiver_source == 'Thread.current'
76
-
77
72
  return unless instance_match || current_match
78
73
 
79
- build_finding(site, :high, :high, operation(site))
74
+ build_finding(site, operation(site))
80
75
  end
81
76
 
82
77
  def operation(site)
83
78
  "Thread.#{site.method_name}"
84
79
  end
85
80
 
86
- def build_finding(site, default_sev, conf, operation)
87
- context = site.execution_context
88
- severity = severity_for(default_sev, context)
89
-
81
+ def build_finding(site, operation)
90
82
  Finding.new(
91
83
  rule_id: self.class.id,
92
84
  title: TITLE,
93
85
  category: CATEGORY,
94
- severity: severity,
95
- confidence: conf,
86
+ severity: advisory_severity(:medium),
87
+ confidence: :high,
96
88
  location: site.location,
97
89
  symbol: site.enclosing_symbol,
98
90
  operation: operation,
99
- execution_context: context,
91
+ execution_context: site.execution_context,
100
92
  message: MESSAGE,
101
93
  evidence: [Evidence.new(
102
94
  source: site.receiver_source,
103
- message: "Thread thread variable access via #{site.method_name}",
95
+ message: "Matched thread-variable access via #{site.method_name}",
104
96
  details: { operation: operation, receiver: site.receiver_source }
105
97
  )],
106
98
  remediation: REMEDIATION
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FiberAudit
4
- VERSION = '0.3.0'
4
+ VERSION = '0.3.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fiber_audit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - FiberAudit Contributors
@@ -61,6 +61,7 @@ files:
61
61
  - lib/fiber_audit/findings/finding.rb
62
62
  - lib/fiber_audit/findings/location.rb
63
63
  - lib/fiber_audit/findings/severity.rb
64
+ - lib/fiber_audit/operation_semantics.rb
64
65
  - lib/fiber_audit/operation_vocabulary.rb
65
66
  - lib/fiber_audit/project.rb
66
67
  - lib/fiber_audit/reporters/base.rb
@@ -80,6 +81,8 @@ files:
80
81
  - lib/fiber_audit/runtime/lifecycle.rb
81
82
  - lib/fiber_audit/runtime/limits.rb
82
83
  - lib/fiber_audit/runtime/location.rb
84
+ - lib/fiber_audit/runtime/operation_liveness_monitor.rb
85
+ - lib/fiber_audit/runtime/operation_liveness_policy.rb
83
86
  - lib/fiber_audit/runtime/policy.rb
84
87
  - lib/fiber_audit/runtime/probes/base.rb
85
88
  - lib/fiber_audit/runtime/probes/http.rb
@@ -94,6 +97,7 @@ files:
94
97
  - lib/fiber_audit/runtime/recorder.rb
95
98
  - lib/fiber_audit/runtime/redactor.rb
96
99
  - lib/fiber_audit/runtime/sampler.rb
100
+ - lib/fiber_audit/runtime/scheduler_evidence_classifier.rb
97
101
  - lib/fiber_audit/runtime/scheduler_observer.rb
98
102
  - lib/fiber_audit/runtime/scheduler_snapshot.rb
99
103
  - lib/fiber_audit/runtime/session.rb