GEANT /
CAT
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
| 1 | <?php |
||
| 2 | |||
| 3 | /* |
||
| 4 | * ***************************************************************************** |
||
| 5 | * Contributions to this work were made on behalf of the GÉANT project, a |
||
| 6 | * project that has received funding from the European Union’s Framework |
||
| 7 | * Programme 7 under Grant Agreements No. 238875 (GN3) and No. 605243 (GN3plus), |
||
| 8 | * Horizon 2020 research and innovation programme under Grant Agreements No. |
||
| 9 | * 691567 (GN4-1) and No. 731122 (GN4-2). |
||
| 10 | * On behalf of the aforementioned projects, GEANT Association is the sole owner |
||
| 11 | * of the copyright in all material which was developed by a member of the GÉANT |
||
| 12 | * project. GÉANT Vereniging (Association) is registered with the Chamber of |
||
| 13 | * Commerce in Amsterdam with registration number 40535155 and operates in the |
||
| 14 | * UK as a branch of GÉANT Vereniging. |
||
| 15 | * |
||
| 16 | * Registered office: Hoekenrode 3, 1102BR Amsterdam, The Netherlands. |
||
| 17 | * UK branch address: City House, 126-130 Hills Road, Cambridge CB2 1PQ, UK |
||
| 18 | * |
||
| 19 | * License: see the web/copyright.inc.php file in the file structure or |
||
| 20 | * <base_url>/copyright.php after deploying the software |
||
| 21 | */ |
||
| 22 | |||
| 23 | namespace core\common; |
||
| 24 | |||
| 25 | use \Exception; |
||
|
0 ignored issues
–
show
|
|||
| 26 | |||
| 27 | class Logging |
||
| 28 | { |
||
| 29 | |||
| 30 | /** |
||
| 31 | * We don't have a lot to do here, but at least make sure that the logdir |
||
| 32 | * is specified and exists. |
||
| 33 | * |
||
| 34 | * @throws Exception |
||
| 35 | */ |
||
| 36 | public function __construct() |
||
| 37 | { |
||
| 38 | if (!isset(\config\Master::PATHS['logdir'])) { |
||
| 39 | throw new Exception("No logdir was specified in the configuration. We cannot continue without one!"); |
||
| 40 | } |
||
| 41 | } |
||
| 42 | |||
| 43 | /** |
||
| 44 | * writes a message to file |
||
| 45 | * |
||
| 46 | * @param string $filename the name of the log file, relative (path to logdir gets prepended) |
||
| 47 | * @param string $message what to write into the file |
||
| 48 | * @return void |
||
| 49 | */ |
||
| 50 | private function writeToFile($filename, $message) |
||
| 51 | { |
||
| 52 | file_put_contents(\config\Master::PATHS['logdir'] . "/$filename", sprintf("%-015s", microtime(TRUE)) . $message, FILE_APPEND); |
||
|
0 ignored issues
–
show
config\Master::PATHS['logdir'] . '/'.$filename can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.
General Strategies to prevent injectionIn general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:
if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
throw new \InvalidArgumentException('This input is not allowed.');
}
For numeric data, we recommend to explicitly cast the data: $sanitized = (integer) $tainted;
Loading history...
sprintf('%-015s', microtime(TRUE)) . $message can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.
3 paths for user data to reach this point
1. Path:
Read tainted data from array, and Data is passed through
strip_tags(), and Data is passed through htmlspecialchars(), and htmlspecialchars(strip_tags($_SERVER['HTTP_USER_AGENT']), core\ENT_QUOTES) is assigned to $browser
in core/UserAPI.php on line 525
2. Path:
Read from
$_GET, and Data is passed through strip_tags(), and Data is passed through htmlspecialchars(), and htmlspecialchars(strip_tags($_GET['device'])) is assigned to $devId
in core/UserAPI.php on line 571
3. Path:
Read from
$_POST, and Data is passed through strip_tags(), and Data is passed through htmlspecialchars(), and htmlspecialchars(strip_tags($_POST['device'])) is assigned to $devId
in core/UserAPI.php on line 573
General Strategies to prevent injectionIn general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:
if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
throw new \InvalidArgumentException('This input is not allowed.');
}
For numeric data, we recommend to explicitly cast the data: $sanitized = (integer) $tainted;
Loading history...
|
|||
| 53 | } |
||
| 54 | |||
| 55 | /** |
||
| 56 | * writes a message to file (static version) |
||
| 57 | * |
||
| 58 | * @param string $filename the name of the log file, relative (path to logdir gets prepended) |
||
| 59 | * @param string $message what to write into the file |
||
| 60 | * @return void |
||
| 61 | */ |
||
| 62 | private static function writeToFile_s($filename, $message) |
||
|
0 ignored issues
–
show
|
|||
| 63 | { |
||
| 64 | file_put_contents(\config\Master::PATHS['logdir'] . "/$filename", sprintf("%-015s", microtime(TRUE)) . $message, FILE_APPEND); |
||
| 65 | } |
||
| 66 | |||
| 67 | /** |
||
| 68 | * write debug messages to the log, if the debug level is high enough |
||
| 69 | * |
||
| 70 | * @param int $level the debug level of the message that is to be logged |
||
| 71 | * @param mixed $stuff the stuff to be logged (via print_r) |
||
| 72 | * @param string $prefix prefix to the message, optional |
||
| 73 | * @param string $suffix suffix to the message, optional |
||
| 74 | * @return void |
||
| 75 | */ |
||
| 76 | public function debug($level, $stuff, $prefix = '', $suffix = '') |
||
| 77 | { |
||
| 78 | if (\config\Master::DEBUG_LEVEL < $level) { |
||
| 79 | return; |
||
| 80 | } |
||
| 81 | |||
| 82 | $output = " ($level) "; |
||
| 83 | if ($level > 3) { |
||
| 84 | $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); |
||
| 85 | $orig_file = $backtrace[1]['file'] ?? "no file"; |
||
| 86 | $file = str_replace(ROOT, "", $orig_file); |
||
| 87 | $function = $backtrace[1]['function'] ?? "no function"; |
||
| 88 | $line = $backtrace[1]['line'] ?? "no line"; |
||
| 89 | $output .= " [$file / $function / $line] "; |
||
| 90 | } |
||
| 91 | if (is_string($stuff)) { |
||
| 92 | $output .= $prefix . $stuff . $suffix; |
||
| 93 | } else { |
||
| 94 | $output .= $prefix . var_export($stuff, TRUE) . $suffix; |
||
| 95 | } |
||
| 96 | $this->writeToFile("debug.log", $output); |
||
| 97 | |||
| 98 | return; |
||
| 99 | } |
||
| 100 | |||
| 101 | /** |
||
| 102 | * write debug messages to the log, if the debug level is high enough - static version |
||
| 103 | * |
||
| 104 | * @param int $level the debug level of the message that is to be logged |
||
| 105 | * @param mixed $stuff the stuff to be logged (via print_r) |
||
| 106 | * @param string $prefix prefix to the message, optional |
||
| 107 | * @param string $suffix suffix to the message, optional |
||
| 108 | * @return void |
||
| 109 | */ |
||
| 110 | public static function debug_s($level, $stuff, $prefix = '', $suffix = '') |
||
|
0 ignored issues
–
show
|
|||
| 111 | { |
||
| 112 | if (\config\Master::DEBUG_LEVEL < $level) { |
||
| 113 | return; |
||
| 114 | } |
||
| 115 | |||
| 116 | $output = " ($level) "; |
||
| 117 | if ($level > 3) { |
||
| 118 | $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); |
||
| 119 | $orig_file = $backtrace[1]['file'] ?? "no file"; |
||
| 120 | $file = str_replace(ROOT, "", $orig_file); |
||
| 121 | $function = $backtrace[1]['function'] ?? "no function"; |
||
| 122 | $line = $backtrace[1]['line'] ?? "no line"; |
||
| 123 | $output .= " [$file / $function / $line] "; |
||
| 124 | } |
||
| 125 | if (is_string($stuff)) { |
||
| 126 | $output .= $prefix . $stuff . $suffix; |
||
| 127 | } else { |
||
| 128 | $output .= $prefix . var_export($stuff, TRUE) . $suffix; |
||
| 129 | } |
||
| 130 | self::writeToFile_s("debug.log", $output); |
||
| 131 | return; |
||
| 132 | } |
||
| 133 | |||
| 134 | /** |
||
| 135 | * Writes an audit log entry to the audit log file. These audits are semantic logs; they don't record every single modification |
||
| 136 | * in the database, but provide a logical "who did what" overview. The exact modification SQL statements are logged |
||
| 137 | * automatically with writeSQLAudit() instead. The log file path is configurable in _config.php. |
||
| 138 | * |
||
| 139 | * @param string $user persistent identifier of the user who triggered the action |
||
| 140 | * @param string $category type of modification, from the fixed vocabulary: "NEW", "OWN", "MOD", "DEL" |
||
| 141 | * @param string $message message to log into the audit log |
||
| 142 | * @return boolean TRUE if successful. Will terminate script execution on failure. |
||
| 143 | * @throws Exception |
||
| 144 | */ |
||
| 145 | public function writeAudit($user, $category, $message) |
||
| 146 | { |
||
| 147 | switch ($category) { |
||
| 148 | case "NEW": // created a new object |
||
| 149 | case "OWN": // ownership changes |
||
| 150 | case "MOD": // modified existing object |
||
| 151 | case "DEL": // deleted an object |
||
| 152 | ob_start(); |
||
| 153 | echo " ($category) $user : $message\n"; |
||
| 154 | $output = ob_get_clean(); |
||
| 155 | $this->writeToFile("audit-activity.log", $output); |
||
| 156 | return TRUE; |
||
| 157 | default: |
||
| 158 | throw new Exception("Unable to write to AUDIT file (unknown category, requested data was $user, $category, $message!"); |
||
| 159 | } |
||
| 160 | } |
||
| 161 | |||
| 162 | /** |
||
| 163 | * Writes an audit log entry to the audit log file - static version. These audits are semantic logs; they don't record every single modification |
||
| 164 | * in the database, but provide a logical "who did what" overview. The exact modification SQL statements are logged |
||
| 165 | * automatically with writeSQLAudit() instead. The log file path is configurable in _config.php. |
||
| 166 | * |
||
| 167 | * @param string $user persistent identifier of the user who triggered the action |
||
| 168 | * @param string $category type of modification, from the fixed vocabulary: "NEW", "OWN", "MOD", "DEL" |
||
| 169 | * @param string $message message to log into the audit log |
||
| 170 | * @return boolean TRUE if successful. Will terminate script execution on failure. |
||
| 171 | * @throws Exception |
||
| 172 | */ |
||
| 173 | public static function writeAudit_s($user, $category, $message) |
||
|
0 ignored issues
–
show
|
|||
| 174 | { |
||
| 175 | switch ($category) { |
||
| 176 | case "NEW": // created a new object |
||
| 177 | case "OWN": // ownership changes |
||
| 178 | case "MOD": // modified existing object |
||
| 179 | case "DEL": // deleted an object |
||
| 180 | ob_start(); |
||
| 181 | echo " ($category) $user : $message\n"; |
||
| 182 | $output = ob_get_clean(); |
||
| 183 | self::writeToFile_s("audit-activity.log", $output); |
||
| 184 | return TRUE; |
||
| 185 | default: |
||
| 186 | throw new Exception("Unable to write to AUDIT file (unknown category, requested data was $user, $category, $message!"); |
||
| 187 | } |
||
| 188 | } |
||
| 189 | |||
| 190 | /** |
||
| 191 | * Write an audit log entry to the SQL log file. Every SQL statement which is not a simple SELECT one will be written |
||
| 192 | * to the log file. The log file path is configurable in _config.php. |
||
| 193 | * |
||
| 194 | * @param string $query the SQL query to be logged |
||
| 195 | * @return void |
||
| 196 | */ |
||
| 197 | public function writeSQLAudit($query) |
||
| 198 | { |
||
| 199 | // clean up text to be in one line, with no extra spaces |
||
| 200 | // also clean up non UTF-8 to sanitise possibly malicious inputs |
||
| 201 | $logTextStep1 = preg_replace("/[\n\r]/", "", $query); |
||
| 202 | $logTextStep2 = preg_replace("/ +/", " ", $logTextStep1); |
||
| 203 | $logTextStep3 = iconv("UTF-8", "UTF-8//IGNORE", $logTextStep2); |
||
| 204 | $this->writeToFile("audit-SQL.log", " " . $logTextStep3 . "\n"); |
||
| 205 | } |
||
| 206 | |||
| 207 | |||
| 208 | /** |
||
| 209 | * Write an audit log entry to the SQL log file. Every SQL statement which is not a simple SELECT one will be written |
||
| 210 | * to the log file. The log file path is configurable in _config.php. |
||
| 211 | * |
||
| 212 | * @param string $query the SQL query to be logged |
||
| 213 | * @return void |
||
| 214 | */ |
||
| 215 | public static function writeSQLAudit_s($query) |
||
|
0 ignored issues
–
show
|
|||
| 216 | { |
||
| 217 | // clean up text to be in one line, with no extra spaces |
||
| 218 | // also clean up non UTF-8 to sanitise possibly malicious inputs |
||
| 219 | $logTextStep1 = preg_replace("/[\n\r]/", "", $query); |
||
| 220 | $logTextStep2 = preg_replace("/ +/", " ", $logTextStep1); |
||
| 221 | $logTextStep3 = iconv("UTF-8", "UTF-8//IGNORE", $logTextStep2); |
||
| 222 | self::writeToFile_s("audit-SQL.log", " " . $logTextStep3 . "\n"); |
||
| 223 | } |
||
| 224 | } |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths