This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /* |
||
3 | * hirak/prestissimo |
||
4 | * @author Hiraku NAKANO |
||
5 | * @license MIT https://github.com/hirak/prestissimo |
||
6 | */ |
||
7 | namespace Hirak\Prestissimo; |
||
8 | |||
9 | use Composer\Util; |
||
10 | use Composer\IO; |
||
11 | |||
12 | class BaseRequest |
||
13 | { |
||
14 | private $scheme; |
||
15 | private $user; |
||
16 | private $pass; |
||
17 | private $host; |
||
18 | private $port; |
||
19 | private $path; |
||
20 | private $query = array(); |
||
21 | |||
22 | /** @var [string => string] */ |
||
23 | private $headers = array(); |
||
24 | |||
25 | private $capath; |
||
26 | private $cafile; |
||
27 | |||
28 | protected static $defaultCurlOptions = array(); |
||
29 | |||
30 | private static $NSS_CIPHERS = array( |
||
31 | 'rsa_3des_sha', |
||
32 | 'rsa_des_sha', |
||
33 | 'rsa_null_md5', |
||
34 | 'rsa_null_sha', |
||
35 | 'rsa_rc2_40_md5', |
||
36 | 'rsa_rc4_128_md5', |
||
37 | 'rsa_rc4_128_sha', |
||
38 | 'rsa_rc4_40_md5', |
||
39 | 'fips_des_sha', |
||
40 | 'fips_3des_sha', |
||
41 | 'rsa_des_56_sha', |
||
42 | 'rsa_rc4_56_sha', |
||
43 | 'rsa_aes_128_sha', |
||
44 | 'rsa_aes_256_sha', |
||
45 | 'rsa_aes_128_gcm_sha_256', |
||
46 | 'dhe_rsa_aes_128_gcm_sha_256', |
||
47 | 'ecdh_ecdsa_null_sha', |
||
48 | 'ecdh_ecdsa_rc4_128_sha', |
||
49 | 'ecdh_ecdsa_3des_sha', |
||
50 | 'ecdh_ecdsa_aes_128_sha', |
||
51 | 'ecdh_ecdsa_aes_256_sha', |
||
52 | 'ecdhe_ecdsa_null_sha', |
||
53 | 'ecdhe_ecdsa_rc4_128_sha', |
||
54 | 'ecdhe_ecdsa_3des_sha', |
||
55 | 'ecdhe_ecdsa_aes_128_sha', |
||
56 | 'ecdhe_ecdsa_aes_256_sha', |
||
57 | 'ecdh_rsa_null_sha', |
||
58 | 'ecdh_rsa_128_sha', |
||
59 | 'ecdh_rsa_3des_sha', |
||
60 | 'ecdh_rsa_aes_128_sha', |
||
61 | 'ecdh_rsa_aes_256_sha', |
||
62 | 'ecdhe_rsa_rc4_128_sha', |
||
63 | 'ecdhe_rsa_3des_sha', |
||
64 | 'ecdhe_rsa_aes_128_sha', |
||
65 | 'ecdhe_rsa_aes_256_sha', |
||
66 | 'ecdhe_ecdsa_aes_128_gcm_sha_256', |
||
67 | 'ecdhe_rsa_aes_128_gcm_sha_256', |
||
68 | ); |
||
69 | |||
70 | /** |
||
71 | * enable ECC cipher suites in cURL/NSS |
||
72 | * @codeCoverageIgnore |
||
73 | */ |
||
74 | public static function nssCiphers() |
||
75 | { |
||
76 | static $cache; |
||
77 | if (isset($cache)) { |
||
78 | return $cache; |
||
79 | } |
||
80 | $ver = curl_version(); |
||
81 | if (preg_match('/^NSS.*Basic ECC$/', $ver['ssl_version'])) { |
||
82 | return $cache = implode(',', self::$NSS_CIPHERS); |
||
83 | } |
||
84 | return $cache = false; |
||
85 | } |
||
86 | |||
87 | 5 | protected function getProxy($url) |
|
88 | { |
||
89 | 5 | if (isset($_SERVER['no_proxy'])) { |
|
90 | 1 | $pattern = new Util\NoProxyPattern($_SERVER['no_proxy']); |
|
91 | 1 | if ($pattern->test($url)) { |
|
92 | 1 | return null; |
|
93 | } |
||
94 | } |
||
95 | |||
96 | // @see https://httpoxy.org/ |
||
97 | 5 | if (!defined('PHP_SAPI') || PHP_SAPI !== 'cli') { |
|
98 | return null; |
||
99 | } |
||
100 | |||
101 | 5 | foreach (array('https', 'http') as $scheme) { |
|
102 | 5 | if ($this->scheme === $scheme) { |
|
103 | 5 | $label = $scheme . '_proxy'; |
|
104 | 5 | foreach (array(strtoupper($label), $label) as $l) { |
|
105 | 5 | if (isset($_SERVER[$l])) { |
|
106 | 1 | return $_SERVER[$l]; |
|
107 | } |
||
108 | } |
||
109 | } |
||
110 | } |
||
111 | 4 | return null; |
|
112 | } |
||
113 | |||
114 | /** |
||
115 | * @param $io |
||
116 | * @param bool $useRedirector |
||
117 | * @param $githubDomains |
||
118 | * @param $gitlabDomains |
||
119 | */ |
||
120 | 6 | protected function setupAuthentication(IO\IOInterface $io, $useRedirector, array $githubDomains, array $gitlabDomains) |
|
121 | { |
||
122 | 6 | if (preg_match('/\.github\.com$/', $this->host)) { |
|
123 | 1 | $authKey = 'github.com'; |
|
124 | 1 | if ($useRedirector) { |
|
125 | 1 | if ($this->host === 'api.github.com' && preg_match('%^/repos(/[^/]+/[^/]+/)zipball(.+)$%', $this->path, $_)) { |
|
126 | 1 | $this->host = 'codeload.github.com'; |
|
127 | 1 | $this->path = $_[1] . 'legacy.zip' . $_[2]; |
|
128 | } |
||
129 | } |
||
130 | } else { |
||
131 | 5 | $authKey = $this->host; |
|
132 | } |
||
133 | 6 | if (!$io->hasAuthentication($authKey)) { |
|
134 | 4 | if ($this->user || $this->pass) { |
|
135 | 1 | $io->setAuthentication($authKey, $this->user, $this->pass); |
|
136 | } else { |
||
137 | 3 | return; |
|
138 | } |
||
139 | } |
||
140 | |||
141 | 3 | $auth = $io->getAuthentication($authKey); |
|
142 | |||
143 | // is github |
||
144 | 3 | View Code Duplication | if (in_array($authKey, $githubDomains) && 'x-oauth-basic' === $auth['password']) { |
0 ignored issues
–
show
|
|||
145 | 1 | $this->addHeader('authorization', 'token ' . $auth['username']); |
|
146 | 1 | $this->user = $this->pass = null; |
|
147 | 1 | return; |
|
148 | } |
||
149 | // is gitlab |
||
150 | 2 | if (in_array($authKey, $gitlabDomains)) { |
|
151 | 1 | View Code Duplication | if ('oauth2' === $auth['password']) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
152 | 1 | $this->addHeader('authorization', 'Bearer ' . $auth['username']); |
|
153 | 1 | $this->user = $this->pass = null; |
|
154 | 1 | return; |
|
155 | } |
||
156 | View Code Duplication | if ('private-token' === $auth['password']) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
157 | $this->addHeader('PRIVATE-TOKEN', $auth['username']); |
||
158 | $this->user = $this->pass = null; |
||
159 | return; |
||
160 | } |
||
161 | } |
||
162 | |||
163 | // others, includes bitbucket |
||
164 | 1 | $this->user = $auth['username']; |
|
165 | 1 | $this->pass = $auth['password']; |
|
166 | 1 | } |
|
167 | |||
168 | /** |
||
169 | * @return array |
||
170 | */ |
||
171 | 5 | public function getCurlOptions() |
|
172 | { |
||
173 | 5 | $headers = array(); |
|
174 | 5 | foreach ($this->headers as $key => $val) { |
|
175 | 2 | $headers[] = strtr(ucwords(strtr($key, '-', ' ')), ' ', '-') . ': ' . $val; |
|
176 | } |
||
177 | |||
178 | 5 | $url = $this->getURL(); |
|
179 | |||
180 | $curlOpts = array( |
||
181 | 5 | CURLOPT_URL => $url, |
|
182 | 5 | CURLOPT_HTTPHEADER => $headers, |
|
183 | 5 | CURLOPT_USERAGENT => ConfigFacade::getUserAgent(), |
|
184 | //CURLOPT_VERBOSE => true, //for debug |
||
185 | ); |
||
186 | 5 | $curlOpts += static::$defaultCurlOptions; |
|
187 | |||
188 | // @codeCoverageIgnoreStart |
||
189 | if ($ciphers = $this->nssCiphers()) { |
||
190 | $curlOpts[CURLOPT_SSL_CIPHER_LIST] = $ciphers; |
||
191 | } |
||
192 | // @codeCoverageIgnoreEnd |
||
193 | 5 | if ($proxy = $this->getProxy($url)) { |
|
194 | 1 | $curlOpts[CURLOPT_PROXY] = $proxy; |
|
195 | } |
||
196 | 5 | if ($this->capath) { |
|
197 | 1 | $curlOpts[CURLOPT_CAPATH] = $this->capath; |
|
198 | } |
||
199 | 5 | if ($this->cafile) { |
|
200 | 1 | $curlOpts[CURLOPT_CAINFO] = $this->cafile; |
|
201 | } |
||
202 | |||
203 | 5 | return $curlOpts; |
|
204 | } |
||
205 | |||
206 | /** |
||
207 | * @return string |
||
208 | */ |
||
209 | 7 | public function getURL() |
|
210 | { |
||
211 | 7 | $url = self::ifOr($this->scheme, '', '://'); |
|
212 | 7 | if ($this->user) { |
|
213 | 1 | $user = $this->user; |
|
214 | 1 | $user .= self::ifOr($this->pass, ':'); |
|
215 | 1 | $url .= $user . '@'; |
|
216 | } |
||
217 | 7 | $url .= self::ifOr($this->host); |
|
218 | 7 | $url .= self::ifOr($this->port, ':'); |
|
219 | 7 | $url .= self::ifOr($this->path); |
|
220 | 7 | $url .= self::ifOr(http_build_query($this->query), '?'); |
|
221 | 7 | return $url; |
|
222 | } |
||
223 | |||
224 | /** |
||
225 | * @return string user/pass/access_token masked url |
||
226 | */ |
||
227 | 1 | View Code Duplication | public function getMaskedURL() |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
228 | { |
||
229 | 1 | $url = self::ifOr($this->scheme, '', '://'); |
|
230 | 1 | $url .= self::ifOr($this->host); |
|
231 | 1 | $url .= self::ifOr($this->port, ':'); |
|
232 | 1 | $url .= self::ifOr($this->path); |
|
233 | 1 | return $url; |
|
234 | } |
||
235 | |||
236 | /** |
||
237 | * @return string |
||
238 | */ |
||
239 | 2 | View Code Duplication | public function getOriginURL() |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
240 | { |
||
241 | 2 | $url = self::ifOr($this->scheme, '', '://'); |
|
242 | 2 | $url .= self::ifOr($this->host); |
|
243 | 2 | $url .= self::ifOr($this->port, ':'); |
|
244 | 2 | return $url; |
|
245 | } |
||
246 | |||
247 | 9 | private static function ifOr($str, $pre = '', $post = '') |
|
248 | { |
||
249 | 9 | if ($str) { |
|
250 | 9 | return $pre . $str . $post; |
|
251 | } |
||
252 | 7 | return ''; |
|
253 | } |
||
254 | |||
255 | /** |
||
256 | * @param string $url |
||
257 | */ |
||
258 | 11 | public function setURL($url) |
|
259 | { |
||
260 | 11 | $struct = parse_url($url); |
|
261 | 11 | foreach ($struct as $key => $val) { |
|
0 ignored issues
–
show
The expression
$struct of type array<string,string>|false is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
262 | 11 | if ($key === 'query') { |
|
263 | 4 | parse_str($val, $this->query); |
|
264 | } else { |
||
265 | 11 | $this->$key = $val; |
|
266 | } |
||
267 | } |
||
268 | 11 | } |
|
269 | |||
270 | public function addParam($key, $val) |
||
271 | { |
||
272 | $this->query[$key] = $val; |
||
273 | } |
||
274 | |||
275 | 2 | public function addHeader($key, $val) |
|
276 | { |
||
277 | 2 | $this->headers[strtolower($key)] = $val; |
|
278 | 2 | } |
|
279 | |||
280 | 7 | public function setCA($path = null, $file = null) |
|
281 | { |
||
282 | 7 | $this->capath = $path; |
|
283 | 7 | $this->cafile = $file; |
|
284 | 7 | } |
|
285 | |||
286 | 1 | public function isHTTP() |
|
287 | { |
||
288 | 1 | return $this->scheme === 'http' || $this->scheme === 'https'; |
|
289 | } |
||
290 | } |
||
291 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.