tainted 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b26e5de6db90715d8868475b14f828ee951472378e2ab3d751bb36e0ab570a1
4
- data.tar.gz: 4e84f893cefc8c37f52b9b353ff80ea3a63eba096f625d6acb2061aefb83d299
3
+ metadata.gz: 278da9234147c4a8df18795ca9666877032253e8cb4409219ba0fd8e4420444b
4
+ data.tar.gz: 16e24fa14406e9755b3f631809a23a13fcf255605b5f6a2f66fc60d27ecee27a
5
5
  SHA512:
6
- metadata.gz: 2a73d2e0c62366eb397b64c7f4cd8d78f643ba1179bafa4534664c901cadc683d3b1d375a205024e0716930d17634076de122e36e3f96c2c8f53f0310ac747c9
7
- data.tar.gz: f1444e63ab1f1fa2cbb328b19d2676c5eabc5948ae6a4bc7af0167ce08c7dd898ea5ee203629ab30adec04c76d0ed652c1966ff008c4806775d8e4039726aaeb
6
+ metadata.gz: b1fdc6834f8e8727e6e7fa0328ddd4193d4a7433f3c020f16eacaa6d63ef61f96b682a7a7e8b34db7e39d28a4554c77373d96467bb3a9cab8b8b00348d4b0fd0
7
+ data.tar.gz: 96b9a1687308bed7f57317dd66ece9eca69a7d0e2a7544cc8e40861017911d447aa11244daf44d5e3d27620358e80150e117b008c3a7a97b76e633608ff73f31
data/README.md CHANGED
@@ -29,8 +29,13 @@ require 'tainted'
29
29
  file = "#{__dir__}/../fixtures/simple.rb"
30
30
  lint = Tainted::Lint.new(file, %i[tainted], %i[unsafe])
31
31
  lint.analyze
32
- # Method `unsafe()` consuming tainted variable `d`
33
- # Method `unsafe()` consuming tainted variable `c`
32
+ =>
33
+ [#<Tainted::Offense:0x0000000107caf690
34
+ @message="Method `unsafe()` consuming tainted variable `d`",
35
+ @node=(call nil nil (ident "unsafe") (arg_paren (args ((var_ref (ident "d"))))))>,
36
+ #<Tainted::Offense:0x0000000107caf5f0
37
+ @message="Method `unsafe()` consuming tainted variable `c`",
38
+ @node=(call nil nil (ident "unsafe") (arg_paren (args ((var_ref (ident "c"))))))>]
34
39
  ```
35
40
 
36
41
  ## Development
data/Rakefile CHANGED
@@ -9,4 +9,4 @@ require "rubocop/rake_task"
9
9
 
10
10
  RuboCop::RakeTask.new
11
11
 
12
- task default: %i[spec rubocop]
12
+ task default: %i[spec]
data/lib/tainted/lint.rb CHANGED
@@ -5,7 +5,7 @@ module Tainted
5
5
  def initialize(filepath, sources, sinks)
6
6
  @filepath = filepath
7
7
 
8
- t = Tainted::DataFlow.new(@filepath)
8
+ t = DataFlow.new(@filepath)
9
9
  t.generate
10
10
  var_dependencies = t.tainted
11
11
  State.instance.var_dependencies = var_dependencies
@@ -15,7 +15,7 @@ module Tainted
15
15
 
16
16
  def analyze
17
17
  @visitor.visit(SyntaxTree.parse_file(@filepath))
18
- @visitor.result
18
+ @visitor.offenses
19
19
  end
20
20
  end
21
21
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tainted
4
+ class Offense
5
+ attr_reader :node, :message
6
+
7
+ def initialize(node, message)
8
+ @node = node
9
+ @message = message
10
+ end
11
+ end
12
+ end
@@ -2,13 +2,14 @@
2
2
 
3
3
  module Tainted
4
4
  class Static < SyntaxTree::Visitor
5
- attr_reader :result
5
+ attr_reader :offenses
6
6
 
7
- def initialize(sources, _sinks)
7
+ def initialize(sources, sinks)
8
8
  super()
9
9
 
10
10
  @sources = sources
11
- @result = []
11
+ @sinks = sinks
12
+ @offenses = []
12
13
  end
13
14
 
14
15
  def visit(node)
@@ -29,10 +30,17 @@ module Tainted
29
30
 
30
31
  def parse_assign(node)
31
32
  variable_name = node.target.value.value
32
- # pp node.value.class
33
- return unless node.value.is_a?(SyntaxTree::CallNode)
34
33
 
35
- method_name = node.value.message.value
34
+ method_name =
35
+ case node.value
36
+ when SyntaxTree::CallNode
37
+ node.value.message.value
38
+ when SyntaxTree::ARef
39
+ # (aref (vcall (ident "<method_name>")))
40
+ node.value.collection.value.value
41
+ end
42
+
43
+ return if method_name.nil?
36
44
  return unless @sources.include?(method_name&.to_sym)
37
45
 
38
46
  State.instance.var_dependencies[variable_name.to_sym][:tainted] = true
@@ -45,10 +53,12 @@ module Tainted
45
53
  arguments.map { |arg| [arg, taint_status(arg.value.value.to_sym)] }
46
54
 
47
55
  method_name = node.message.value
56
+ return unless @sinks.include?(method_name.to_sym)
57
+
48
58
  taint_statuses.each do |status|
49
59
  next unless status[1]
50
60
 
51
- @result << "Method `#{method_name}()` consuming tainted variable `#{status[0].value.value}`"
61
+ @offenses << Offense.new(node, "Method `#{method_name}()` consuming tainted variable `#{status[0].value.value}`")
52
62
  end
53
63
  end
54
64
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tainted
4
- VERSION = "0.1.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/tainted.rb CHANGED
@@ -6,6 +6,7 @@ require_relative "tainted/state"
6
6
  require_relative "tainted/static"
7
7
  require_relative "tainted/lint"
8
8
  require_relative "tainted/dataflow"
9
+ require_relative "tainted/offense"
9
10
  require_relative "tainted/version"
10
11
 
11
12
  module Tainted
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tainted
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Syed Faraaz Ahmad
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-23 00:00:00.000000000 Z
11
+ date: 2023-11-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -23,10 +23,10 @@ files:
23
23
  - LICENSE.txt
24
24
  - README.md
25
25
  - Rakefile
26
- - fixtures/simple.rb
27
26
  - lib/tainted.rb
28
27
  - lib/tainted/dataflow.rb
29
28
  - lib/tainted/lint.rb
29
+ - lib/tainted/offense.rb
30
30
  - lib/tainted/state.rb
31
31
  - lib/tainted/static.rb
32
32
  - lib/tainted/version.rb
data/fixtures/simple.rb DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- a = tainted()
4
- b = a + 1
5
- c = b + 2
6
- d = b + c
7
- unsafe(d)
8
- unsafe(c)