hackerone-client 0.15.0 → 0.20.0
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/.github/workflows/build.yml +28 -12
- data/.rubocop.yml +4 -0
- data/CHANGELOG.md +21 -0
- data/Gemfile +11 -3
- data/Guardfile +2 -0
- data/README.md +8 -2
- data/Rakefile +10 -1
- data/bin/console +1 -0
- data/fixtures/vcr_cassettes/create_report.yml +81 -0
- data/fixtures/vcr_cassettes/create_report_invalid.yml +79 -0
- data/fixtures/vcr_cassettes/lock_report.yml +156 -0
- data/fixtures/vcr_cassettes/report.yml +22 -1
- data/fixtures/vcr_cassettes/report_list_triaged.yml +77 -0
- data/fixtures/vcr_cassettes/update_severity.yml +78 -0
- data/hackerone-client.gemspec +4 -2
- data/lib/hackerone/client.rb +56 -9
- data/lib/hackerone/client/activity.rb +20 -8
- data/lib/hackerone/client/address.rb +2 -0
- data/lib/hackerone/client/attachment.rb +24 -0
- data/lib/hackerone/client/bounty.rb +2 -0
- data/lib/hackerone/client/group.rb +2 -0
- data/lib/hackerone/client/incremental/activities.rb +3 -1
- data/lib/hackerone/client/member.rb +2 -0
- data/lib/hackerone/client/program.rb +4 -2
- data/lib/hackerone/client/report.rb +63 -5
- data/lib/hackerone/client/reporter.rb +2 -0
- data/lib/hackerone/client/resource_helper.rb +5 -3
- data/lib/hackerone/client/structured_scope.rb +2 -0
- data/lib/hackerone/client/swag.rb +2 -0
- data/lib/hackerone/client/user.rb +2 -0
- data/lib/hackerone/client/version.rb +3 -1
- data/lib/hackerone/client/weakness.rb +16 -14
- metadata +9 -2
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "./resource_helper"
|
2
4
|
|
3
5
|
module HackerOne
|
4
6
|
module Client
|
@@ -71,7 +73,7 @@ module HackerOne
|
|
71
73
|
"programs/#{id}/swag",
|
72
74
|
params: { page: { number: page_number, size: page_size } }
|
73
75
|
)
|
74
|
-
response_body.map{|r| Swag.new(r, self) }
|
76
|
+
response_body.map { |r| Swag.new(r, self) }
|
75
77
|
end
|
76
78
|
|
77
79
|
private
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require_relative
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "./resource_helper"
|
4
|
+
require_relative "./weakness"
|
5
|
+
require_relative "./activity"
|
4
6
|
|
5
7
|
module HackerOne
|
6
8
|
module Client
|
@@ -24,6 +26,22 @@ module HackerOne
|
|
24
26
|
duplicate
|
25
27
|
).map(&:to_sym).freeze
|
26
28
|
|
29
|
+
RESOLVED_STATES = %w(
|
30
|
+
resolved
|
31
|
+
not-applicable
|
32
|
+
informative
|
33
|
+
duplicate
|
34
|
+
spam
|
35
|
+
).map(&:to_sym).freeze
|
36
|
+
|
37
|
+
SEVERITY_RATINGS = %w(
|
38
|
+
none
|
39
|
+
low
|
40
|
+
medium
|
41
|
+
high
|
42
|
+
critical
|
43
|
+
).freeze
|
44
|
+
|
27
45
|
class << self
|
28
46
|
def add_on_state_change_hook(proc)
|
29
47
|
on_state_change_hooks << proc
|
@@ -62,6 +80,10 @@ module HackerOne
|
|
62
80
|
attributes[:issue_tracker_reference_id]
|
63
81
|
end
|
64
82
|
|
83
|
+
def severity
|
84
|
+
attributes[:severity]
|
85
|
+
end
|
86
|
+
|
65
87
|
def state
|
66
88
|
attributes[:state]
|
67
89
|
end
|
@@ -118,7 +140,13 @@ module HackerOne
|
|
118
140
|
|
119
141
|
# Bounty writeups just use the key, and not the label value.
|
120
142
|
def writeup_classification
|
121
|
-
classification_label
|
143
|
+
classification_label.split("-").first
|
144
|
+
end
|
145
|
+
|
146
|
+
def attachments
|
147
|
+
@attachments ||= relationships.fetch(:attachments, {})
|
148
|
+
.fetch(:data, [])
|
149
|
+
.map { |attachment| HackerOne::Client::Attachment.new(attachment) }
|
122
150
|
end
|
123
151
|
|
124
152
|
def activities
|
@@ -159,6 +187,23 @@ module HackerOne
|
|
159
187
|
Swag.new(response_body, program)
|
160
188
|
end
|
161
189
|
|
190
|
+
def update_severity(rating:)
|
191
|
+
raise ArgumentError, "Invalid severity rating" unless SEVERITY_RATINGS.include?(rating.to_s)
|
192
|
+
|
193
|
+
request_body = {
|
194
|
+
type: "severity",
|
195
|
+
attributes: {
|
196
|
+
rating: rating
|
197
|
+
}
|
198
|
+
}
|
199
|
+
response_body = make_post_request(
|
200
|
+
"reports/#{id}/severities",
|
201
|
+
request_body: request_body
|
202
|
+
)
|
203
|
+
@report[:attributes][:severity] = { rating: rating }
|
204
|
+
Activities.build(response_body)
|
205
|
+
end
|
206
|
+
|
162
207
|
def suggest_bounty(message:, amount:, bonus_amount: nil)
|
163
208
|
request_body = {
|
164
209
|
message: message,
|
@@ -261,6 +306,19 @@ module HackerOne
|
|
261
306
|
HackerOne::Client::Activities.build(response_json)
|
262
307
|
end
|
263
308
|
|
309
|
+
def lock!
|
310
|
+
unless RESOLVED_STATES.include? self.state.to_sym
|
311
|
+
raise ArgumentError, "Report must be closed before locking"
|
312
|
+
end
|
313
|
+
|
314
|
+
body = {
|
315
|
+
type: "activity-comments-closed"
|
316
|
+
}
|
317
|
+
|
318
|
+
response_json = make_put_request("reports/#{id}/close_comments", request_body: body)
|
319
|
+
HackerOne::Client::Activities.build(response_json)
|
320
|
+
end
|
321
|
+
|
264
322
|
def assign_to_user(name)
|
265
323
|
member = program.find_member(name)
|
266
324
|
_assign_to(member.user.id, :user)
|
@@ -304,7 +362,7 @@ module HackerOne
|
|
304
362
|
request_body[:id] = assignee_id if assignee_id
|
305
363
|
|
306
364
|
response = HackerOne::Client::Api.hackerone_api_connection.put do |req|
|
307
|
-
req.headers[
|
365
|
+
req.headers["Content-Type"] = "application/json"
|
308
366
|
req.url "reports/#{id}/assignee"
|
309
367
|
req.body = { data: request_body }.to_json
|
310
368
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HackerOne
|
2
4
|
module Client
|
3
5
|
module ResourceHelper
|
@@ -14,7 +16,7 @@ module HackerOne
|
|
14
16
|
|
15
17
|
def make_put_request(url, request_body:, extract_data: true)
|
16
18
|
response = HackerOne::Client::Api.hackerone_api_connection.put do |req|
|
17
|
-
req.headers[
|
19
|
+
req.headers["Content-Type"] = "application/json"
|
18
20
|
req.url url
|
19
21
|
req.body = { data: request_body }.to_json
|
20
22
|
end
|
@@ -24,7 +26,7 @@ module HackerOne
|
|
24
26
|
|
25
27
|
def make_post_request(url, request_body:, extract_data: true)
|
26
28
|
response = HackerOne::Client::Api.hackerone_api_connection.post do |req|
|
27
|
-
req.headers[
|
29
|
+
req.headers["Content-Type"] = "application/json"
|
28
30
|
req.url url
|
29
31
|
req.body = { data: request_body }.to_json
|
30
32
|
end
|
@@ -34,7 +36,7 @@ module HackerOne
|
|
34
36
|
|
35
37
|
def make_get_request(url, params: {}, extract_data: true)
|
36
38
|
response = HackerOne::Client::Api.hackerone_api_connection.get do |req|
|
37
|
-
req.headers[
|
39
|
+
req.headers["Content-Type"] = "application/json"
|
38
40
|
req.url url
|
39
41
|
req.params = params
|
40
42
|
end
|
@@ -1,17 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HackerOne
|
2
4
|
module Client
|
3
5
|
class Weakness
|
4
6
|
class << self
|
5
7
|
def validate_cwe!(cwe)
|
6
|
-
fail NotAnOwaspWeaknessError if cwe.upcase.start_with?(
|
7
|
-
fail StandardError::ArgumentError unless cwe.upcase.start_with?(
|
8
|
+
fail NotAnOwaspWeaknessError if cwe.upcase.start_with?("CAPEC-")
|
9
|
+
fail StandardError::ArgumentError unless cwe.upcase.start_with?("CWE-")
|
8
10
|
end
|
9
11
|
|
10
12
|
def extract_cwe_number(cwe)
|
11
13
|
return if cwe.nil?
|
12
14
|
validate_cwe!(cwe)
|
13
15
|
|
14
|
-
cwe.split(
|
16
|
+
cwe.split("CWE-").last.to_i
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
@@ -39,20 +41,20 @@ module HackerOne
|
|
39
41
|
}
|
40
42
|
|
41
43
|
OWASP_TOP_10_2013_TO_CWE = {
|
42
|
-
|
43
|
-
|
44
|
+
"A1-Injection" => [77, 78, 88, 89, 90, 91, 564],
|
45
|
+
"A2-AuthSession" =>
|
44
46
|
[287, 613, 522, 256, 384, 472, 346, 441, 523, 620, 640, 319, 311],
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
47
|
+
"A3-XSS" => [79],
|
48
|
+
"A4-DirectObjRef" => [639, 99, 22],
|
49
|
+
"A5-Misconfig" => [16, 2, 215, 548, 209],
|
50
|
+
"A6-DataExposure" => [312, 319, 310, 326, 320, 311, 325, 328, 327],
|
51
|
+
"A7-MissingACL" => [285, 287],
|
52
|
+
"A8-CSRF" => [352, 642, 613, 346, 441],
|
53
|
+
"A9-KnownVuln" => [],
|
54
|
+
"A10-Redirects" => [601],
|
53
55
|
}.freeze
|
54
56
|
|
55
|
-
OWASP_DEFAULT =
|
57
|
+
OWASP_DEFAULT = "A0-Other".freeze
|
56
58
|
|
57
59
|
def initialize(weakness)
|
58
60
|
@attributes = weakness
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hackerone-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Neil Matatall
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- ".github/workflows/build.yml"
|
119
119
|
- ".gitignore"
|
120
120
|
- ".rspec"
|
121
|
+
- ".rubocop.yml"
|
121
122
|
- ".travis.yml"
|
122
123
|
- CHANGELOG.md
|
123
124
|
- CODE_OF_CONDUCT.md
|
@@ -141,12 +142,16 @@ files:
|
|
141
142
|
- fixtures/vcr_cassettes/award_a_bounty.yml
|
142
143
|
- fixtures/vcr_cassettes/award_swag.yml
|
143
144
|
- fixtures/vcr_cassettes/common_responses.yml
|
145
|
+
- fixtures/vcr_cassettes/create_report.yml
|
146
|
+
- fixtures/vcr_cassettes/create_report_invalid.yml
|
144
147
|
- fixtures/vcr_cassettes/dup.yml
|
145
148
|
- fixtures/vcr_cassettes/empty_report_list.yml
|
149
|
+
- fixtures/vcr_cassettes/lock_report.yml
|
146
150
|
- fixtures/vcr_cassettes/missing_report.yml
|
147
151
|
- fixtures/vcr_cassettes/programs.yml
|
148
152
|
- fixtures/vcr_cassettes/report.yml
|
149
153
|
- fixtures/vcr_cassettes/report_list.yml
|
154
|
+
- fixtures/vcr_cassettes/report_list_triaged.yml
|
150
155
|
- fixtures/vcr_cassettes/reporters.yml
|
151
156
|
- fixtures/vcr_cassettes/server_error.yml
|
152
157
|
- fixtures/vcr_cassettes/server_error_when_assigning_report_to_user.yml
|
@@ -158,11 +163,13 @@ files:
|
|
158
163
|
- fixtures/vcr_cassettes/traverse_through_all_activities.yml
|
159
164
|
- fixtures/vcr_cassettes/triage_and_hook_assign_report_to_user.yml
|
160
165
|
- fixtures/vcr_cassettes/update_policy.yml
|
166
|
+
- fixtures/vcr_cassettes/update_severity.yml
|
161
167
|
- fixtures/vcr_cassettes/user_find_fransrosen.yml
|
162
168
|
- hackerone-client.gemspec
|
163
169
|
- lib/hackerone/client.rb
|
164
170
|
- lib/hackerone/client/activity.rb
|
165
171
|
- lib/hackerone/client/address.rb
|
172
|
+
- lib/hackerone/client/attachment.rb
|
166
173
|
- lib/hackerone/client/bounty.rb
|
167
174
|
- lib/hackerone/client/group.rb
|
168
175
|
- lib/hackerone/client/incremental/activities.rb
|