Rev 40 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 40 | Rev 42 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | <?php /* <ViaThinkSoftSignature> |
1 | <?php /* <ViaThinkSoftSignature> |
2 | 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 |
23 | g== |
23 | g== |
24 | </ViaThinkSoftSignature> */ ?> |
24 | </ViaThinkSoftSignature> */ ?> |
25 | <?php |
25 | <?php |
26 | 26 | ||
27 | /* |
27 | /* |
28 | * VNag - Nagios Framework for PHP |
28 | * VNag - Nagios Framework for PHP |
29 | * Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com> |
29 | * Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com> |
30 | * Licensed under the terms of the Apache 2.0 license |
30 | * Licensed under the terms of the Apache 2.0 license |
31 | * |
31 | * |
32 | * Revision 2021-12-06 |
32 | * Revision 2021-12-23 |
33 | */ |
33 | */ |
34 | 34 | ||
35 | declare(ticks=1); |
35 | declare(ticks=1); |
36 | 36 | ||
37 | class OpenBugBountyCheck extends VNag { |
37 | class OpenBugBountyCheck extends VNag { |
Line 107... | Line 107... | ||
107 | //assert(!empty($this->argDomain->getValue())); |
107 | //assert(!empty($this->argDomain->getValue())); |
108 | //assert(empty($this->argPrivateAPI->getValue())); |
108 | //assert(empty($this->argPrivateAPI->getValue())); |
109 | 109 | ||
110 | $fixed = 0; |
110 | $fixed = 0; |
111 | $unfixed = 0; |
111 | $unfixed = 0; |
- | 112 | $unfixed_ignored = 0; |
|
112 | 113 | ||
113 | $this->setStatus(VNag::STATUS_OK); |
114 | $this->setStatus(VNag::STATUS_OK); |
114 | 115 | ||
115 | $domain = strtolower($domain); |
116 | $domain = strtolower($domain); |
116 | $cache_file = $this->get_cache_dir() . '/' . md5($domain); |
117 | $cache_file = $this->get_cache_dir() . '/' . md5($domain); |
Line 127... | Line 128... | ||
127 | 128 | ||
128 | $xml = simplexml_load_string($cont); |
129 | $xml = simplexml_load_string($cont); |
129 | foreach ($xml as $x) { |
130 | foreach ($xml as $x) { |
130 | $submission = $x->url; |
131 | $submission = $x->url; |
131 | 132 | ||
- | 133 | if ($x->fixed == '1') { |
|
- | 134 | $fixed++; |
|
- | 135 | $this->addVerboseMessage("Fixed issue found at $domain: $submission", VNag::VERBOSITY_ADDITIONAL_INFORMATION); |
|
- | 136 | $this->setStatus(VNag::STATUS_OK); |
|
132 | if ($fake_fix = $this->is_ignored($this->extract_id_from_url($submission))) $x->fixed = '1'; |
137 | } else if ($this->is_ignored($this->extract_id_from_url($submission))) { |
133 | - | ||
134 | if ($x->fixed == '0') { |
138 | $unfixed_ignored++; |
- | 139 | $this->addVerboseMessage("Ignored issue found at $domain: $submission", VNag::VERBOSITY_ADDITIONAL_INFORMATION); |
|
- | 140 | $this->setStatus(VNag::STATUS_OK); |
|
- | 141 | } else { |
|
135 | $unfixed++; |
142 | $unfixed++; |
136 | $this->addVerboseMessage("Unfixed issue found at $domain: $submission", VNag::VERBOSITY_SUMMARY); |
143 | $this->addVerboseMessage("Unfixed issue found at $domain: $submission", VNag::VERBOSITY_SUMMARY); |
137 | $this->setStatus(VNag::STATUS_WARNING); |
144 | $this->setStatus(VNag::STATUS_WARNING); |
138 | // TODO: Unlike the "private" API, the "normal" API does not show if a bug is disclosed (= critical instead of warning) |
145 | // TODO: Unlike the "private" API, the "normal" API does not show if a bug is disclosed (= critical instead of warning) |
139 | // But we could check if the report is older than XXX months, and then we know that it must be disclosed. |
146 | // But we could check if the report is older than XXX months, and then we know that it must be disclosed. |
140 | } |
147 | } |
141 | 148 | ||
142 | if ($x->fixed == '1') { |
- | |
143 | $fixed++; |
- | |
144 | $tmp = $fake_fix ? ' (fix asserted by operator)' : ''; |
- | |
145 | $this->addVerboseMessage("Fixed issue found at $domain: $submission$tmp", VNag::VERBOSITY_ADDITIONAL_INFORMATION); |
- | |
146 | $this->setStatus(VNag::STATUS_OK); |
- | |
147 | } |
- | |
148 | } |
149 | } |
149 | 150 | ||
150 | return array($fixed, $unfixed); |
151 | return array($fixed, $unfixed, $unfixed_ignored); |
151 | } |
152 | } |
152 | 153 | ||
153 | function get_privateapi_data($url, $max_cache_time = 3600) { // TODO: make cache time configurable via config |
154 | function get_privateapi_data($url, $max_cache_time = 3600) { // TODO: make cache time configurable via config |
154 | $url = strtolower($url); |
155 | $url = strtolower($url); |
155 | $cache_file = $this->get_cache_dir() . '/' . md5($url); |
156 | $cache_file = $this->get_cache_dir() . '/' . md5($url); |
Line 173... | Line 174... | ||
173 | //assert(!empty($this->argPrivateAPI->getValue())); |
174 | //assert(!empty($this->argPrivateAPI->getValue())); |
174 | 175 | ||
175 | $sum_fixed = 0; |
176 | $sum_fixed = 0; |
176 | $sum_unfixed_pending = 0; |
177 | $sum_unfixed_pending = 0; |
177 | $sum_unfixed_disclosed = 0; |
178 | $sum_unfixed_disclosed = 0; |
- | 179 | $sum_unfixed_ignored = 0; |
|
178 | 180 | ||
179 | $this->setStatus(VNag::STATUS_OK); |
181 | $this->setStatus(VNag::STATUS_OK); |
180 | 182 | ||
181 | $ary = $this->get_privateapi_data($privateapi, $max_cache_time); |
183 | $ary = $this->get_privateapi_data($privateapi, $max_cache_time); |
182 | foreach ($ary as $id => $data) { |
184 | foreach ($ary as $id => $data) { |
Line 194... | Line 196... | ||
194 | if (empty($data['Vulnerability Reported'])) throw new Exception("This is probably not a correct Private API URL, or the service is down (Missing fields in structure)"); |
196 | if (empty($data['Vulnerability Reported'])) throw new Exception("This is probably not a correct Private API URL, or the service is down (Missing fields in structure)"); |
195 | 197 | ||
196 | $status = isset($data['Patch Status']) ? $data['Patch Status'] : $data['Path Status']; // sic! There is a typo in their API (reported, but not fixed) |
198 | $status = isset($data['Patch Status']) ? $data['Patch Status'] : $data['Path Status']; // sic! There is a typo in their API (reported, but not fixed) |
197 | 199 | ||
198 | $submission = $data['Report Url']; |
200 | $submission = $data['Report Url']; |
199 | if ($fake_fix = $this->is_ignored($this->extract_id_from_url($submission))) $status = 'Patched'; |
- | |
200 | - | ||
201 | $domain = $data['Host']; |
201 | $domain = $data['Host']; |
202 | 202 | ||
203 | if ($status == 'Patched') { |
203 | if ($status == 'Patched') { |
204 | $sum_fixed++; |
204 | $sum_fixed++; |
205 | $fixed_date = $fake_fix ? 'asserted by operator' : $data['Vulnerability Fixed']; |
205 | $fixed_date = $data['Vulnerability Fixed']; |
206 | $this->addVerboseMessage("Fixed issue found at $domain: $submission (fixed: $fixed_date)", VNag::VERBOSITY_ADDITIONAL_INFORMATION); |
206 | $this->addVerboseMessage("Fixed issue found at $domain: $submission (fixed: $fixed_date)", VNag::VERBOSITY_ADDITIONAL_INFORMATION); |
207 | $this->setStatus(VNag::STATUS_OK); |
207 | $this->setStatus(VNag::STATUS_OK); |
- | 208 | } else if ($this->is_ignored($this->extract_id_from_url($submission))) { |
|
- | 209 | $sum_unfixed_ignored++; |
|
- | 210 | $this->addVerboseMessage("Ignored issue found at $domain: $submission", VNag::VERBOSITY_ADDITIONAL_INFORMATION); |
|
- | 211 | $this->setStatus(VNag::STATUS_OK); |
|
208 | } else { |
212 | } else { |
209 | $disclosure = $data['Scheduled Public Disclosure']; |
213 | $disclosure = $data['Scheduled Public Disclosure']; |
210 | $time = strtotime(str_replace(',', '', $disclosure)); |
214 | $time = strtotime(str_replace(',', '', $disclosure)); |
211 | if (time() > $time) { |
215 | if (time() > $time) { |
212 | $sum_unfixed_disclosed++; |
216 | $sum_unfixed_disclosed++; |
Line 218... | Line 222... | ||
218 | $this->setStatus(VNag::STATUS_WARNING); |
222 | $this->setStatus(VNag::STATUS_WARNING); |
219 | } |
223 | } |
220 | } |
224 | } |
221 | } |
225 | } |
222 | 226 | ||
223 | return array($sum_fixed, $sum_unfixed_pending, $sum_unfixed_disclosed); |
227 | return array($sum_fixed, $sum_unfixed_pending, $sum_unfixed_disclosed, $sum_unfixed_ignored); |
224 | } |
228 | } |
225 | 229 | ||
226 | protected function cbRun($optional_args=array()) { |
230 | protected function cbRun($optional_args=array()) { |
227 | $domain = $this->argDomain->getValue(); |
231 | $domain = $this->argDomain->getValue(); |
228 | $privateapi = $this->argPrivateAPI->getValue(); |
232 | $privateapi = $this->argPrivateAPI->getValue(); |
Line 239... | Line 243... | ||
239 | // Possibility 1: Private API (showing all bugs for all of your domains, with detailled information) |
243 | // Possibility 1: Private API (showing all bugs for all of your domains, with detailled information) |
240 | // https://www.openbugbounty.org/api/2/.../ |
244 | // https://www.openbugbounty.org/api/2/.../ |
241 | $sum_fixed = 0; |
245 | $sum_fixed = 0; |
242 | $sum_unfixed_pending = 0; |
246 | $sum_unfixed_pending = 0; |
243 | $sum_unfixed_disclosed = 0; |
247 | $sum_unfixed_disclosed = 0; |
244 | list($sum_fixed, $sum_unfixed_pending, $sum_unfixed_disclosed) = $this->num_open_bugs_v2($privateapi); |
- | |
245 | if ($this->getVerbosityLevel() == VNag::VERBOSITY_SUMMARY) { |
248 | $sum_unfixed_ignored = 0; |
246 | $this->setHeadline(($sum_unfixed_pending + $sum_unfixed_disclosed)." unfixed ($sum_unfixed_pending pending, $sum_unfixed_disclosed disclosed) issues found at your domains", true); |
249 | list($sum_fixed, $sum_unfixed_pending, $sum_unfixed_disclosed, $sum_unfixed_ignored) = $this->num_open_bugs_v2($privateapi); |
247 | } else { |
- | |
248 | $this->setHeadline("$sum_fixed fixed and ".($sum_unfixed_pending + $sum_unfixed_disclosed)." unfixed ($sum_unfixed_pending pending, $sum_unfixed_disclosed disclosed) issues found at your domains", true); |
250 | $this->setHeadline("$sum_fixed fixed and ".($sum_unfixed_pending + $sum_unfixed_disclosed + $sum_unfixed_ignored)." unfixed ($sum_unfixed_pending pending, $sum_unfixed_disclosed disclosed, $sum_unfixed_ignored ignored) issues found at your domain(s)", true); |
249 | } |
- | |
250 | } else if (file_exists($domain)) { |
251 | } else if (file_exists($domain)) { |
251 | // Possibility 2: File containing a list of domains |
252 | // Possibility 2: File containing a list of domains |
252 | $domains = file($domain); |
253 | $domains = file($domain); |
253 | $sum_fixed = 0; |
254 | $sum_fixed = 0; |
254 | $sum_unfixed = 0; |
255 | $sum_unfixed = 0; |
- | 256 | $sum_unfixed_ignored = 0; |
|
255 | $count = 0; |
257 | $count = 0; |
256 | foreach ($domains as $domain) { |
258 | foreach ($domains as $domain) { |
257 | $domain = trim($domain); |
259 | $domain = trim($domain); |
258 | if ($domain == '') continue; |
260 | if ($domain == '') continue; |
259 | if ($domain[0] == '#') continue; |
261 | if ($domain[0] == '#') continue; |
260 | list($fixed, $unfixed) = $this->num_open_bugs_v1($domain); |
262 | list($fixed, $unfixed, $unfixed_ignored) = $this->num_open_bugs_v1($domain); |
261 | $sum_fixed += $fixed; |
263 | $sum_fixed += $fixed; |
262 | $sum_unfixed += $unfixed; |
264 | $sum_unfixed += $unfixed; |
- | 265 | $sum_unfixed_ignored += $unfixed_ignored; |
|
263 | $count++; |
266 | $count++; |
264 | $this->addVerboseMessage("$fixed fixed and $unfixed unfixed issues found at $domain", $unfixed > 0 ? VNag::VERBOSITY_SUMMARY : VNag::VERBOSITY_ADDITIONAL_INFORMATION); |
267 | $this->addVerboseMessage("$fixed fixed, $unfixed_ignored ignored, and $unfixed unfixed issues found at $domain", $unfixed > 0 ? VNag::VERBOSITY_SUMMARY : VNag::VERBOSITY_ADDITIONAL_INFORMATION); |
265 | } |
- | |
266 | if ($this->getVerbosityLevel() == VNag::VERBOSITY_SUMMARY) { |
- | |
267 | $this->setHeadline("$sum_unfixed unfixed issues found at $count domains", true); |
- | |
268 | } else { |
- | |
269 | $this->setHeadline("$sum_fixed fixed and $sum_unfixed unfixed issues found at $count domains", true); |
- | |
270 | } |
268 | } |
- | 269 | $this->setHeadline("$sum_fixed fixed and ".($sum_unfixed + $sum_unfixed_ignored)." unfixed (including $sum_unfixed_ignored ignored) issues found at $count domains", true); |
|
271 | } else if (strpos($domain, ',') !== false) { |
270 | } else if (strpos($domain, ',') !== false) { |
272 | // Possibility 3: Domains separated with comma |
271 | // Possibility 3: Domains separated with comma |
273 | $domains = explode(',', $domain); |
272 | $domains = explode(',', $domain); |
274 | $sum_fixed = 0; |
273 | $sum_fixed = 0; |
275 | $sum_unfixed = 0; |
274 | $sum_unfixed = 0; |
- | 275 | $sum_unfixed_ignored = 0; |
|
276 | $count = 0; |
276 | $count = 0; |
277 | foreach ($domains as $domain) { |
277 | foreach ($domains as $domain) { |
278 | list($fixed, $unfixed) = $this->num_open_bugs_v1($domain); |
278 | list($fixed, $unfixed, $unfixed_ignored) = $this->num_open_bugs_v1($domain); |
279 | $sum_fixed += $fixed; |
279 | $sum_fixed += $fixed; |
280 | $sum_unfixed += $unfixed; |
280 | $sum_unfixed += $unfixed; |
- | 281 | $sum_unfixed_ignored += $unfixed_ignored; |
|
281 | $count++; |
282 | $count++; |
282 | $this->addVerboseMessage("$fixed fixed and $unfixed unfixed issues found at $domain", $unfixed > 0 ? VNag::VERBOSITY_SUMMARY : VNag::VERBOSITY_ADDITIONAL_INFORMATION); |
283 | $this->addVerboseMessage("$fixed fixed, $unfixed_ignored ignored, and $unfixed unfixed issues found at $domain", $unfixed > 0 ? VNag::VERBOSITY_SUMMARY : VNag::VERBOSITY_ADDITIONAL_INFORMATION); |
283 | } |
- | |
284 | if ($this->getVerbosityLevel() == VNag::VERBOSITY_SUMMARY) { |
- | |
285 | $this->setHeadline("$sum_unfixed unfixed issues found at $count domains", true); |
- | |
286 | } else { |
- | |
287 | $this->setHeadline("$sum_fixed fixed and $sum_unfixed unfixed issues found at $count domains", true); |
- | |
288 | } |
284 | } |
- | 285 | $this->setHeadline("$sum_fixed fixed and ".($sum_unfixed + $sum_unfixed_ignored)." unfixed (including $sum_unfixed_ignored ignored) issues found at $count domains", true); |
|
289 | } else { |
286 | } else { |
290 | // Possibility 4: Single domain |
287 | // Possibility 4: Single domain |
291 | list($fixed, $unfixed) = $this->num_open_bugs_v1($domain); |
288 | list($sum_fixed, $sum_unfixed, $sum_unfixed_ignored) = $this->num_open_bugs_v1($domain); |
292 | if ($this->getVerbosityLevel() == VNag::VERBOSITY_SUMMARY) { |
- | |
293 | $this->setHeadline("$unfixed unfixed issues found at $domain", true); |
- | |
294 | } else { |
- | |
295 | $this->setHeadline("$fixed fixed and $unfixed unfixed issues found at $domain", true); |
289 | $this->setHeadline("$sum_fixed fixed and ".($sum_unfixed + $sum_unfixed_ignored)." unfixed (including $sum_unfixed_ignored ignored) issues found at $domain", true); |
296 | } |
- | |
297 | } |
290 | } |
298 | } |
291 | } |
299 | } |
292 | } |
300 | 293 |