Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions PhpSecInfo/PhpSecInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ function PhpSecInfo($opts = null) {
if (isset($opts['format'])) {
$this->setFormat($opts['format']);
} else {
if (strtolower(php_sapi_name()) == 'cli' ) {
if (!strcasecmp(PHP_SAPI, 'cli')) {
$this->setFormat('Cli');
} else {
$this->setFormat(PHPSECINFO_FORMAT_DEFAULT);
Expand All @@ -207,7 +207,7 @@ function PhpSecInfo($opts = null) {

} else { /* Use defaults */
$this->setViewDirectory(dirname(__FILE__).DIRECTORY_SEPARATOR . PHPSECINFO_VIEW_DIR_DEFAULT);
if (strtolower(php_sapi_name()) == 'cli' ) {
if (!strcasecmp(PHP_SAPI, 'cli')) {
$this->setFormat('Cli');
} else {
$this->setFormat(PHPSECINFO_FORMAT_DEFAULT);
Expand All @@ -228,7 +228,7 @@ function loadTests() {
//echo "<pre>"; echo print_r($test_root, true); echo "</pre>";

while (false !== ($entry = $test_root->read())) {
if ( is_dir($test_root->path.DIRECTORY_SEPARATOR.$entry) && !preg_match('|^\.(.*)$|', $entry) ) {
if ( is_dir($test_root->path.DIRECTORY_SEPARATOR.$entry) && !preg_match('~^(\.|_vti)(.*)$~', $entry) ) {
$test_dirs[] = $entry;
}
}
Expand Down
40 changes: 35 additions & 5 deletions PhpSecInfo/Test/CGI/force_redirect.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,41 @@ function _retrieveCurrentValue() {
}



private function skipTest() {
if (strpos(PHP_SAPI, 'cgi') === false) {
return PHP_SAPI . ' SAPI for php';
}

// these web servers require cgi.force_redirect = 0
$webServers = array('Microsoft-IIS', 'OmniHTTPd', 'Xitami');
if (isset($_SERVER['SERVER_SOFTWARE'])) {
foreach ($webServers as $webServer) {
if (strpos($_SERVER['SERVER_SOFTWARE'], $webServer) === 0) {
return $_SERVER['SERVER_SOFTWARE'];
}
}
}

return false;
}



/**
* Checks to see if cgi.force_redirect is enabled
*
*/
function _execTest() {

if ($this->current_value == $this->recommended_value) {
return PHPSECINFO_TEST_RESULT_OK;
}

if ($this->skipTest())
{
return PHPSECINFO_TEST_RESULT_NOTICE;
}

return PHPSECINFO_TEST_RESULT_WARN;
}

Expand All @@ -64,8 +89,13 @@ function _setMessages() {
parent::_setMessages();

$this->setMessageForResult(PHPSECINFO_TEST_RESULT_OK, 'en', "force_redirect is enabled, which is the recommended setting");
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_WARN, 'en', "force_redirect is disabled. In most cases, this is a <strong>serious</strong> security vulnerability. Unless you are absolutely sure this is not needed, enable this setting");

$ini = ini_get_all();
if (isset($ini['cgi.force_redirect'])) {
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_NOTICE, 'en', "force_redirect is disabled. In most cases, this is a security vulnerability, but it appears this is not needed because you are running " . $this->skipTest());
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_WARN, 'en', "force_redirect is disabled. In most cases, this is a <strong>serious</strong> security vulnerability. Unless you are absolutely sure this is not needed, enable this setting");
} else {
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_NOTICE, 'en', "force_redirect is disabled because php was not compiled with --enable-force-cgi-redirect. In most cases, this is a security vulnerability, but it appears this is not needed because you are running " . $this->skipTest());
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_WARN, 'en', "force_redirect is disabled because php was not compiled with --enable-force-cgi-redirect. In most cases, this is a <strong>serious</strong> security vulnerability. Unless you are absolutely sure this is not needed, recompile php with --enable-force-cgi-redirect and enable cgi.force_redirect");
}
}

}
}
7 changes: 1 addition & 6 deletions PhpSecInfo/Test/Core/allow_url_include.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,7 @@ function _execTest() {
* @return boolean
*/
function isTestable() {

if ( version_compare(PHP_VERSION, '5.2', '<') ) {
return false;
} else {
return true;
}
return version_compare(PHP_VERSION, '5.2', '>=');
}


Expand Down
9 changes: 5 additions & 4 deletions PhpSecInfo/Test/Core/upload_tmp_dir.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ function isTestable() {
*/
function _execTest() {

$perms = fileperms($this->current_value);

if ($this->current_value
$perms = @fileperms($this->current_value);
if ($perms === false) {
return PHPSECINFO_TEST_RESULT_WARN;
} else if ($this->current_value
&& !preg_match("|".PHPSECINFO_TEST_COMMON_TMPDIR."/?|", $this->current_value)
&& ! ($perms & 0x0004)
&& ! ($perms & 0x0002) ) {
Expand All @@ -79,7 +80,6 @@ function _execTest() {
return PHPSECINFO_TEST_RESULT_NOTICE;
}


/**
* Set the messages specific to this test
*
Expand All @@ -90,6 +90,7 @@ function _setMessages() {
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_NOTRUN, 'en', 'Test not run -- currently disabled on Windows OSes');
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_OK, 'en', 'upload_tmp_dir is enabled, which is the
recommended setting. Make sure your upload_tmp_dir path is not world-readable');
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_WARN, 'en', 'unable to retrieve file permissions on upload_tmp_dir');
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_NOTICE, 'en', 'upload_tmp_dir is disabled, or is set to a
common world-writable directory. This typically allows other users on this server
to access temporary copies of files uploaded via your PHP scripts. You should set
Expand Down
11 changes: 8 additions & 3 deletions PhpSecInfo/Test/Session/save_path.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ function _retrieveCurrentValue() {
}
}

if( preg_match('/^[0-9]+;(.+)/', $this->current_value, $matches) ) {
$this->current_value = $matches[1];
}
}


Expand Down Expand Up @@ -67,9 +70,10 @@ function isTestable() {
*/
function _execTest() {

$perms = fileperms($this->current_value);

if ($this->current_value
$perms = @fileperms($this->current_value);
if ($perms === false) {
return PHPSECINFO_TEST_RESULT_WARN;
} else if ($this->current_value
&& !preg_match("|".PHPSECINFO_TEST_COMMON_TMPDIR."/?|", $this->current_value)
&& ! ($perms & 0x0004)
&& ! ($perms & 0x0002) ) {
Expand All @@ -92,6 +96,7 @@ function _setMessages() {
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_NOTRUN, 'en', 'Test not run -- currently disabled on Windows OSes');
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_OK, 'en', 'save_path is enabled, which is the
recommended setting. Make sure your save_path path is not world-readable');
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_WARN, 'en', 'unable to retrieve file permissions on save_path');
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_NOTICE, 'en', 'save_path is disabled, or is set to a
common world-writable directory. This typically allows other users on this server
to access session files. You should set save_path to a non-world-readable directory');
Expand Down
46 changes: 46 additions & 0 deletions PhpSecInfo/Test/Suhosin/extension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/**
* Test class for Suhosin extension
*
* @package PhpSecInfo
* @author Piwik
*/

/**
* require the PhpSecInfo_Test_Suhosin class
*/
require_once(PHPSECINFO_BASE_DIR.'/Test/Test_Suhosin.php');

/**
* Test class for Suhosin extension
*
* Checks for suhosin extension
*
* @package PhpSecInfo
* @author Piwik
*/
class PhpSecInfo_Test_Suhosin_Extension extends PhpSecInfo_Test_Suhosin
{
var $test_name = "Suhosin extension";

var $recommended_value = true;

function _retrieveCurrentValue() {
$this->current_value = extension_loaded('suhosin');
}

function _execTest() {
if ( $this->current_value === true ) {
return PHPSECINFO_TEST_RESULT_OK;
} else {
return PHPSECINFO_TEST_RESULT_NOTICE;
}
}

function _setMessages() {
parent::_setMessages();

$this->setMessageForResult(PHPSECINFO_TEST_RESULT_OK, 'en', "You are running PHP with the Suhosin extension loaded. This extension provides high-level runtime protections, and additional filtering and logging features.");
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_NOTICE, 'en', "You are not running PHP with the Suhosin extension loaded. We recommend both the patch and extension for low- and high-level protections including transparent cookie encryption and remote inclusion vulnerabilities.");
}
}
55 changes: 55 additions & 0 deletions PhpSecInfo/Test/Suhosin/patch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
/**
* Test class for Suhosin patch
*
* @package PhpSecInfo
* @author Piwik
*/

/**
* require the PhpSecInfo_Test_Suhosin class
*/
require_once(PHPSECINFO_BASE_DIR.'/Test/Test_Suhosin.php');

/**
* Test class for Suhosin
*
* Checks for Suhosin patch which implements low-level protections against bufferoverflows or format string vulnerabilities
*
* @package PhpSecInfo
* @author Piwik
*/
class PhpSecInfo_Test_Suhosin_Patch extends PhpSecInfo_Test_Suhosin
{
var $test_name = "Suhosin patch";

var $recommended_value = true;

function _retrieveCurrentValue() {
if (preg_match('/Suhosin/', $_SERVER['SERVER_SOFTWARE'])) {
$this->current_value = true;
} else {
$this->current_value = false;

$constants = get_defined_constants();
if(isset($constants['SUHOSIN_PATCH']) && $constants['SUHOSIN_PATCH'] == 1) {
$this->current_value = true;
}
}
}

function _execTest() {
if ( $this->current_value === true ) {
return PHPSECINFO_TEST_RESULT_OK;
} else {
return PHPSECINFO_TEST_RESULT_NOTICE;
}
}

function _setMessages() {
parent::_setMessages();

$this->setMessageForResult(PHPSECINFO_TEST_RESULT_OK, 'en', "You are running PHP with the Suhosin patch applied against the PHP core. This patch implements various low-level protections against (for example) buffer overflows and format string vulnerabilities.");
$this->setMessageForResult(PHPSECINFO_TEST_RESULT_NOTICE, 'en', "You are not running PHP with the Suhosin patch applied. We recommend both the patch and extension for low- and high-level protections against (for example) buffer overflows and format string vulnerabilities.");
}
}
26 changes: 15 additions & 11 deletions PhpSecInfo/Test/Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -463,15 +463,14 @@ function getBooleanIniValue($ini_key) {
*/
function sys_get_temp_dir() {
// Try to get from environment variable
if ( !empty($_ENV['TMP']) ) {
return realpath( $_ENV['TMP'] );
} else if ( !empty($_ENV['TMPDIR']) ) {
return realpath( $_ENV['TMPDIR'] );
} else if ( !empty($_ENV['TEMP']) ) {
return realpath( $_ENV['TEMP'] );
} else {
return NULL;
$vars = array('TMP', 'TMPDIR', 'TEMP');
foreach($vars as $var) {
$tmp = getenv($var);
if ( !empty($tmp) ) {
return realpath( $tmp );
}
}
return NULL;
}


Expand Down Expand Up @@ -530,16 +529,20 @@ function getUnixId() {
'gid'=>$matches[3],
'group'=>$matches[4] );

$groups = array();
if ($matches[5]) {
$gs = $matches[5];
$gs = explode(',', $gs);
foreach ($gs as $groupstr) {
preg_match("/(\d+)\(([^\)]+)\)/", $groupstr, $subs);
$groups[$subs[1]] = $subs[2];
if (preg_match("/(\d+)\(([^\)]+)\)/", $groupstr, $subs)) {
$groups[$subs[1]] = $subs[2];
} else {
$groups[$groupstr] = '';
}
}
ksort($groups);
$id_data['groups'] = $groups;
}
$id_data['groups'] = $groups;
$success = true;
}

Expand All @@ -553,6 +556,7 @@ function getUnixId() {
$id_data['gid'] = $data['gid'];
//$group_data = posix_getgrgid( posix_getegid() );
//$id_data['group'] = $group_data['name'];
$id_data['groups'] = array();
$groups = posix_getgroups();
foreach ( $groups as $gid ) {
//$group_data = posix_getgrgid(posix_getgid());
Expand Down
4 changes: 2 additions & 2 deletions PhpSecInfo/Test/Test_Cgi.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ class PhpSecInfo_Test_Cgi extends PhpSecInfo_Test
* @return boolean
*/
function isTestable() {
/*if ( preg_match('/^cgi.*$/', php_sapi_name()) ) {
/*if ( preg_match('/^cgi.*$/', PHP_SAPI) ) {
return true;
} else {
return false;
}*/
return strpos(php_sapi_name(), 'cgi') === 0;
return !strncmp(PHP_SAPI, 'cgi', 3);
}


Expand Down
50 changes: 50 additions & 0 deletions PhpSecInfo/Test/Test_Suhosin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
/**
* Skeleton Test class file for Suhosin group
*
* @package PhpSecInfo
* @author Anthon Pang
*/

/**
* require the main PhpSecInfo class
*/
require_once(PHPSECINFO_BASE_DIR.'/Test/Test.php');



/**
* This is a skeleton class for PhpSecInfo "Suhosin" tests
* @package PhpSecInfo
*/
class PhpSecInfo_Test_Suhosin extends PhpSecInfo_Test
{

/**
* This value is used to group test results together.
*
* For example, all tests related to the mysql lib should be grouped under "mysql."
*
* @var string
*/
var $test_group = 'Suhosin';


/**
* "Suhosin" tests should pretty much be always testable, so the default is just to return true
*
* @return boolean
*/
function isTestable() {

return true;
}

function getMoreInfoURL() {
if ($tn = $this->getTestName()) {
return 'http://www.hardened-php.net/suhosin/index.html';
} else {
return false;
}
}
}