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 | * @author Chris Hilsdon <[email protected]> |
||
4 | * @package ComodoDecodeCSR |
||
5 | * @copyright 2016 Xigen |
||
6 | * @license GNU General Public License v3 |
||
7 | * @link https://github.com/XigenChris/ComodoDecodeCSR |
||
8 | */ |
||
9 | |||
10 | namespace Xigen; |
||
11 | |||
12 | use GuzzleHttp\Client; |
||
13 | use GuzzleHttp\Exception\ClientException; |
||
14 | use GuzzleHttp\Psr7\Response; |
||
15 | |||
16 | class ComodoDecodeCSR |
||
17 | { |
||
18 | use Traits\GetSetUnset; |
||
19 | |||
20 | protected $MD5; |
||
21 | protected $SHA1; |
||
22 | protected $Endpoint = "https://secure.comodo.net/products/!decodeCSR"; |
||
23 | protected $CSR; |
||
24 | /** |
||
25 | * An array of warnings that can be show after the test |
||
26 | * @var array |
||
27 | */ |
||
28 | protected $warnings = []; |
||
29 | protected $Form = [ |
||
30 | 'responseFormat' => 'N', |
||
31 | 'showErrorCodes' => 'N', |
||
32 | 'showErrorMessages' => 'N', |
||
33 | 'showFieldNames' => 'N', |
||
34 | 'showEmptyFields' => 'N', |
||
35 | 'showCN' => 'N', |
||
36 | 'showAddress' => 'N', |
||
37 | 'showPublicKey' => 'N', |
||
38 | 'showKeySize' => 'N', |
||
39 | 'showSANDNSNames' => 'Y', |
||
40 | 'showCSR' => 'N', |
||
41 | 'showCSRHashes' => 'Y', |
||
42 | 'showSignatureAlgorithm' => 'N', |
||
43 | 10 | 'product' => '', |
|
44 | 'countryNameType' => 'TWOCHAR' |
||
45 | 10 | ]; |
|
46 | private $request; |
||
47 | 10 | ||
48 | 10 | private $forceSSL = false; |
|
49 | 10 | ||
50 | public function getCN() |
||
51 | 10 | { |
|
52 | $CSRInfo = $this->decodeCSR(); |
||
53 | return $CSRInfo['subject']['CN']; |
||
54 | 10 | } |
|
55 | |||
56 | 2 | public function setCSR($csr) |
|
57 | 2 | { |
|
58 | $this->CSR = $csr; |
||
59 | 2 | //Check that this is a valid CSR |
|
60 | $this->decodeCSR(); |
||
61 | $this->Form['csr'] = $csr; |
||
62 | 2 | } |
|
63 | 2 | ||
64 | 1 | protected function addWarning($code, $message) |
|
65 | 10 | { |
|
66 | $this->warnings[] = [ |
||
67 | 1 | $code => $message |
|
68 | 1 | ]; |
|
69 | } |
||
70 | |||
71 | 7 | public function fetchHashes() |
|
72 | { |
||
73 | 7 | $client = new Client(); |
|
74 | 7 | ||
75 | $this->request = $client->request('POST', $this->getEndpoint(), [ |
||
76 | 7 | 'form_params' => $this->Form |
|
77 | ]); |
||
78 | |||
79 | 7 | return $this->processResponse(); |
|
80 | } |
||
81 | 7 | ||
82 | public function checkInstalled() |
||
83 | { |
||
84 | 7 | ||
85 | 2 | try { |
|
86 | $domain = $this->getCN(); |
||
87 | } catch (\Exception $e) { |
||
88 | return false; |
||
89 | 5 | } |
|
90 | 1 | ||
91 | 1 | $response = $this->fetchDVCFile($domain); |
|
92 | if ($response == false) { |
||
93 | return false; |
||
94 | 5 | } |
|
95 | |||
96 | 2 | $check = $this->checkDVC($response); |
|
97 | 2 | if ($check === true) { |
|
98 | return $check; |
||
99 | } |
||
100 | 5 | ||
101 | 2 | //Try again but this time use https:// |
|
102 | $this->forceSSL = true; |
||
103 | |||
104 | 3 | $response = $this->fetchDVCFile($domain); |
|
105 | if ($response == false) { |
||
106 | return false; |
||
107 | 2 | } |
|
108 | |||
109 | 2 | $check = $this->checkDVC($response); |
|
110 | 2 | if ($check === true) { |
|
111 | 2 | //TODO Add a message to say then you will need to select 'HTTPS CSR |
|
112 | 2 | //Hash' |
|
113 | return $check; |
||
114 | } |
||
115 | 2 | ||
116 | return false; |
||
117 | 2 | } |
|
118 | |||
119 | public function generateDVC() |
||
120 | 10 | { |
|
121 | $DVC = $this->getSHA1() . "\n"; |
||
122 | 10 | $DVC .= "comodoca.com\n"; |
|
123 | 10 | ||
124 | 10 | return $DVC; |
|
125 | } |
||
126 | |||
127 | 10 | /** |
|
128 | * |
||
129 | 10 | * @param GuzzleHttp\Psr7\Response $response |
|
130 | 10 | * @return bool |
|
131 | 10 | */ |
|
132 | 10 | public function checkDVC(Response $response) |
|
133 | 10 | { |
|
134 | 10 | $body = $response->getBody() . ''; |
|
135 | $DVC = $this->generateDVC(); |
||
136 | 10 | ||
137 | 10 | //Check if we received a 301 or 302 redirect |
|
138 | if ($response->getStatusCode() === 301 || $response->getStatusCode() == 302) { |
||
139 | 10 | return false; |
|
140 | } |
||
141 | |||
142 | //If the response matches the DVC value return true |
||
143 | if ($body === $DVC) { |
||
144 | return true; |
||
145 | } |
||
146 | |||
147 | //Check if last 2 characters are new lines |
||
148 | if (substr($body, -2) === "\n\n") { |
||
149 | $body = substr($body, 0, -2) . "\n"; |
||
150 | } |
||
151 | |||
152 | //Check if last character is not a new line |
||
153 | if (substr($body, -1) !== "\n") { |
||
154 | //Add said new line |
||
155 | $body = $body . "\n"; |
||
156 | } |
||
157 | |||
158 | var_dump($body, $DVC); |
||
0 ignored issues
–
show
Security
Debugging Code
introduced
by
![]() |
|||
159 | |||
160 | //Check it again |
||
161 | if ($body === $DVC) { |
||
162 | return true; |
||
163 | } |
||
164 | |||
165 | return false; |
||
166 | } |
||
167 | |||
168 | private function decodeCSR() |
||
169 | { |
||
170 | try { |
||
171 | $data = openssl_csr_get_public_key($this->getCSR()); |
||
172 | $details = openssl_pkey_get_details($data); |
||
173 | $key = $details['key']; |
||
174 | $subject = openssl_csr_get_subject($this->getCSR()); |
||
175 | } catch (\Exception $e) { |
||
176 | throw new Exception("Invalid CSR"); |
||
177 | } |
||
178 | |||
179 | return array( |
||
180 | "subject" => $subject, |
||
181 | "key" => $key |
||
182 | ); |
||
183 | } |
||
184 | |||
185 | private function processResponse() |
||
186 | { |
||
187 | $response = $this->request->getBody(); |
||
188 | $lines = explode("\n", $response); |
||
189 | $data = array(); |
||
190 | //Remove the first array as we don't need the SAN and can cause problems |
||
191 | //with a multi domain SAN |
||
192 | unset($lines[0]); |
||
193 | |||
194 | foreach ($lines as $v) { |
||
195 | if (!empty($v)) { |
||
196 | $value = explode("=", $v); |
||
197 | $data[$value[0]] = $value[1]; |
||
198 | } |
||
199 | } |
||
200 | |||
201 | $this->setMD5($data["md5"]); |
||
202 | $this->setSHA1($data["sha1"]); |
||
203 | |||
204 | return $data ? $data : false; |
||
205 | } |
||
206 | |||
207 | private function fetchDVCFile($domain) |
||
208 | { |
||
209 | //We do most of our DVC over http:// unless the site is fully SSL |
||
210 | $protocol = 'http://'; |
||
211 | |||
212 | if ($this->forceSSL) { |
||
213 | $protocol = 'https://'; |
||
214 | } |
||
215 | |||
216 | $url = $protocol . $domain . "/" . $this->getMD5() . '.txt'; |
||
217 | |||
218 | $client = new Client(['allow_redirects' => false, 'verify' => false]); |
||
219 | |||
220 | try { |
||
221 | $response = $client->request('GET', $url); |
||
222 | } catch (ClientException $e) { |
||
223 | var_dump('te', $e); |
||
0 ignored issues
–
show
|
|||
224 | return false; |
||
225 | } |
||
226 | |||
227 | return $response; |
||
228 | } |
||
229 | } |
||
230 |