Created Useful Functions for Plugin/Theme Security (markdown)

Erwan
2021-05-20 11:07:29 +02:00
parent 54fb6f0591
commit a95ed3b86b

@@ -0,0 +1,63 @@
The snippets below are a collection of PHP functions to help WordPress Plugin/Theme developer secure their code.
## is_url_local()
When using an arbitrary URL in functions such as `wp_remote_get`, `curl` etc (which is not really recommended but sometimes there is no other way), in addition to ensure that the URL is indeed an URL, it should be also be checked to make sure the URL is not a local one, to avoid issues such as SSRF (https://portswigger.net/web-security/ssrf, https://en.wikipedia.org/wiki/Server-side_request_forgery)
```php
<?php
function is_url_local($url) {
$host = parse_url($url, PHP_URL_HOST);
// Case of an url passed w/o protocol
if ($host === NULL)
$host = $url;
$ip = gethostbyname($host);
return ! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
}
$urls = [
'doesntexistblabla.com', 'https://wpscan.com', 'wpscan.com', '192.168.1.32', '127.0.0.1:9090', 'https://youtube.com:23', 'localhost',
'http://127.0.0.1', '127.1', 'https://0x7f.0x0.0x0.0x1', '0177.0.0.01', '2130706433', 'https://%6c%6f%63%61%6c%68%6f%73%74', 'http://0177.0.0.0x1:9090/aa.txt', '::1', 'https://[::1]:8080', 'http://[::ffff:127.0.0.1]:19983/'
];
foreach ($urls as $url) {
if (is_url_local($url))
$type = 'local';
else
$type = 'remote';
echo "{$url} => {$type}\n";
}
```
## zip_only_contains_allowed_extensions()
Before extracting a zip file uploaded by any user (including admin), its content should be checked to ensure that the archive only contains expected files (such as png) and no other ones (such as php etc) which could lead to severe security issues.
```php
<?php
function zip_only_contains_allowed_extensions($zip_path, array $allowed_extensions) {
$zip = new ZipArchive;
$zip->open($zip_path);
for ($i = 0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex( $i );
$ext = pathinfo($stat['name'], PATHINFO_EXTENSION);
//print_r( "{$stat['name']} => {$ext}" . PHP_EOL );
if (!in_array(strtolower($ext), $allowed_extensions))
return false;
}
return true;
}
var_dump(zip_only_contains_allowed_extensions('midex.zip', ['png']));
```