-
Notifications
You must be signed in to change notification settings - Fork 23
/
wpscan-api.php
166 lines (148 loc) · 4.2 KB
/
wpscan-api.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<?php
/**
* WPScan API related functions for vip-go-ci.
*
* @package Automattic/vip-go-ci
*/
declare(strict_types=1);
/**
* Call WPScan API for the plugin or theme slug specified. Return the results.
*
* @param string $wpscan_slug Plugin or theme slug.
* @param string $wpscan_type Type of scan, plugin or theme
* -- use VIPGOCI_ADDON_PLUGIN or VIPGOCI_ADDON_THEME defines.
* @param string $wpscan_access_token WPScan access token to use.
*
* @return null|array Results from WPScan API as array on success, null on failure.
*/
function vipgoci_wpscan_do_scan_via_api(
string $wpscan_slug,
string $wpscan_type,
string $wpscan_access_token,
) :null|array {
/*
* Construct WPScan API URL
*/
$wpscan_complete_url = VIPGOCI_WPSCAN_API_BASE_URL;
if ( VIPGOCI_ADDON_PLUGIN === $wpscan_type ) {
$wpscan_complete_url .= '/plugins';
} elseif ( VIPGOCI_ADDON_THEME === $wpscan_type ) {
$wpscan_complete_url .= '/themes';
} else {
vipgoci_sysexit(
'Incorrect usage of $wpscan_type parameter in ' . __FUNCTION__,
array(),
VIPGOCI_EXIT_INTERNAL_ERROR
);
}
$wpscan_complete_url .= '/' . rawurlencode( $wpscan_slug );
/*
* Call WPScan API.
*/
vipgoci_log(
'Calling WPScan API for slug',
array(
'wpscan_slug' => $wpscan_slug,
'wpscan_type' => $wpscan_type,
'wpscan_complete_url' => $wpscan_complete_url,
),
0
);
$wpscan_report_json = vipgoci_http_api_fetch_url(
$wpscan_complete_url,
array(
'wpscan_token' => $wpscan_access_token,
),
);
vipgoci_log(
'WScan API returned data',
array(
'wpscan_slug' => $wpscan_slug,
'wpscan_type' => $wpscan_type,
'wpscan_complete_url' => $wpscan_complete_url,
'wpscan_report_json_preview' => vipgoci_preview_string( $wpscan_report_json ),
),
0
);
if ( null !== $wpscan_report_json ) {
$wpscan_report = json_decode(
$wpscan_report_json,
true
);
} else {
$wpscan_report = null;
}
/*
* Return information collected, or error.
*/
$log_detail = array(
'wpscan_slug' => $wpscan_slug,
'wpscan_type' => $wpscan_type,
'wpscan_complete_url' => $wpscan_complete_url,
'wpscan_report_json' => $wpscan_report_json,
'wpscan_report' => $wpscan_report,
);
if ( null === $wpscan_report ) {
vipgoci_log(
'WPscan API returned with error',
$log_detail,
0,
true // Log to IRC.
);
return null;
} elseif (
// Check if all expected keys exist.
( ! isset( $wpscan_report[ $wpscan_slug ]['friendly_name'] ) ) ||
( ! isset( $wpscan_report[ $wpscan_slug ]['latest_version'] ) ) ||
( ! isset( $wpscan_report[ $wpscan_slug ]['last_updated'] ) ) ||
( ! isset( $wpscan_report[ $wpscan_slug ]['vulnerabilities'] ) )
) {
vipgoci_log(
'WPscan API returned unexpected data',
$log_detail,
0,
true // Log to IRC.
);
return null;
} else {
return $wpscan_report;
}
}
/**
* Filter away any security problems fixed in earlier versions
* of the theme/plugin as indicated in WPScan API results.
*
* @param string $wpscan_slug Plugin or theme slug.
* @param string $version_number Version number of the plugin to use as baseline.
* @param array $wpscan_results WPScan API results array.
*
* @return null|array WPScan results on success, with only vulnerabilities affecting the current or later versions listed. On failure, null.
*/
function vipgoci_wpscan_filter_fixed_vulnerabilities(
string $wpscan_slug,
string $version_number,
array $wpscan_results
) :null|array {
if ( ! isset( $wpscan_results[ $wpscan_slug ]['vulnerabilities'] ) ) {
return null;
}
// Filter away vulnerabilities that affect versions older than $version_number.
$wpscan_results[ $wpscan_slug ] ['vulnerabilities'] = array_filter(
$wpscan_results[ $wpscan_slug ]['vulnerabilities'],
function( $vuln_item ) use ( $version_number ) {
if ( ! isset( $vuln_item['fixed_in'] ) ) {
return false;
}
return version_compare(
$version_number,
$vuln_item['fixed_in'],
'<'
);
}
);
// Ensure keys are reset before returning new value.
$wpscan_results[ $wpscan_slug ]['vulnerabilities'] = array_values(
$wpscan_results[ $wpscan_slug ]['vulnerabilities']
);
return $wpscan_results;
}