virustotal_api 0.5.0 → 0.5.5

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: 68e1f3494830e62ef04f24a74431a540d3dd6943ee329b772b8a3629798f0856
4
- data.tar.gz: 58e0b36a8a6745b2db5957ab4b48da429f9ec154b1116d0110933cbc54d9f456
3
+ metadata.gz: 4d61c90abdeb3a513e29da52a083c10044eace4aa1f51e6b758798abfee9137a
4
+ data.tar.gz: eae6f4130f49c3e5b6d17553aaf4c4e6725e7e74260ae2c0c250bc0130823c55
5
5
  SHA512:
6
- metadata.gz: 03cf94231610ed5e8002c60dde3cc6d3b3d4ab52682be470023911559c0df6f2cf9230532fe3f002bd2587268405b086742e73a9edba86a4de49eaca37ab1b6b
7
- data.tar.gz: a831140e24d0302e971a33f3b44d7c9760aa271b27d4036bf310ada72f09aa9cd11d1c685793d2a78a0ac6814725de873f8ea6419e92461febef84bb909f2065
6
+ metadata.gz: ef0c2142c1e1ad07be96a88a035f7c906c22c67bb183e7c5906256a1ba83a03378eb985eb02fae68362bb9d9e1439fffef7c82eccfd9a3004144ac6640dd14f3
7
+ data.tar.gz: 2016ad82dadcc09fd03e3ca89cc324bcf7670a3a762a0ea1464569171e589e9d83052f7f95210406747f3d7b3b0ff93e8f67801a35c8d1d42bb482270b036717
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear and concise description of what the bug is.
12
+
13
+ **To Reproduce**
14
+ Steps to reproduce the behavior:
15
+ 1. Go to '...'
16
+ 2. Click on '....'
17
+ 3. Scroll down to '....'
18
+ 4. See error
19
+
20
+ **Expected behavior**
21
+ A clear and concise description of what you expected to happen.
22
+
23
+ **Screenshots**
24
+ If applicable, add screenshots to help explain your problem.
25
+
26
+ **Desktop (please complete the following information):**
27
+ - OS: [e.g. iOS]
28
+ - Browser [e.g. chrome, safari]
29
+ - Version [e.g. 22]
30
+
31
+ **Smartphone (please complete the following information):**
32
+ - Device: [e.g. iPhone6]
33
+ - OS: [e.g. iOS8.1]
34
+ - Browser [e.g. stock browser, safari]
35
+ - Version [e.g. 22]
36
+
37
+ **Additional context**
38
+ Add any other context about the problem here.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Is your feature request related to a problem? Please describe.**
11
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
+
13
+ **Describe the solution you'd like**
14
+ A clear and concise description of what you want to happen.
15
+
16
+ **Describe alternatives you've considered**
17
+ A clear and concise description of any alternative solutions or features you've considered.
18
+
19
+ **Additional context**
20
+ Add any other context or screenshots about the feature request here.
@@ -0,0 +1,11 @@
1
+ CHANGELOG: no-impact/Added/Changed/Deprecated/Removed/Fixed/Security
2
+
3
+ ## Summary
4
+
5
+ ## Testing
6
+
7
+ 1. _Describe how to test this change_
8
+
9
+ ## Other Information
10
+
11
+ _Include screenshots, GIFs, and/or API responses as appropriate._
@@ -7,17 +7,56 @@ on:
7
7
  branches: [ master ]
8
8
 
9
9
  jobs:
10
- Test:
10
+ Test-Ruby-2-5:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+ - name: Set up Ruby
15
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
16
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
17
+ uses: ruby/setup-ruby@v1.70.1
18
+ with:
19
+ ruby-version: 2.5
20
+ - name: Show Ruby Version
21
+ run: ruby --version
22
+ - name: Install dependencies
23
+ run: bundle install
24
+ - name: Lint
25
+ run: bundle exec rake rubocop
26
+ - name: Run tests
27
+ run: bundle exec rake
28
+
29
+ Test-Ruby-2-7:
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@v2
33
+ - name: Set up Ruby
34
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
35
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
36
+ uses: ruby/setup-ruby@v1.70.1
37
+ with:
38
+ ruby-version: 2.7
39
+ - name: Show Ruby Version
40
+ run: ruby --version
41
+ - name: Install dependencies
42
+ run: bundle install
43
+ - name: Lint
44
+ run: bundle exec rake rubocop
45
+ - name: Run tests
46
+ run: bundle exec rake
47
+
48
+ Test-Ruby-3-0:
11
49
  runs-on: ubuntu-latest
12
-
13
50
  steps:
14
51
  - uses: actions/checkout@v2
15
52
  - name: Set up Ruby
16
53
  # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
17
54
  # change this to (see https://github.com/ruby/setup-ruby#versioning):
18
- uses: ruby/setup-ruby@v1.46.0
55
+ uses: ruby/setup-ruby@v1.70.1
19
56
  with:
20
- ruby-version: 2.6
57
+ ruby-version: 3.0
58
+ - name: Show Ruby Version
59
+ run: ruby --version
21
60
  - name: Install dependencies
22
61
  run: bundle install
23
62
  - name: Lint
data/CHANGELOG.md CHANGED
@@ -1,8 +1,32 @@
1
1
  # VirusTotal API Changelog
2
2
 
3
+ ## [0.5.5] - 2021-05-10
4
+ * Add support for larger files
5
+ * [@Grandman](https://github.com/Grandman)
6
+
7
+ ## [0.5.4] - 2020-12-10
8
+ * Manage bad requests like not found
9
+ * Use strict base64 encoding
10
+ * [@crondaemon](https://github.com/crondaemon)
11
+
12
+ ## [0.5.3] = 2020-10-12
13
+
14
+ ## [0.5.2] - 2020-10-06
15
+
16
+ * Fix Fix exists? check
17
+ * Fix detected_by for File
18
+ * Fix RateLimitError
19
+ * Added User and Group API
20
+ * [@jonnynux](https://github.com/jonnynux)
21
+
22
+ ## [0.5.1] - 2020-10-06
23
+
24
+ * Downgrade ruby requirement to 2.5.
25
+ * [@crondaemon](https://github.com/crondaemon)
26
+
3
27
  ## [0.5.0] - 2020-09-02
4
28
 
5
- * Full rework to support API V3.
29
+ * Full rework to support API V3 [#30](https://github.com/pwelch/virustotal_api/pull/30)
6
30
  * [@crondaemon](https://github.com/crondaemon) & [@jonnynux](https://github.com/jonnynux)
7
31
  * Move to Ruby 2.6 for minimum Ruby version
8
32
 
data/README.md CHANGED
@@ -65,7 +65,10 @@ require 'virustotal_api'
65
65
  file = '/path/to/file'
66
66
  api_key = 'MY_API_KEY'
67
67
 
68
+ # for upload file
68
69
  vtscan = VirustotalAPI::File.upload(file, api_key)
70
+ # or large file (more than 32MB)
71
+ vtscan = VirustotalAPI::File.upload_large(file, api_key)
69
72
 
70
73
  # Virustotal ID of file
71
74
  vtscan.id
@@ -117,7 +120,7 @@ vturl_report.exists?
117
120
 
118
121
  # URL for Report (if it exists)
119
122
  vturl_report.report_url
120
- # => "https://www.virustotal.com/api/v3/urls/dd014af5ed6b38d9130e3f466f850e46d21b951199d53a18ef29ee9341614eaf/"
123
+ # => "https://www.virustotal.com/api/v3/urls/dd014af5ed6b38d9130e3f466f850e46d21b951199d53a18ef29ee9341614eaf"
121
124
 
122
125
  # Report results (if they exist) are available via #report
123
126
  vturl_report.report['data']['attributes']['last_analysis_results']['Avira']
@@ -161,6 +164,10 @@ vtip_report = VirustotalAPI::IP.find(ip, api_key)
161
164
  vtip_report.exists?
162
165
  # => true
163
166
 
167
+ # URL for Report (if it exists)
168
+ vtip_report.report_url
169
+ # => "https://www.virustotal.com/api/v3/ip_addresses/8.8.8.8"
170
+
164
171
  # Report results (if they exist) are available via #report
165
172
  vtip_report.report
166
173
  # => Hash of report results
@@ -180,17 +187,60 @@ vtdomain_report = VirustotalAPI::Domain.find(domain, api_key)
180
187
  vtdomain_report.exists?
181
188
  # => true
182
189
 
190
+ # URL for Report (if it exists)
191
+ vtdomain_report.report_url
192
+ # => "https://www.virustotal.com/api/v3/domains/virustotal.com"
193
+
183
194
  # Report results (if they exist) are available via #report
184
195
  vtdomain_report.report
185
196
  # => Hash of report results
186
197
  ```
187
198
 
199
+ ### User Find
200
+
201
+ ```ruby
202
+ require 'virustotal_api'
203
+
204
+ user_key = 'user_key' # user_id or api_key
205
+ api_key = 'MY_API_KEY'
206
+
207
+ vtuser_report = VirustotalAPI::User.find(user_key, api_key)
208
+
209
+ # Does the resource have any results?
210
+ vtuser_report.exists?
211
+ # => true
212
+
213
+ # Report results (if they exist) are available via #report
214
+ vtuser_report.report
215
+ # => Hash of report results
216
+ ```
217
+
218
+ ### Group Find
219
+
220
+ ```ruby
221
+ require 'virustotal_api'
222
+
223
+ group_id = 'GROUP_id'
224
+ api_key = 'MY_API_KEY'
225
+
226
+ vtgroup_report = VirustotalAPI::Group.find(group_id, api_key)
227
+
228
+ # Does the resource have any results?
229
+ vtgroup_report.exists?
230
+ # => true
231
+
232
+ # Report results (if they exist) are available via #report
233
+ vtgroup_report.report
234
+ # => Hash of report results
235
+ ```
236
+
188
237
  ## Contributors
189
238
 
190
- - [@postmodern](https://github.com/postmodern)
191
- - [@mkunkel](https://github.com/mkunkel)
192
239
  - [@jonnynux](https://github.com/jonnynux)
193
240
  - [@crondaemon](https://github.com/crondaemon/)
241
+ - [@postmodern](https://github.com/postmodern)
242
+ - [@mkunkel](https://github.com/mkunkel)
243
+ - [@Grandman](https://github.com/Grandman)
194
244
 
195
245
  ## Contributing
196
246
 
@@ -3,7 +3,9 @@
3
3
  require 'virustotal_api/analysis'
4
4
  require 'virustotal_api/domain'
5
5
  require 'virustotal_api/file'
6
+ require 'virustotal_api/group'
6
7
  require 'virustotal_api/ip'
7
8
  require 'virustotal_api/url'
8
9
  require 'virustotal_api/uri'
10
+ require 'virustotal_api/user'
9
11
  require 'virustotal_api/version'
@@ -5,13 +5,6 @@ require_relative 'base'
5
5
  module VirustotalAPI
6
6
  # A class for '/analyses' API
7
7
  class Analysis < Base
8
- attr_reader :report
9
-
10
- # rubocop:disable Lint/MissingSuper
11
- def initialize(report)
12
- @report = report
13
- end
14
-
15
8
  # @param [String] id The Virustotal ID to get the report for.
16
9
  # @param [String] api_key The key for virustotal
17
10
  # @return [VirustotalAPI::IP] Report
@@ -21,4 +14,3 @@ module VirustotalAPI
21
14
  end
22
15
  end
23
16
  end
24
- # rubocop:enable Lint/MissingSuper
@@ -9,10 +9,12 @@ require 'base64'
9
9
  module VirustotalAPI
10
10
  # The base class implementing the raw calls to Virustotal API V3.
11
11
  class Base
12
- attr_reader :report
12
+ attr_reader :report, :report_url, :id
13
13
 
14
14
  def initialize(report)
15
- @report = report
15
+ @report = report
16
+ @report_url = report&.dig('data', 'links', 'self')
17
+ @id = report&.dig('data', 'id')
16
18
  end
17
19
 
18
20
  # @return [String] string of API URI class method
@@ -20,6 +22,14 @@ module VirustotalAPI
20
22
  VirustotalAPI::URI
21
23
  end
22
24
 
25
+ def self.perform(path, api_key, method = :get, options = {})
26
+ base_perform(api_uri + path, api_key, method, options)
27
+ end
28
+
29
+ def self.perform_absolute(url, api_key, method = :get, options = {})
30
+ base_perform(url, api_key, method, options)
31
+ end
32
+
23
33
  # The actual method performing a call to Virustotal
24
34
  #
25
35
  # @param [String] url The url of the API
@@ -27,22 +37,28 @@ module VirustotalAPI
27
37
  # @param [String] method The HTTP method to use
28
38
  # @param [Hash] options Options to pass as payload
29
39
  # @return [VirustotalAPI::Domain] Report Search Result
30
- def self.perform(url, api_key, method = :get, options = {})
40
+ def self.base_perform(url, api_key, method = :get, options = {})
31
41
  response = RestClient::Request.execute(
32
42
  method: method,
33
- url: api_uri + url,
43
+ url: url,
34
44
  headers: { 'x-apikey': api_key },
35
45
  payload: options
36
46
  )
37
47
  JSON.parse(response.body)
38
- rescue RestClient::NotFound
39
- nil
48
+ rescue RestClient::NotFound, RestClient::BadRequest
49
+ {}
40
50
  rescue RestClient::Unauthorized
41
51
  # Raise a custom exception not to expose the underlying
42
52
  # HTTP client.
43
53
  raise VirustotalAPI::Unauthorized
54
+ rescue RestClient::TooManyRequests
55
+ # Raise a custom exception not to expose the underlying
56
+ # HTTP client.
57
+ raise VirustotalAPI::RateLimitError
44
58
  end
45
59
 
60
+ private_class_method :base_perform
61
+
46
62
  # @return [String] string of API URI instance method
47
63
  def api_uri
48
64
  self.class.api_uri
@@ -56,7 +72,7 @@ module VirustotalAPI
56
72
  # Generate a URL identifier.
57
73
  # @see https://developers.virustotal.com/v3.0/reference#url
58
74
  def self.url_identifier(url)
59
- Base64.encode64(url).strip.gsub('=', '')
75
+ Base64.strict_encode64(url).strip.gsub('=', '')
60
76
  end
61
77
  end
62
78
  end
@@ -5,11 +5,6 @@ require_relative 'base'
5
5
  module VirustotalAPI
6
6
  # A class for '/domains' API
7
7
  class Domain < Base
8
- # rubocop:disable Lint/UselessMethodDefinition
9
- def initialize(report)
10
- super(report)
11
- end
12
-
13
8
  # Find a domain.
14
9
  #
15
10
  # @param [String] domain The domain to search
@@ -21,4 +16,3 @@ module VirustotalAPI
21
16
  end
22
17
  end
23
18
  end
24
- # rubocop:enable Lint/UselessMethodDefinition
@@ -5,14 +5,6 @@ require_relative 'base'
5
5
  module VirustotalAPI
6
6
  # A class for '/files' API
7
7
  class File < Base
8
- attr_reader :id, :report_url
9
-
10
- def initialize(report)
11
- super(report)
12
- @id = report&.dig('data', 'id')
13
- @report_url = report&.dig('data', 'links', 'self')
14
- end
15
-
16
8
  # Find a hash.
17
9
  #
18
10
  # @param [String] resource file as a md5/sha1/sha256 hash
@@ -31,7 +23,20 @@ module VirustotalAPI
31
23
  # @return [VirusotalAPI::File] Report
32
24
  def self.upload(file_path, api_key, opts = {})
33
25
  filename = opts.fetch('filename') { ::File.basename(file_path) }
34
- report = perform('/files', api_key, :post, filename: filename, file: ::File.open(file_path, 'r'))
26
+ report = perform('/files', api_key, :post, filename: filename, file: ::File.open(file_path, 'r'))
27
+ new(report)
28
+ end
29
+
30
+ # Upload a new file with size more than 32MB.
31
+ #
32
+ # @param [String] file_path for file to be sent for scan
33
+ # @param [String] api_key The key for virustotal
34
+ # @param [Hash] opts hash for additional options
35
+ # @return [VirusotalAPI::File] Report
36
+ def self.upload_large(file_path, api_key, opts = {})
37
+ filename = opts.fetch('filename') { ::File.basename(file_path) }
38
+ url = upload_url(api_key)
39
+ report = perform_absolute(url, api_key, :post, filename: filename, file: ::File.open(file_path, 'r'))
35
40
  new(report)
36
41
  end
37
42
 
@@ -45,12 +50,18 @@ module VirustotalAPI
45
50
  new(report)
46
51
  end
47
52
 
53
+ # @return [String] url for upload file
54
+ def self.upload_url(api_key)
55
+ data = perform('/files/upload_url', api_key)
56
+ data&.dig('data')
57
+ end
58
+
48
59
  # Check if the submitted hash is detected by an AV engine.
49
60
  #
50
61
  # @param [String] engine The engine to check.
51
62
  # @return [Boolean] true if detected
52
63
  def detected_by(engine)
53
- report['data']['attributes']['last_analysis_results'][engine]['category'] == 'harmless'
64
+ report&.dig('data', 'attributes', 'last_analysis_results', engine, 'category') == 'malicious'
54
65
  end
55
66
  end
56
67
  end