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.
- checksums.yaml +4 -4
- data/.fiber-audit.example.yml +7 -8
- data/ARCHITECTURE.md +92 -670
- data/CHANGELOG.md +29 -0
- data/README.md +145 -92
- data/lib/fiber_audit/cli.rb +3 -1
- data/lib/fiber_audit/configuration.rb +31 -6
- data/lib/fiber_audit/operation_semantics.rb +172 -0
- data/lib/fiber_audit/runtime/active_operations.rb +25 -9
- data/lib/fiber_audit/runtime/boot.rb +4 -0
- data/lib/fiber_audit/runtime/environment.rb +58 -0
- data/lib/fiber_audit/runtime/lifecycle.rb +91 -50
- data/lib/fiber_audit/runtime/operation_liveness_monitor.rb +282 -0
- data/lib/fiber_audit/runtime/operation_liveness_policy.rb +47 -0
- data/lib/fiber_audit/runtime/probes/base.rb +12 -10
- data/lib/fiber_audit/runtime/scheduler_evidence_classifier.rb +60 -0
- data/lib/fiber_audit/runtime/scheduler_snapshot.rb +6 -24
- data/lib/fiber_audit/runtime/watchdog.rb +17 -9
- data/lib/fiber_audit/runtime.rb +4 -0
- data/lib/fiber_audit/static/rules/blocking_subprocess.rb +3 -26
- data/lib/fiber_audit/static/rules/direct_socket.rb +52 -16
- data/lib/fiber_audit/static/rules/thread_current_state.rb +12 -20
- data/lib/fiber_audit/version.rb +1 -1
- metadata +5 -1
|
@@ -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
|
|
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
|
|
18
|
+
description 'Direct socket constructors range from inventory-only allocation to endpoint setup.'
|
|
19
19
|
|
|
20
|
-
TITLE
|
|
20
|
+
TITLE = 'Direct socket construction'
|
|
21
21
|
CATEGORY = :network
|
|
22
|
-
|
|
23
22
|
EXACT = OperationVocabulary::FA1006_EXACT
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
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:
|
|
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:
|
|
96
|
-
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: "
|
|
101
|
-
details: {
|
|
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:
|
|
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 :
|
|
15
|
+
severity :medium
|
|
20
16
|
confidence :high
|
|
21
|
-
description 'Thread
|
|
17
|
+
description 'Thread-variable access may share mutable state across fibers on one thread'
|
|
22
18
|
|
|
23
|
-
TITLE = 'Thread
|
|
19
|
+
TITLE = 'Thread-variable access shared across fibers'
|
|
24
20
|
CATEGORY = :thread_local
|
|
25
|
-
MESSAGE = 'Thread
|
|
26
|
-
'
|
|
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,
|
|
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,
|
|
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:
|
|
95
|
-
confidence:
|
|
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:
|
|
91
|
+
execution_context: site.execution_context,
|
|
100
92
|
message: MESSAGE,
|
|
101
93
|
evidence: [Evidence.new(
|
|
102
94
|
source: site.receiver_source,
|
|
103
|
-
message: "
|
|
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
|
data/lib/fiber_audit/version.rb
CHANGED
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.
|
|
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
|