1
|
|
|
<?php
|
2
|
|
|
/**
|
3
|
|
|
* Created by PhpStorm.
|
4
|
|
|
* User: Alessandro
|
5
|
|
|
* Date: 02/12/2015
|
6
|
|
|
* Time: 13:47
|
7
|
|
|
*/
|
8
|
|
|
|
9
|
|
|
namespace Padosoft\LaravelComposerSecurity;
|
10
|
|
|
|
11
|
|
|
use Illuminate\Console\Command;
|
12
|
|
|
use GuzzleHttp\Client;
|
13
|
|
|
|
14
|
|
|
class SensiolabHelper
|
15
|
|
|
{
|
16
|
|
|
|
17
|
|
|
protected $guzzle;
|
18
|
|
|
|
19
|
|
|
protected $command;
|
20
|
|
|
|
21
|
|
|
protected $tableVulnerabilities = [];
|
22
|
|
|
|
23
|
|
|
/**
|
24
|
|
|
* SensiolabHelper constructor.
|
25
|
|
|
* @param Client $objguzzle
|
26
|
|
|
* @param Command $objcommand
|
27
|
|
|
*/
|
28
|
12 |
|
public function __construct(Client $objguzzle, Command $objcommand)
|
29
|
|
|
{
|
30
|
12 |
|
$this->guzzle = $objguzzle;
|
31
|
12 |
|
$this->command = $objcommand;
|
32
|
12 |
|
}
|
33
|
|
|
|
34
|
|
|
/**
|
35
|
|
|
*
|
36
|
|
|
* Send Request to sensiolab and return array of sensiolab vulnerabilities.
|
37
|
|
|
* Empty array if here is no vulnerabilities.
|
38
|
|
|
*
|
39
|
|
|
* @param $fileLock path to composer.lock file.
|
40
|
|
|
*
|
41
|
|
|
* @return array
|
42
|
|
|
*/
|
43
|
10 |
|
public function getSensiolabVulnerabilties($fileLock)
|
44
|
|
|
{
|
45
|
10 |
|
$this->addVerboseLog('Send request to sensiolab: <info>'.$fileLock.'</info>');
|
46
|
|
|
|
47
|
10 |
|
$debug = false;//set to true to log into console output
|
48
|
|
|
$headers = [
|
49
|
|
|
//OPTIONS
|
50
|
|
|
'allow_redirects' => [
|
51
|
10 |
|
'max' => 3, // allow at most 10 redirects.
|
52
|
10 |
|
'strict' => true, // use "strict" RFC compliant redirects.
|
53
|
10 |
|
'referer' => true, // add a Referer header
|
54
|
10 |
|
'protocols' => ['http', 'https'], // only allow http and https URLs
|
55
|
|
|
'track_redirects' => false
|
56
|
10 |
|
],
|
57
|
10 |
|
'connect_timeout' => 20,//Use 0 to wait connection indefinitely
|
58
|
10 |
|
'timeout' => 30, //Use 0 to wait response indefinitely
|
59
|
10 |
|
'debug' => $debug,
|
60
|
|
|
//HEADERS
|
61
|
|
|
'headers' => [
|
62
|
|
|
'Accept' => 'application/json'
|
63
|
10 |
|
],
|
64
|
|
|
//UPLOAD FORM FILE
|
65
|
|
|
'multipart' => [
|
66
|
|
|
[
|
67
|
10 |
|
'name' => 'lock',
|
68
|
10 |
|
'contents' => fopen($fileLock, 'r')
|
69
|
10 |
|
]
|
70
|
10 |
|
]
|
71
|
10 |
|
];
|
72
|
10 |
|
$response = null;
|
73
|
|
|
|
74
|
|
|
try {
|
75
|
10 |
|
$iResponse = $this->guzzle->request('POST', 'https://security.sensiolabs.org/check_lock', $headers);
|
76
|
4 |
|
$responseBody = $iResponse->getBody()->getContents();
|
77
|
4 |
|
$response = json_decode($responseBody, true);
|
78
|
10 |
|
} catch (\GuzzleHttp\Exception\ClientException $e) {
|
79
|
4 |
|
$this->command->error("ClientException!\nMessage: ".$e->getMessage());
|
80
|
4 |
|
$colorTag = $this->getColorTagForStatusCode($e->getResponse()->getStatusCode());
|
81
|
4 |
|
$this->command->line("HTTP StatusCode: <{$colorTag}>".$e->getResponse()->getStatusCode()."<{$colorTag}>");
|
82
|
4 |
|
$this->printMessage($e->getResponse());
|
83
|
4 |
|
$this->printMessage($e->getRequest());
|
84
|
6 |
|
} catch (\GuzzleHttp\Exception\RequestException $e) {
|
85
|
4 |
|
$this->command->error("RequestException!\nMessage: ".$e->getMessage());
|
86
|
4 |
|
$this->printMessage($e->getRequest());
|
87
|
4 |
|
if ($e->hasResponse()) {
|
88
|
2 |
|
$colorTag = $this->getColorTagForStatusCode($e->getResponse()->getStatusCode());
|
89
|
2 |
|
$this->command->line("HTTP StatusCode: <{$colorTag}>".$e->getResponse()->getStatusCode()."<{$colorTag}>");
|
90
|
2 |
|
$this->printMessage($e->getResponse());
|
91
|
2 |
|
}
|
92
|
|
|
}
|
93
|
10 |
|
return $response;
|
94
|
|
|
}
|
95
|
|
|
|
96
|
|
|
/**
|
97
|
|
|
* @param $name
|
98
|
|
|
* @param $vulnerability
|
99
|
|
|
*/
|
100
|
4 |
|
public function parseVulnerability($name, $vulnerability)
|
101
|
|
|
{
|
102
|
|
|
$data = [
|
103
|
4 |
|
'name' => $name,
|
104
|
4 |
|
'version' => $vulnerability['version'],
|
105
|
4 |
|
'advisories' => array_values($vulnerability['advisories'])
|
106
|
4 |
|
];
|
107
|
4 |
|
unset($this->tableVulnerabilities);
|
108
|
4 |
|
foreach ($data['advisories'] as $key2 => $advisory) {
|
109
|
|
|
$data2 = [
|
110
|
4 |
|
'title' => $advisory['title'],
|
111
|
4 |
|
'link' => $advisory['link'],
|
112
|
4 |
|
'cve' => $advisory['cve']
|
113
|
4 |
|
];
|
114
|
|
|
|
115
|
|
|
$dataTable = [
|
116
|
4 |
|
'name' => $data['name'],
|
117
|
4 |
|
'version' => $data['version'],
|
118
|
4 |
|
'advisories' => $data2["title"]
|
119
|
4 |
|
];
|
120
|
|
|
|
121
|
4 |
|
$this->addVerboseLog($data['name'] . " " . $data['version'] . " " . $data2["title"], true);
|
122
|
4 |
|
$this->tableVulnerabilities[] =$dataTable;
|
123
|
4 |
|
}
|
124
|
|
|
|
125
|
4 |
|
return $this->tableVulnerabilities;
|
126
|
|
|
}
|
127
|
|
|
|
128
|
|
|
/**
|
129
|
|
|
* @param $msg
|
130
|
|
|
* @param bool|false $error
|
131
|
|
|
*/
|
132
|
12 |
|
private function addVerboseLog($msg, $error = false)
|
133
|
|
|
{
|
134
|
12 |
|
$verbose = $this->command->option('verbose');
|
135
|
12 |
|
if ($verbose) {
|
136
|
10 |
|
if ($error) {
|
137
|
2 |
|
$this->command->error($msg);
|
138
|
2 |
|
} else {
|
139
|
8 |
|
$this->command->line($msg);
|
140
|
|
|
}
|
141
|
10 |
|
}
|
142
|
12 |
|
}
|
143
|
|
|
|
144
|
|
|
/**
|
145
|
|
|
* @param \Psr\Http\Message\MessageInterface $message
|
146
|
|
|
*/
|
147
|
6 |
|
private function printMessage(\Psr\Http\Message\MessageInterface $message)
|
148
|
|
|
{
|
149
|
6 |
|
$type='';
|
150
|
6 |
|
if(is_a($message,'\Psr\Http\Message\RequestInterface')) {
|
151
|
6 |
|
$type='REQUEST';
|
152
|
6 |
|
} else if(is_a($message,'\Psr\Http\Message\ResponseInterface')) {
|
153
|
6 |
|
$type='RESPONSE';
|
154
|
6 |
|
}
|
155
|
6 |
|
$this->command->info("$type:");
|
156
|
6 |
|
$headers='';
|
157
|
6 |
|
foreach ($message->getHeaders() as $name => $values) {
|
158
|
|
|
$headers .= $name . ': ' . implode(', ', $values) . "\r\n";
|
159
|
6 |
|
}
|
160
|
6 |
|
$this->command->comment($headers);
|
161
|
6 |
|
if($type=='REQUEST') {
|
162
|
6 |
|
$this->command->comment($message->getBody());
|
163
|
6 |
|
} else if($type=='RESPONSE') {
|
164
|
6 |
|
$this->command->comment($message->getBody()->getContents());
|
165
|
6 |
|
}
|
166
|
6 |
|
}
|
167
|
|
|
|
168
|
|
|
|
169
|
|
|
/**
|
170
|
|
|
* Get the color tag for the given status code.
|
171
|
|
|
*
|
172
|
|
|
* @param string $code
|
173
|
|
|
*
|
174
|
|
|
* @return string
|
175
|
|
|
*
|
176
|
|
|
* @see https://github.com/spatie/http-status-check/blob/master/src/CrawlLogger.php#L96
|
177
|
|
|
*/
|
178
|
6 |
|
protected function getColorTagForStatusCode($code)
|
179
|
|
|
{
|
180
|
6 |
|
if (starts_with($code, '2')) {
|
181
|
2 |
|
return 'info';
|
182
|
|
|
}
|
183
|
4 |
|
if (starts_with($code, '3')) {
|
184
|
|
|
return 'comment';
|
185
|
|
|
}
|
186
|
4 |
|
return 'error';
|
187
|
|
|
}
|
188
|
|
|
} |