police-dataflow 0.0.1 → 0.0.2
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 +15 -0
- data/Gemfile +8 -7
- data/Gemfile.lock +57 -18
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/lib/police/dataflow.rb +2 -1
- data/lib/police/dataflow/core_extensions.rb +18 -4
- data/lib/police/dataflow/gate_profiles/ruby1.9.3 +167 -0
- data/lib/police/dataflow/gating.rb +70 -0
- data/lib/police/dataflow/label.rb +19 -14
- data/lib/police/dataflow/labeling.rb +103 -22
- data/lib/police/dataflow/proxies.rb +33 -5
- data/lib/police/dataflow/proxy_base.rb +80 -40
- data/lib/police/dataflow/proxy_numeric.rb +22 -0
- data/lib/police/dataflow/proxying.rb +215 -40
- data/police-dataflow.gemspec +11 -15
- data/tasks/info.rake +43 -0
- data/test/dataflow/core_extensions_test.rb +8 -8
- data/test/dataflow/labeling_test.rb +324 -15
- data/test/dataflow/proxies_test.rb +7 -11
- data/test/dataflow/proxy_base_test.rb +199 -72
- data/test/dataflow/proxy_numeric_test.rb +45 -0
- data/test/dataflow/proxying_test.rb +333 -80
- data/test/helper.rb +2 -2
- data/test/helpers/hooks_flow_fixture.rb +22 -0
- data/test/helpers/no_flow_fixture.rb +4 -4
- data/test/helpers/proxying_fixture.rb +11 -7
- data/test/helpers/sticky_fixture.rb +14 -0
- metadata +12 -12
- data/lib/police/dataflow/guarding.rb +0 -16
- data/test/helpers/auto_flow_fixture.rb +0 -6
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
Mjg4ZTczMTliM2Q2MjdmMWQzNDlmNWM0MDExZDRjOWQ4OWY5MzUwMQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MTU2OWU0NTUzYzFiOWMwYTUwM2FiZjM1OTg1MmIwNDUyZGNiZGQwMg==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NDQ5MDRlZTVlOTgxNWI1MzIzNTI3MzNlZTE5NTlmZjZhMWZjNDBjZTBkNTRj
|
10
|
+
N2QwMDhjNmJmODM0YjdiYjM3YjVhNWM2YTcwNmY5NDhhNTcxNTRhYmM0ZjAw
|
11
|
+
ZjljM2IxNWQyYjA3ZTQzNDM2YjNmNjc4NjJhNjQ5MzU2NDZjNjU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MDEzNWQ5ZmEyYTJjYjQzOWJlNzE0Yjk2MThhMDFhMjZlOWQwNjMwOTI3NWMy
|
14
|
+
MDYzN2U2YmFmNjI4NDRjNTNhM2RkOWFlNmZiMDM1ZjYwNjFkYWZmMTRkYjA3
|
15
|
+
NTc4NzdjZDE4OGVjY2Y4YTE4YTM4ZTY0NDdmNjAxYTVlMjAwMDI=
|
data/Gemfile
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'police-vminfo', '>= 0.0.2', path: '../police-vminfo'
|
2
4
|
|
3
5
|
group :development do
|
4
|
-
gem 'bundler', '>= 1.
|
5
|
-
gem 'jeweler', '>= 1.8.
|
6
|
-
gem 'minitest', '>=
|
7
|
-
gem '
|
8
|
-
gem '
|
9
|
-
gem 'yard', '>= 0.7'
|
6
|
+
gem 'bundler', '>= 1.3.5'
|
7
|
+
gem 'jeweler', '>= 1.8.7'
|
8
|
+
gem 'minitest', '>= 5.0.7'
|
9
|
+
gem 'simplecov', '>= 0.7.1'
|
10
|
+
gem 'yard', '>= 0.8.7.1'
|
10
11
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,31 +1,70 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../police-vminfo
|
3
|
+
specs:
|
4
|
+
police-vminfo (0.0.4)
|
5
|
+
|
1
6
|
GEM
|
2
|
-
remote:
|
7
|
+
remote: https://rubygems.org/
|
3
8
|
specs:
|
4
|
-
|
5
|
-
|
9
|
+
addressable (2.3.5)
|
10
|
+
builder (3.2.2)
|
11
|
+
faraday (0.8.8)
|
12
|
+
multipart-post (~> 1.2.0)
|
13
|
+
git (1.2.6)
|
14
|
+
github_api (0.10.1)
|
15
|
+
addressable
|
16
|
+
faraday (~> 0.8.1)
|
17
|
+
hashie (>= 1.2)
|
18
|
+
multi_json (~> 1.4)
|
19
|
+
nokogiri (~> 1.5.2)
|
20
|
+
oauth2
|
21
|
+
hashie (2.0.5)
|
22
|
+
highline (1.6.19)
|
23
|
+
httpauth (0.2.0)
|
24
|
+
jeweler (1.8.7)
|
25
|
+
builder
|
6
26
|
bundler (~> 1.0)
|
7
27
|
git (>= 1.2.5)
|
28
|
+
github_api (= 0.10.1)
|
29
|
+
highline (>= 1.6.15)
|
30
|
+
nokogiri (= 1.5.10)
|
8
31
|
rake
|
9
32
|
rdoc
|
10
|
-
json (1.
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
33
|
+
json (1.8.0)
|
34
|
+
json (1.8.0-java)
|
35
|
+
jwt (0.1.8)
|
36
|
+
multi_json (>= 1.5)
|
37
|
+
minitest (5.0.7)
|
38
|
+
multi_json (1.7.3)
|
39
|
+
multi_xml (0.5.5)
|
40
|
+
multipart-post (1.2.0)
|
41
|
+
nokogiri (1.5.10)
|
42
|
+
nokogiri (1.5.10-java)
|
43
|
+
oauth2 (0.9.2)
|
44
|
+
faraday (~> 0.8)
|
45
|
+
httpauth (~> 0.2)
|
46
|
+
jwt (~> 0.1.4)
|
47
|
+
multi_json (~> 1.0)
|
48
|
+
multi_xml (~> 0.5)
|
49
|
+
rack (~> 1.2)
|
50
|
+
rack (1.5.2)
|
51
|
+
rake (10.1.0)
|
52
|
+
rdoc (4.0.1)
|
15
53
|
json (~> 1.4)
|
16
|
-
simplecov (0.
|
54
|
+
simplecov (0.7.1)
|
17
55
|
multi_json (~> 1.0)
|
18
|
-
simplecov-html (~> 0.
|
19
|
-
simplecov-html (0.
|
20
|
-
yard (0.7.
|
56
|
+
simplecov-html (~> 0.7.1)
|
57
|
+
simplecov-html (0.7.1)
|
58
|
+
yard (0.8.7.1)
|
21
59
|
|
22
60
|
PLATFORMS
|
61
|
+
java
|
23
62
|
ruby
|
24
63
|
|
25
64
|
DEPENDENCIES
|
26
|
-
bundler (>= 1.
|
27
|
-
jeweler (>= 1.8.
|
28
|
-
minitest (>=
|
29
|
-
|
30
|
-
simplecov (>= 0.
|
31
|
-
yard (>= 0.7)
|
65
|
+
bundler (>= 1.3.5)
|
66
|
+
jeweler (>= 1.8.7)
|
67
|
+
minitest (>= 5.0.7)
|
68
|
+
police-vminfo (>= 0.0.2)!
|
69
|
+
simplecov (>= 0.7.1)
|
70
|
+
yard (>= 0.8.7.1)
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/lib/police/dataflow.rb
CHANGED
@@ -8,9 +8,10 @@ end # namespace Police
|
|
8
8
|
|
9
9
|
|
10
10
|
require 'police/dataflow/core_extensions.rb'
|
11
|
-
require 'police/dataflow/
|
11
|
+
require 'police/dataflow/gating.rb'
|
12
12
|
require 'police/dataflow/label.rb'
|
13
13
|
require 'police/dataflow/labeling.rb'
|
14
14
|
require 'police/dataflow/proxies.rb'
|
15
15
|
require 'police/dataflow/proxy_base.rb'
|
16
|
+
require 'police/dataflow/proxy_numeric.rb'
|
16
17
|
require 'police/dataflow/proxying.rb'
|
@@ -1,12 +1,26 @@
|
|
1
1
|
# @private
|
2
|
-
# The methods below are used by the Police::
|
2
|
+
# The methods below are used by the {Police::DataFlow} implementation, and
|
3
3
|
# should not be called directly.
|
4
|
-
class
|
5
|
-
# Counterpart to the Police::DataFlow::ProxyBase#__police_labels__
|
4
|
+
class BasicObject
|
5
|
+
# Counterpart to the {Police::DataFlow::ProxyBase#__police_labels__} getter.
|
6
6
|
#
|
7
|
-
# @
|
7
|
+
# @private
|
8
|
+
# Use the {Police::DataFlow} API instead of reading this directly.
|
9
|
+
#
|
10
|
+
# @return [NilClass] nil, to help the {Police::DataFlow} implementation
|
8
11
|
# distinguish between "real" objects and label-carrying proxies
|
9
12
|
def __police_labels__
|
10
13
|
nil
|
11
14
|
end
|
15
|
+
|
16
|
+
# Counterpart to {Police::DataFlow::ProxyBase#__police_stickies__}.
|
17
|
+
#
|
18
|
+
# @private
|
19
|
+
# Use the {Police::DataFlow} API instead of reading this directly.
|
20
|
+
#
|
21
|
+
# @return [NilClass] nil, to help the {Police::DataFlow} implementation
|
22
|
+
# distinguish between "real" objects and label-carrying proxies
|
23
|
+
def __police_stickies__
|
24
|
+
nil
|
25
|
+
end
|
12
26
|
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
---
|
2
|
+
:core:
|
3
|
+
- Array
|
4
|
+
- BasicObject
|
5
|
+
- Bignum
|
6
|
+
- Binding
|
7
|
+
- Class
|
8
|
+
- Comparable
|
9
|
+
- Complex
|
10
|
+
- Dir
|
11
|
+
- Encoding
|
12
|
+
- Encoding::Converter
|
13
|
+
- Enumerable
|
14
|
+
- Enumerator
|
15
|
+
- Enumerator::Yielder
|
16
|
+
- Exception
|
17
|
+
- FalseClass
|
18
|
+
- Fiber
|
19
|
+
- File
|
20
|
+
- File::Stat
|
21
|
+
- FileTest
|
22
|
+
- Fixnum
|
23
|
+
- Float
|
24
|
+
- GC
|
25
|
+
- GC::Profiler
|
26
|
+
- Hash
|
27
|
+
- IO
|
28
|
+
- Integer
|
29
|
+
- Kernel
|
30
|
+
- Marshal
|
31
|
+
- MatchData
|
32
|
+
- Math
|
33
|
+
- Method
|
34
|
+
- Module
|
35
|
+
- Mutex
|
36
|
+
- NilClass
|
37
|
+
- Numeric
|
38
|
+
- ObjectSpace
|
39
|
+
- Proc
|
40
|
+
- Process
|
41
|
+
- Process::GID
|
42
|
+
- Process::Status
|
43
|
+
- Process::Sys
|
44
|
+
- Process::UID
|
45
|
+
- Random
|
46
|
+
- Range
|
47
|
+
- Rational
|
48
|
+
- Regexp
|
49
|
+
- RubyVM::InstructionSequence
|
50
|
+
- Signal
|
51
|
+
- String
|
52
|
+
- Struct
|
53
|
+
- Struct::Tms
|
54
|
+
- Symbol
|
55
|
+
- SystemCallError
|
56
|
+
- Thread
|
57
|
+
- ThreadGroup
|
58
|
+
- Time
|
59
|
+
- TrueClass
|
60
|
+
- UnboundMethod
|
61
|
+
:class:
|
62
|
+
Array:
|
63
|
+
- :[]
|
64
|
+
- :try_convert
|
65
|
+
File:
|
66
|
+
- :absolute_path
|
67
|
+
- :basename
|
68
|
+
- :dirname
|
69
|
+
- :extname
|
70
|
+
- :fnmatch
|
71
|
+
- :ftype
|
72
|
+
- :join
|
73
|
+
- :path
|
74
|
+
- :readlink
|
75
|
+
- :realdirpath
|
76
|
+
- :realpath
|
77
|
+
- :split
|
78
|
+
- :stat
|
79
|
+
- :symlink
|
80
|
+
- :truncate
|
81
|
+
- :unlink
|
82
|
+
Regexp:
|
83
|
+
- :compile
|
84
|
+
- :escape
|
85
|
+
- :last_match
|
86
|
+
- :quote
|
87
|
+
- :try_convert
|
88
|
+
- :union
|
89
|
+
String:
|
90
|
+
- :try_convert
|
91
|
+
Struct:
|
92
|
+
- :new
|
93
|
+
:instance:
|
94
|
+
Array:
|
95
|
+
- :&
|
96
|
+
- :*
|
97
|
+
- :+
|
98
|
+
- :-
|
99
|
+
- :<<
|
100
|
+
- :<=>
|
101
|
+
- :==
|
102
|
+
- :[]
|
103
|
+
- :[]=
|
104
|
+
- :assoc
|
105
|
+
- :combination
|
106
|
+
- :concat
|
107
|
+
- :cycle
|
108
|
+
- :fill
|
109
|
+
- :find_index
|
110
|
+
- :first
|
111
|
+
- :flatten
|
112
|
+
- :flatten!
|
113
|
+
- :include?
|
114
|
+
- :insert
|
115
|
+
- :join
|
116
|
+
- :last
|
117
|
+
- :pack
|
118
|
+
- :permutation
|
119
|
+
- :pop
|
120
|
+
- :product
|
121
|
+
- :push
|
122
|
+
- :rassoc
|
123
|
+
- :repeated_combination
|
124
|
+
- :repeated_permutation
|
125
|
+
- :replace
|
126
|
+
- :sample
|
127
|
+
- :shift
|
128
|
+
- :take
|
129
|
+
- :unshift
|
130
|
+
- :values_at
|
131
|
+
- :zip
|
132
|
+
- :|
|
133
|
+
Encoding:
|
134
|
+
- :_dump
|
135
|
+
- :replicate
|
136
|
+
Encoding::Converter:
|
137
|
+
- :convert
|
138
|
+
- :insert_output
|
139
|
+
- :primitive_convert
|
140
|
+
- :putback
|
141
|
+
Hash:
|
142
|
+
- :member?
|
143
|
+
- :merge
|
144
|
+
- :merge!
|
145
|
+
Regexp:
|
146
|
+
- :match
|
147
|
+
String:
|
148
|
+
- :%
|
149
|
+
- :+
|
150
|
+
- :<<
|
151
|
+
- :concat
|
152
|
+
- :gsub
|
153
|
+
- :gsub!
|
154
|
+
- :insert
|
155
|
+
- :match
|
156
|
+
- :prepend
|
157
|
+
- :replace
|
158
|
+
- :scan
|
159
|
+
- :squeeze
|
160
|
+
- :squeeze!
|
161
|
+
- :sub
|
162
|
+
- :sub!
|
163
|
+
- :sum
|
164
|
+
- :tr
|
165
|
+
- :tr!
|
166
|
+
- :tr_s
|
167
|
+
- :tr_s!
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Police
|
4
|
+
|
5
|
+
module DataFlow
|
6
|
+
# Sets up label-propagating gates around all the native methods in the VM.
|
7
|
+
#
|
8
|
+
# This method is idempotent, so it is safe to call it multiple times.
|
9
|
+
def self.setup_gates
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
# Gating logic.
|
14
|
+
module Gating
|
15
|
+
# Sets up label-propagating gates around all the native methods in the VM.
|
16
|
+
#
|
17
|
+
# This method is idempotent, so it is safe to call it multiple times.
|
18
|
+
def self.setup_gates
|
19
|
+
return if @gates_set
|
20
|
+
setup_gates!
|
21
|
+
@gates_set = true
|
22
|
+
end
|
23
|
+
@gates_set = false
|
24
|
+
|
25
|
+
# Sets up label-propagating gates around all the native methods in Ruby.
|
26
|
+
#
|
27
|
+
# @private
|
28
|
+
# Call setup_gates instead of calling this method directly.
|
29
|
+
def self.setup_gates!
|
30
|
+
Police::VmInfo.named_modules do |module_object|
|
31
|
+
Police::VmInfo.class_methods(module_object).each do |method|
|
32
|
+
next unless Police::VmInfo.method_source(method) == :native
|
33
|
+
gate_class_method module_object, method
|
34
|
+
end
|
35
|
+
Police::VmInfo.instance_methods(module_object).each do |method|
|
36
|
+
next unless Police::VmInfo.method_source(method) == :native
|
37
|
+
gate_instance_method module_object, method
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Sets up a label-propagating gate around a native method.
|
43
|
+
#
|
44
|
+
# @param {Module} module_object the Ruby module that owns (declared) the
|
45
|
+
# method that will be gated
|
46
|
+
# @param {Method, UnboundMethod} method the method that will be gated
|
47
|
+
def self.gate_class_method(module_object, method)
|
48
|
+
gate_instance_method module_object.singleton_class, method
|
49
|
+
end
|
50
|
+
|
51
|
+
# Sets up a label-propagating gate around a native method.
|
52
|
+
#
|
53
|
+
# @param {Module} module_object the Ruby module that owns (declareD) the
|
54
|
+
# method that will be gated
|
55
|
+
# @param {Method, UnboundMethod} method the method that will be gated
|
56
|
+
def self.gate_instance_method(module_object, method)
|
57
|
+
alias_name = :"__police_gated__#{method.name}"
|
58
|
+
if module_object.public_method_defined?(alias_name) ||
|
59
|
+
module_object.private_method_defined?(alias_name) ||
|
60
|
+
module_object.protected_method_defined?(alias_name)
|
61
|
+
raise RuntimeError, "#{method.inspect} was already gated"
|
62
|
+
end
|
63
|
+
|
64
|
+
# TODO(pwnall): finish this code
|
65
|
+
end
|
66
|
+
end # namespace Police::DataFlow::Guarding
|
67
|
+
|
68
|
+
end # namespace Police::DataFlow
|
69
|
+
|
70
|
+
end # namespace Police
|
@@ -6,31 +6,36 @@ module DataFlow
|
|
6
6
|
class Label
|
7
7
|
# True for labels that automatically propagate across operations.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
9
|
+
# This method's return value is used for methods where the label does not
|
10
|
+
# provide a hook. When present, hooks are responsible for label propagation.
|
11
|
+
#
|
12
|
+
# Labels that indicate privacy should be sticky. For example, an
|
13
|
+
# auto-generated message that contains a user's phone number is just as
|
14
|
+
# sensitive as the phone number.
|
15
|
+
#
|
16
|
+
# Labels that indicate sanitization should not be sticky. For example, a
|
17
|
+
# substring of an HTML-sanitized string is not necessarily HTML-sanitized.
|
15
18
|
#
|
16
19
|
# @return [Boolean] if true, the label will be automatically added to objects
|
17
|
-
# whose value is likely to be derived from other labeled objects
|
18
|
-
|
20
|
+
# whose value is likely to be derived from other labeled objects; the
|
21
|
+
# return value for a given method name should always be the same
|
22
|
+
def self.sticky?
|
19
23
|
true
|
20
24
|
end
|
21
|
-
|
25
|
+
|
22
26
|
# Label method changing the return value of a method in a labeled object.
|
23
27
|
#
|
24
28
|
# @param [Symbol] method_name the name of the method that will be decorated
|
25
29
|
# by the label
|
26
30
|
# @return [Symbol, NilClass] the name of a label instance method that will
|
27
|
-
# be given a chance to label the decorated method's return value
|
31
|
+
# be given a chance to label the decorated method's return value; the
|
32
|
+
# return value for a given method name should always be the same
|
28
33
|
#
|
29
34
|
# @see Police::DataFlow::Label.sample_return_hook
|
30
35
|
def self.return_hook(method_name)
|
31
36
|
:sample_return_hook
|
32
37
|
end
|
33
|
-
|
38
|
+
|
34
39
|
# Label method changing the values yielded by a method in a labeled object.
|
35
40
|
#
|
36
41
|
# @param [Symbol] method_name the name of the method that will be decorated
|
@@ -43,7 +48,7 @@ class Label
|
|
43
48
|
def self.yield_args_hook(method_name)
|
44
49
|
:sample_yield_args_hook
|
45
50
|
end
|
46
|
-
|
51
|
+
|
47
52
|
# Hook that can label a decorated method's return value.
|
48
53
|
#
|
49
54
|
# @param [Object] value the decorated method's return value; if a method is
|
@@ -52,7 +57,7 @@ class Label
|
|
52
57
|
# @param [Object] receiver the object that the decorated method was called on
|
53
58
|
# @param [Array] args the arguments passed to the decorated method
|
54
59
|
# @return [Object] either the un-modified value argument, or the return value
|
55
|
-
# of calling Police::
|
60
|
+
# of calling {Police::DataFlow.label} on the value argument
|
56
61
|
def sample_return_hook(value, receiver, *args)
|
57
62
|
Police::DataFlow.label value, self
|
58
63
|
end
|
@@ -62,7 +67,7 @@ class Label
|
|
62
67
|
# @param [Object] receiver the object that the decorated method was called on
|
63
68
|
# @param [Array] yield_args the arguments yielded by the decorated method to
|
64
69
|
# its block; the array's elements can be replaced with the return values
|
65
|
-
# of calling Police::DataFlow.label on them; if a method is
|
70
|
+
# of calling {Police::DataFlow.label} on them; if a method is
|
66
71
|
# decorated by multiple labels, the values might be already labeled by
|
67
72
|
# another label's yield values hook
|
68
73
|
# @param [Array] args the arguments passed to the decorated method
|