Skip to content

Commit 1496813

Browse files
committed
update version, removed unrelated methods from ezQuery class to global functions only
- added/tested two additional security related functions, `is_traversal` and `sanitize_path` to go along with `clean_string`
1 parent a20e2b5 commit 1496813

File tree

7 files changed

+138
-127
lines changed

7 files changed

+138
-127
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ use function ezsql\functions\{
288288
///
289289
to_string,
290290
clean_string,
291+
is_traversal,
292+
sanitize_path,
291293
create_certificate,
292294
///
293295
column,

lib/Constants.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/**
66
* ezsqlModel Constants
77
*/
8-
\defined('EZSQL_VERSION') or \define('EZSQL_VERSION', '5.1.0');
8+
\defined('EZSQL_VERSION') or \define('EZSQL_VERSION', '5.1.1');
99
\defined('OBJECT') or \define('OBJECT', 'OBJECT');
1010
\defined('ARRAY_A') or \define('ARRAY_A', 'ARRAY_A');
1111
\defined('ARRAY_N') or \define('ARRAY_N', 'ARRAY_N');

lib/ezFunctions.php

Lines changed: 113 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -215,40 +215,6 @@ function changingColumn(string $columnName, ...$datatype)
215215
return column(\CHANGER, $columnName, ...$datatype);
216216
}
217217

218-
/**
219-
* Creates self signed certificate
220-
*
221-
* @param string $privatekeyFile
222-
* @param string $certificateFile
223-
* @param string $signingFile
224-
* // param string $caCertificate
225-
* @param string $ssl_path
226-
* @param array $details - certificate details
227-
*
228-
* Example:
229-
* array $details = [
230-
* "countryName" => '',
231-
* "stateOrProvinceName" => '',
232-
* "localityName" => '',
233-
* "organizationName" => '',
234-
* "organizationalUnitName" => '',
235-
* "commonName" => '',
236-
* "emailAddress" => ''
237-
* ];
238-
*
239-
* @return string certificate path
240-
*/
241-
function create_certificate(
242-
string $privatekeyFile = 'certificate.key',
243-
string $certificateFile = 'certificate.crt',
244-
string $signingFile = 'certificate.csr',
245-
// string $caCertificate = null,
246-
string $ssl_path = null,
247-
array $details = ["commonName" => "localhost"]
248-
) {
249-
return ezQuery::createCertificate($privatekeyFile, $certificateFile, $signingFile, $ssl_path, $details);
250-
}
251-
252218
/**
253219
* Creates an equality comparison expression with the given arguments.
254220
*
@@ -600,7 +566,119 @@ function clearInstance()
600566
*/
601567
function clean_string(string $string)
602568
{
603-
return ezQuery::clean($string);
569+
$patterns = array( // strip out:
570+
'@<script[^>]*?>.*?</script>@si', // Strip out javascript
571+
'@<[\/\!]*?[^<>]*?>@si', // HTML tags
572+
'@<style[^>]*?>.*?</style>@siU', // Strip style tags properly
573+
'@<![\s\S]*?--[ \t\n\r]*>@' // Strip multi-line comments
574+
);
575+
576+
$string = \preg_replace($patterns, '', $string);
577+
$string = \trim($string);
578+
$string = \stripslashes($string);
579+
580+
return \htmlentities($string);
581+
}
582+
583+
/**
584+
* Check if path/filename is directory traversal attack.
585+
*
586+
* @param string $basePath base directory to check against
587+
* @param string $filename will be preprocess with `sanitize_path()`
588+
* @return boolean
589+
*/
590+
function is_traversal(string $basePath, string $filename)
591+
{
592+
if (\strpos(\urldecode($filename), '..') !== false)
593+
return true;
594+
595+
$realBase = \rtrim(\realpath($basePath), _DS);
596+
$userPath = $realBase . _DS . sanitize_path($filename);
597+
$realUserPath = \realpath($userPath);
598+
// Reassign with un-sanitized if file does not exits
599+
if ($realUserPath === false)
600+
$realUserPath = $filename;
601+
602+
return (\strpos($realUserPath, $realBase) !== 0);
603+
}
604+
605+
/**
606+
* Sanitize path to prevent directory traversal.
607+
*
608+
* Example:
609+
*
610+
* `sanitize_path("../../../../config.php");`
611+
*
612+
* Returns `config.php` without the path traversal
613+
* @param string $path
614+
* @return string
615+
*/
616+
function sanitize_path(string $path)
617+
{
618+
$file = \preg_replace("/\.[\.]+/", "", $path);
619+
$file = \preg_replace("/^[\/]+/", "", $file);
620+
$file = \preg_replace("/^[A-Za-z][:\|][\/]?/", "", $file);
621+
return ($file);
622+
}
623+
624+
/**
625+
* Creates self signed certificate
626+
*
627+
* @param string $privatekeyFile
628+
* @param string $certificateFile
629+
* @param string $signingFile
630+
* // param string $caCertificate
631+
* @param string $ssl_path
632+
* @param array $details - certificate details
633+
*
634+
* Example:
635+
* array $details = [
636+
* "countryName" => '',
637+
* "stateOrProvinceName" => '',
638+
* "localityName" => '',
639+
* "organizationName" => '',
640+
* "organizationalUnitName" => '',
641+
* "commonName" => '',
642+
* "emailAddress" => ''
643+
* ];
644+
*
645+
* @return string certificate path
646+
*/
647+
function create_certificate(
648+
string $privatekeyFile = 'certificate.key',
649+
string $certificateFile = 'certificate.crt',
650+
string $signingFile = 'certificate.csr',
651+
// string $caCertificate = null,
652+
string $ssl_path = null,
653+
array $details = ["commonName" => "localhost"]
654+
) {
655+
if (empty($ssl_path)) {
656+
$ssl_path = \getcwd();
657+
$ssl_path = \preg_replace('/\\\/', \_DS, $ssl_path) . \_DS;
658+
} else
659+
$ssl_path = $ssl_path . \_DS;
660+
661+
$opensslConfig = array("config" => $ssl_path . 'openssl.cnf');
662+
663+
// Generate a new private (and public) key pair
664+
$privatekey = \openssl_pkey_new($opensslConfig);
665+
666+
// Generate a certificate signing request
667+
$csr = \openssl_csr_new($details, $privatekey, $opensslConfig);
668+
669+
// Create a self-signed certificate valid for 365 days
670+
$sslcert = \openssl_csr_sign($csr, null, $privatekey, 365, $opensslConfig);
671+
672+
// Create key file. Note no passphrase
673+
\openssl_pkey_export_to_file($privatekey, $ssl_path . $privatekeyFile, null, $opensslConfig);
674+
675+
// Create server certificate
676+
\openssl_x509_export_to_file($sslcert, $ssl_path . $certificateFile, false);
677+
678+
// Create a signing request file
679+
\openssl_csr_export_to_file($csr, $ssl_path . $signingFile);
680+
681+
return $ssl_path;
604682
}
605683

606684
/**

lib/ezQuery.php

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -44,82 +44,6 @@ public function __construct()
4444
{
4545
}
4646

47-
public static function clean($string)
48-
{
49-
$patterns = array( // strip out:
50-
'@<script[^>]*?>.*?</script>@si', // Strip out javascript
51-
'@<[\/\!]*?[^<>]*?>@si', // HTML tags
52-
'@<style[^>]*?>.*?</style>@siU', // Strip style tags properly
53-
'@<![\s\S]*?--[ \t\n\r]*>@' // Strip multi-line comments
54-
);
55-
56-
$string = \preg_replace($patterns, '', $string);
57-
$string = \trim($string);
58-
$string = \stripslashes($string);
59-
60-
return \htmlentities($string);
61-
}
62-
63-
/**
64-
* Creates self signed certificate
65-
*
66-
* @param string $privatekeyFile
67-
* @param string $certificateFile
68-
* @param string $signingFile
69-
* // param string $caCertificate
70-
* @param string $ssl_path
71-
* @param array $details - certificate details
72-
*
73-
* Example:
74-
* array $details = [
75-
* "countryName" => '',
76-
* "stateOrProvinceName" => '',
77-
* "localityName" => '',
78-
* "organizationName" => '',
79-
* "organizationalUnitName" => '',
80-
* "commonName" => '',
81-
* "emailAddress" => ''
82-
* ];
83-
*
84-
* @return string certificate path
85-
*/
86-
public static function createCertificate(
87-
string $privatekeyFile = 'certificate.key',
88-
string $certificateFile = 'certificate.crt',
89-
string $signingFile = 'certificate.csr',
90-
// string $caCertificate = null,
91-
string $ssl_path = null,
92-
array $details = ["commonName" => "localhost"]
93-
) {
94-
if (empty($ssl_path)) {
95-
$ssl_path = \getcwd();
96-
$ssl_path = \preg_replace('/\\\/', \_DS, $ssl_path) . \_DS;
97-
} else
98-
$ssl_path = $ssl_path . \_DS;
99-
100-
$opensslConfig = array("config" => $ssl_path . 'openssl.cnf');
101-
102-
// Generate a new private (and public) key pair
103-
$privatekey = \openssl_pkey_new($opensslConfig);
104-
105-
// Generate a certificate signing request
106-
$csr = \openssl_csr_new($details, $privatekey, $opensslConfig);
107-
108-
// Create a self-signed certificate valid for 365 days
109-
$sslcert = \openssl_csr_sign($csr, null, $privatekey, 365, $opensslConfig);
110-
111-
// Create key file. Note no passphrase
112-
\openssl_pkey_export_to_file($privatekey, $ssl_path . $privatekeyFile, null, $opensslConfig);
113-
114-
// Create server certificate
115-
\openssl_x509_export_to_file($sslcert, $ssl_path . $certificateFile, false);
116-
117-
// Create a signing request file
118-
\openssl_csr_export_to_file($csr, $ssl_path . $signingFile);
119-
120-
return $ssl_path;
121-
}
122-
12347
/**
12448
* Return status of prepare function availability in shortcut method calls
12549
*/

lib/ezQueryInterface.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,6 @@
2929
*/
3030
interface ezQueryInterface
3131
{
32-
/**
33-
* Clean input of XSS, html, javascript, etc...
34-
* @param string $string
35-
* @return string cleaned string
36-
*/
37-
public static function clean($string);
38-
3932
/**
4033
* Turn on prepare function availability in ezQuery shortcut method calls
4134
*/

tests/ezFunctionsTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@
5050
get_results,
5151
table_setup,
5252
set_table,
53-
set_prefix
53+
set_prefix,
54+
clean_string,
55+
is_traversal,
56+
sanitize_path
5457
};
5558

5659
class ezFunctionsTest extends EZTestCase
@@ -60,6 +63,23 @@ protected function setUp(): void
6063
clearInstance();
6164
}
6265

66+
public function testClean_string()
67+
{
68+
$this->assertEquals("' help", clean_string("<?php echo 'foo' >' help</php?>"));
69+
}
70+
71+
public function testSanitize_path()
72+
{
73+
$this->assertEquals("config.php", sanitize_path("../../../../config.php"));
74+
}
75+
76+
public function testis_traversal()
77+
{
78+
$this->assertEquals(true, is_traversal('/home', "../../../../config.php"));
79+
$this->assertEquals(true, is_traversal(__DIR__, dirname(__DIR__), 8));
80+
$this->assertEquals(false, is_traversal(__DIR__, 'Foo.php'));
81+
}
82+
6383
public function testGetInstance()
6484
{
6585
$this->assertNull(getInstance());

tests/ezQueryTest.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
eq,
1010
neq,
1111
like,
12-
in,
13-
clean_string
12+
in
1413
};
1514

1615
class ezQueryTest extends EZTestCase
@@ -27,11 +26,6 @@ protected function tearDown(): void
2726
$this->object = null;
2827
}
2928

30-
public function testClean_string()
31-
{
32-
$this->assertEquals("' help", clean_string("<?php echo 'foo' >' help</php?>"));
33-
}
34-
3529
public function testHaving()
3630
{
3731
$this->assertFalse($this->object->having(''));

0 commit comments

Comments
 (0)