steverobbins /
magescan
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Mage Scan |
||
| 4 | * |
||
| 5 | * PHP version 5 |
||
| 6 | * |
||
| 7 | * @category MageScan |
||
| 8 | * @package MageScan |
||
| 9 | * @author Steve Robbins <[email protected]> |
||
| 10 | * @copyright 2015 Steve Robbins |
||
| 11 | * @license http://creativecommons.org/licenses/by/4.0/ CC BY 4.0 |
||
| 12 | * @link https://github.com/steverobbins/magescan |
||
| 13 | */ |
||
| 14 | |||
| 15 | namespace MageScan; |
||
| 16 | |||
| 17 | use MageScan\Check\Catalog; |
||
| 18 | use MageScan\Check\Module; |
||
| 19 | use MageScan\Check\Patch; |
||
| 20 | use MageScan\Check\Sitemap; |
||
| 21 | use MageScan\Check\TechHeader; |
||
| 22 | use MageScan\Check\UnreachablePath; |
||
| 23 | use MageScan\Check\Version; |
||
| 24 | use MageScan\Request; |
||
| 25 | use MageScan\Url; |
||
| 26 | |||
| 27 | /** |
||
| 28 | * Scan a Magento site using a web browser |
||
| 29 | * |
||
| 30 | * @category MageScan |
||
| 31 | * @package MageScan |
||
| 32 | * @author Steve Robbins <[email protected]> |
||
| 33 | * @copyright 2015 Steve Robbins |
||
| 34 | * @license http://creativecommons.org/licenses/by/4.0/ CC BY 4.0 |
||
| 35 | * @link https://github.com/steverobbins/magescan |
||
| 36 | */ |
||
| 37 | class Http |
||
| 38 | { |
||
| 39 | /** |
||
| 40 | * The URL we are scanning |
||
| 41 | * |
||
| 42 | * @var string |
||
| 43 | */ |
||
| 44 | public $url; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * Request object |
||
| 48 | * |
||
| 49 | * @var \MageScan\Request |
||
| 50 | */ |
||
| 51 | protected $request; |
||
| 52 | |||
| 53 | /** |
||
| 54 | * Start a check |
||
| 55 | * |
||
| 56 | * @param string $code |
||
| 57 | * @param string $url |
||
| 58 | */ |
||
| 59 | public function __construct($code, $url) |
||
| 60 | { |
||
| 61 | $magescanUrl = new Url; |
||
| 62 | $this->url = $magescanUrl->clean(urldecode($url)); |
||
| 63 | $this->request = new Request($this->url, isset($_SERVER['ALLOW_INSECURE'])); |
||
| 64 | call_user_func([$this, 'check' . ucwords($code)]); |
||
| 65 | } |
||
| 66 | |||
| 67 | /** |
||
| 68 | * Check for Magento version |
||
| 69 | * |
||
| 70 | * @return void |
||
| 71 | */ |
||
| 72 | public function checkMagentoinfo() |
||
| 73 | { |
||
| 74 | $version = new Version; |
||
| 75 | $version->setRequest($this->request); |
||
| 76 | $version = $version->getInfo(); |
||
| 77 | $rows = [ |
||
| 78 | ['Edition', $version[0] ?: 'Unknown'], |
||
| 79 | ['Version', $version[1] ?: 'Unknown'] |
||
| 80 | ]; |
||
| 81 | $this->respond(['body' => $rows]); |
||
| 82 | } |
||
| 83 | |||
| 84 | /** |
||
| 85 | * Check for installed modules |
||
| 86 | * |
||
| 87 | * @return void |
||
| 88 | */ |
||
| 89 | public function checkModules() |
||
| 90 | { |
||
| 91 | $module = new Module; |
||
| 92 | $module->setRequest($this->request); |
||
| 93 | $this->respond(array_keys($module->getFiles())); |
||
| 94 | } |
||
| 95 | |||
| 96 | /** |
||
| 97 | * Check for an installed module |
||
| 98 | * |
||
| 99 | * @return void |
||
| 100 | */ |
||
| 101 | public function checkModulessingle() |
||
| 102 | { |
||
| 103 | $module = new Module; |
||
| 104 | $module->setRequest($this->request); |
||
| 105 | $file = $_GET['path']; |
||
| 106 | $files = $module->getFiles(); |
||
| 107 | $result = $module->checkForModule($_GET['path']); |
||
| 108 | if ($result) { |
||
| 109 | $this->respond([ |
||
| 110 | isset($files[$file]) ? $files[$file] : '<!-- how did this happen -->' |
||
| 111 | ]); |
||
| 112 | } |
||
| 113 | } |
||
| 114 | |||
| 115 | /** |
||
| 116 | * Check for install patches |
||
| 117 | * |
||
| 118 | * @return void |
||
| 119 | */ |
||
| 120 | public function checkPatch() |
||
| 121 | { |
||
| 122 | $patch = new Patch; |
||
| 123 | $patch->setRequest($this->request); |
||
| 124 | $patches = $patch->checkAll($this->url); |
||
| 125 | $rows = []; |
||
| 126 | View Code Duplication | foreach ($patches as $name => $result) { |
|
| 127 | switch ($result) { |
||
| 128 | case PATCH::PATCHED: |
||
| 129 | $status = '<span class="pass">Patched</span class="pass">'; |
||
| 130 | break; |
||
| 131 | case PATCH::UNPATCHED: |
||
| 132 | $status = '<span class="fail">Unpatched</span class="fail">'; |
||
| 133 | break; |
||
| 134 | default: |
||
| 135 | $status = 'Unknown'; |
||
| 136 | } |
||
| 137 | $rows[] = [ |
||
| 138 | $name, |
||
| 139 | $status |
||
| 140 | ]; |
||
| 141 | } |
||
| 142 | $this->respond([ |
||
| 143 | 'head' => ['Patch', 'Status'], |
||
| 144 | 'body' => $rows |
||
| 145 | ]); |
||
| 146 | } |
||
| 147 | |||
| 148 | /** |
||
| 149 | * Check for catalog information |
||
| 150 | * |
||
| 151 | * @return void |
||
| 152 | */ |
||
| 153 | public function checkCatalog() |
||
| 154 | { |
||
| 155 | $rows = []; |
||
| 156 | $catalog = new Catalog; |
||
| 157 | $catalog->setRequest($this->request); |
||
| 158 | $categoryCount = $catalog->categoryCount(); |
||
| 159 | $rows[] = [ |
||
| 160 | '<a href="' . $this->url. 'catalog/seo_sitemap/category" target="_blank">Categories</a>', |
||
| 161 | $categoryCount !== false ? $categoryCount : 'Unknown' |
||
| 162 | ]; |
||
| 163 | $productCount = $catalog->productCount(); |
||
| 164 | $rows[] = [ |
||
| 165 | '<a href="' . $this->url . 'catalog/seo_sitemap/product" target="_blank">Products</a>', |
||
| 166 | $productCount !== false ? $productCount : 'Unknown' |
||
| 167 | ]; |
||
| 168 | $this->respond(['body' => $rows]); |
||
| 169 | } |
||
| 170 | |||
| 171 | /** |
||
| 172 | * Check for a valid sitemap |
||
| 173 | * |
||
| 174 | * @return void |
||
| 175 | */ |
||
| 176 | public function checkSitemap() |
||
| 177 | { |
||
| 178 | $rows = []; |
||
| 179 | $response = $this->request->get('robots.txt'); |
||
|
0 ignored issues
–
show
|
|||
| 180 | $sitemap = new Sitemap; |
||
| 181 | $sitemap->setRequest($this->request); |
||
| 182 | $sitemapUrl = $sitemap->getSitemapFromRobotsTxt($response); |
||
| 183 | if ($sitemapUrl === false) { |
||
| 184 | $rows[] = ['<span class="fail">Sitemap is not declared in <a href="' . $this->url |
||
| 185 | . 'robots.txt" target="_blank">robots.txt</a></span>']; |
||
| 186 | $sitemapUrl = $this->url . 'sitemap.xml'; |
||
| 187 | } else { |
||
| 188 | $rows[] = ['<span class="pass">Sitemap is declared in <a href="' . $this->url |
||
| 189 | . 'robots.txt" target="_blank">robots.txt</a></span></span>']; |
||
| 190 | } |
||
| 191 | $response = $this->request->get($sitemapUrl); |
||
|
0 ignored issues
–
show
The call to
Request::get() has too many arguments starting with $sitemapUrl.
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the Loading history...
|
|||
| 192 | if ($response->code == 200) { |
||
|
0 ignored issues
–
show
The property
code does not seem to exist in GuzzleHttp\Psr7\Response.
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. Loading history...
|
|||
| 193 | $rows[] = ['<span class="pass"><a href="' . $sitemapUrl |
||
| 194 | . '" target="_blank">Sitemap</a> is accessible</span>']; |
||
| 195 | } else { |
||
| 196 | $rows[] = ['<span class="fail"><a href="' . $sitemapUrl |
||
| 197 | . '" target="_blank">Sitemap</a> is not accessible</span>']; |
||
| 198 | } |
||
| 199 | $this->respond(['body' => $rows]); |
||
| 200 | } |
||
| 201 | |||
| 202 | /** |
||
| 203 | * Check for server technologies |
||
| 204 | * |
||
| 205 | * @return void |
||
| 206 | */ |
||
| 207 | public function checkServertech() |
||
| 208 | { |
||
| 209 | $rows = []; |
||
| 210 | $techHeader = new TechHeader; |
||
| 211 | $techHeader->setRequest($this->request); |
||
| 212 | $values = $techHeader->getHeaders(); |
||
| 213 | if (empty($values)) { |
||
| 214 | $rows[] = ['No detectable technology was found']; |
||
| 215 | } |
||
| 216 | foreach ($values as $key => $value) { |
||
| 217 | $rows[] = [$key, $value]; |
||
| 218 | } |
||
| 219 | $this->respond(['body' => $rows]); |
||
| 220 | } |
||
| 221 | |||
| 222 | /** |
||
| 223 | * Check for unreachable paths |
||
| 224 | * |
||
| 225 | * @return void |
||
| 226 | */ |
||
| 227 | public function checkUnreachablepath() |
||
| 228 | { |
||
| 229 | $unreachablePath = new UnreachablePath; |
||
| 230 | $unreachablePath->setRequest($this->request); |
||
| 231 | $this->respond($unreachablePath->getPaths()); |
||
| 232 | } |
||
| 233 | |||
| 234 | /** |
||
| 235 | * Check for unreachable paths |
||
| 236 | * |
||
| 237 | * @return void |
||
| 238 | */ |
||
| 239 | public function checkUnreachablepathsingle() |
||
| 240 | { |
||
| 241 | $unreachablePath = new UnreachablePath; |
||
| 242 | $unreachablePath->setRequest($this->request); |
||
| 243 | $result = $unreachablePath->checkPath($_GET['path']); |
||
| 244 | if ($result[2] === true) { |
||
| 245 | return; |
||
| 246 | } |
||
| 247 | if ($result[2] === false) { |
||
| 248 | $result[0] = '<a target="_blank" href="' . $this->url . $result[0] . '">' . $result[0] . '</a>'; |
||
| 249 | $result[2] = '<span class="fail">Reachable</span>'; |
||
| 250 | } elseif (substr($result[1], 0, 1) == 3) { |
||
| 251 | if (substr($result[2], 0, 4) == 'http') { |
||
| 252 | $newUrl = $result[2]; |
||
| 253 | } else { |
||
| 254 | $newUrl = $this->url . substr($result[2], 1); |
||
| 255 | } |
||
| 256 | $result[0] = '<a target="_blank" href="' . $newUrl . '">' . $result[0] . '</a>'; |
||
| 257 | $result[2] = '<a target="_blank" href="' . $newUrl . '">Redirect</a>'; |
||
| 258 | } |
||
| 259 | $this->respond($result); |
||
| 260 | } |
||
| 261 | |||
| 262 | /** |
||
| 263 | * Send JSON response |
||
| 264 | * |
||
| 265 | * @param array $data |
||
| 266 | * |
||
| 267 | * @return void |
||
| 268 | */ |
||
| 269 | public function respond(array $data) |
||
| 270 | { |
||
| 271 | echo json_encode($data); |
||
| 272 | } |
||
| 273 | } |
||
| 274 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.