Completed
Push — master ( ee79b5...34b090 )
by Stefan
04:54
created

CAT::__construct()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 18
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 14
nc 5
nop 0
dl 0
loc 18
rs 9.2
c 0
b 0
f 0
1
<?php
2
/* *********************************************************************************
3
 * (c) 2011-15 GÉANT on behalf of the GN3, GN3plus and GN4 consortia
4
 * License: see the LICENSE file in the root directory
5
 ***********************************************************************************/
6
?>
7
<?php
8
/**
9
 * 
10
 * 
11
 *  This is the definition of the CAT class
12
 * @author Stefan Winter <[email protected]>
13
 * @author Tomasz Wolniewicz <[email protected]>
14
 *
15
 * @package Developer
16
 */
17
18
/**
19
 * necessary includes
20
 */
21
session_start();
22
require_once("Helper.php");
23
require_once("Federation.php");
24
25
/**
26
 * Define some variables which need to be globally accessible
27
 * and some general purpose methods
28
 *
29
 * @author Stefan Winter <[email protected]>
30
 * @author Tomasz Wolniewicz <[email protected]>
31
 *
32
 * @package Developer
33
 */
34
class CAT {
35
36
    /** 
37
     * which version is this?
38
     * even if we are unreleased, keep track of internal version-to-be
39
     * developers need to set this in code. The user-displayed string
40
     * is generated into $VERSION below
41
     */
42
    public static $VERSION_MAJOR = 1;
43
    public static $VERSION_MINOR = 2;
44
    public static $VERSION_PATCH = 0;
45
    public static $VERSION_EXTRA = "";
46
    public static $RELEASE_VERSION = FALSE;
47
    public static $USER_API_VERSION = 2;
48
    
49
    /*
50
     * This is the user-displayed string; controlled by the four options above
51
     * It is generated in the constructor.
52
     */
53
    
54
    public static $VERSION;
55
    /**
56
   /**
57
     * database which this class queries by default
58
     * 
59
     * @var string
60
     */
61
    private static $LANG = '';
62
    private static $DB_TYPE = "INST";
63
    /**
64
     *  Constructor sets the language by calling set_lang 
65
     *  and stores language settings in object properties
66
     *  additionally it also sets static variables $laing_index and $root
67
     */
68
    public function __construct() {
69
        $A = $this->set_lang();
70
        self::$locale = $A[1];
71
        $a = __DIR__;
72
        self::$root = dirname($a);
73
74
75
        if (CAT::$RELEASE_VERSION) {
76
            $temp_version = "CAT-".CAT::$VERSION_MAJOR.".".CAT::$VERSION_MINOR;
77
            if (CAT::$VERSION_PATCH != 0)
78
                    $temp_version .= ".".CAT::$VERSION_PATCH;
79
            if (CAT::$VERSION_EXTRA != "")
80
                $temp_version .= "-".CAT::$VERSION_EXTRA;
81
            CAT::$VERSION = sprintf(_("Release %s"), $temp_version );
82
        }
83
        else
84
            CAT::$VERSION = _("Unreleased SVN Revision");
85
    }
86
87
    /** 
88
     * 
89
     */
90
    public function totalIdPs($level) {
91
        switch ($level) {
92
            case "ALL":
93
                $idpcount = DBConnection::exec(CAT::$DB_TYPE, "SELECT COUNT(inst_id) AS instcount FROM institution");
94
                break;
95
            case "VALIDPROFILE":
96
                $idpcount = DBConnection::exec(CAT::$DB_TYPE, "SELECT COUNT(DISTINCT institution.inst_id) AS instcount FROM institution,profile WHERE institution.inst_id = profile.inst_id AND profile.sufficient_config = 1");
97
                break;
98
            case "PUBLICPROFILE":
99
                $idpcount = DBConnection::exec(CAT::$DB_TYPE, "SELECT COUNT(DISTINCT institution.inst_id) AS instcount FROM institution,profile WHERE institution.inst_id = profile.inst_id AND profile.showtime = 1");
100
                break;
101
            default:
102
                return -1;
103
        }
104
        $dbresult = mysqli_fetch_object($idpcount);
105
        return $dbresult->instcount;
106
    }
107
    
108
    /**
109
     * Sets the gettext domain
110
     *
111
     * @param string $domain
112
     * @return string previous seting so that you can restore it later
113
     */
114
    public static function set_locale($domain) {
115
        $olddomain = textdomain(NULL);
116
        debug(4, "set_locale($domain)\n");
117
        debug(4, CAT::$root . "\n");
118
        textdomain($domain);
119
        bindtextdomain($domain, CAT::$root . "/translation/");
120
        return $olddomain;
121
    }
122
123
    /**
124
     * set_lang does all language setting magic
125
     * checks if lang has been declared in the http call
126
     * if not, checks for saved lang in the SESSION
127
     * or finally checks browser properties.
128
     * Only one of the supported langiages can be set
129
     * if a match is not found, the default langiage is used
130
     * @param $hardsetlang - this is currently not used but
131
     * will allow to forst lang setting if this was ever required
132
     */
133
    private static function set_lang($hardsetlang = 0) {
134
        $lang_converted = [];
135
        if ($hardsetlang !== 0) {
136
            $hardsetlocale = $hardsetlang;
137
            $lang_converted[] = $hardsetlocale;
138
            $_SESSION['language'] = $hardsetlocale;
139
        } elseif (isset($_REQUEST['lang'])) {
140
            $hardsetlocale = $_REQUEST['lang'];
141
            $lang_converted[] = $hardsetlocale;
142
            $_SESSION['language'] = $hardsetlocale;
143
        } elseif (isset($_SESSION['language'])) {
144
            $hardsetlocale = $_SESSION['language'];
145
            $lang_converted[] = $hardsetlocale;
146
        } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
147
            $langs = explode(",", $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
148
            foreach ($langs as $lang) {
149
                preg_match("/(.*);+.*/", $lang, $result);
150
                $lang_converted[] = (isset($result[1]) && $result[1] ? $result[1] : $lang);
151
            }
152
        };
153
        // always add configured locale as last resort
154
        $defaultlocale = Config::$APPEARANCE['defaultlocale'];
155
        $lang_converted[] = Config::$LANGUAGES[$defaultlocale]['locale'];
156
        $lang_index = $defaultlocale;
157
158
        setlocale(LC_ALL, 0);
159
160
        foreach ($lang_converted as $try_lang) {
161
            // madness! setlocale is completely unflexible. If $try_lang is "en"
162
            // it will fail, because it only knows en_US, en_GB a.s.o.
163
            // we need to map stuff manually
164
            $thelang = $try_lang;
165
166
            foreach (Config::$LANGUAGES as $language => $value)
167
                if (preg_match("/^" . $language . ".*/", $try_lang)) {
168
                    $thelang = $value['locale'];
169
                    $lang_index = $language;
170
                }
171
172
            // echo "Trying to set language to $thelang...";
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
173
//        putenv("LC_ALL=$thelang");
174
            if (setlocale(LC_ALL, $thelang))
175
                break;
176
        }
177
        putenv("LC_ALL=" . $thelang);
0 ignored issues
show
Bug introduced by
The variable $thelang does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Security Other Vulnerability introduced by
'LC_ALL=' . $thelang can contain request data and is used in security-relevant context(s) leading to a potential security vulnerability.

2 paths for user data to reach this point

  1. Path: Read from $_REQUEST, and $hardsetlocale is assigned in core/CAT.php on line 140
  1. Read from $_REQUEST, and $hardsetlocale is assigned
    in core/CAT.php on line 140
  2. $lang_converted is assigned
    in core/CAT.php on line 141
  3. $lang_converted is assigned
    in core/CAT.php on line 155
  4. $try_lang is assigned
    in core/CAT.php on line 160
  5. $thelang is assigned
    in core/CAT.php on line 164
  2. Path: Fetching key HTTP_ACCEPT_LANGUAGE from $_SERVER, and $_SERVER['HTTP_ACCEPT_LANGUAGE'] is passed through explode(), and $langs is assigned in core/CAT.php on line 147
  1. Fetching key HTTP_ACCEPT_LANGUAGE from $_SERVER, and $_SERVER['HTTP_ACCEPT_LANGUAGE'] is passed through explode(), and $langs is assigned
    in core/CAT.php on line 147
  2. $lang is assigned
    in core/CAT.php on line 148
  3. $lang_converted is assigned
    in core/CAT.php on line 150
  4. $lang_converted is assigned
    in core/CAT.php on line 155
  5. $try_lang is assigned
    in core/CAT.php on line 160
  6. $thelang is assigned
    in core/CAT.php on line 164

General Strategies to prevent injection

In 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...
178
        debug(4, "selected lang:$lang_index:$thelang\n");
179
        debug(4, $lang_converted);
180
        return([$lang_index, $thelang]);
181
    }
182
183
    /**
184
     * gets the language setting in CAT
185
     */
186
    static public function get_lang() {
187
       if(self::$LANG === '')
188
         list(self::$LANG, $xx) = self::set_lang();
0 ignored issues
show
Unused Code introduced by
The assignment to $xx is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
189
       return self::$LANG;
190
    }
191
192
    /**
193
     * Prepares a list of countries known to the CAT.
194
     * 
195
     * @param int $active_only is set and nonzero will cause that only countries with some institutions underneath will be listed
196
     * @return array Array indexed by (uppercase) lang codes and sorted according to the current locale
197
     */
198
    public function printCountryList($active_only = 0) {
199
        $olddomain = $this->set_locale("core");
200
        if ($active_only) {
201
            $federations = DBConnection::exec(CAT::$DB_TYPE, "SELECT DISTINCT LOWER(institution.country) AS country FROM institution JOIN profile
202
                          ON institution.inst_id = profile.inst_id WHERE profile.showtime = 1 ORDER BY country");
203
            while ($a = mysqli_fetch_object($federations)) {
204
                $b = $a->country;
205
                $F = new Federation($b);
206
                $c = strtoupper($F->name);
207
                $C[$c] = isset(Federation::$FederationList[$c]) ? Federation::$FederationList[$c] : $c;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$C was never initialized. Although not strictly required by PHP, it is generally a good practice to add $C = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
208
            }
209
        } else {
210
            new Federation;
211
            $C = Federation::$FederationList;
212
        }
213
        asort($C, SORT_LOCALE_STRING);
214
        $this->set_locale($olddomain);
215
        return($C);
216
    }
217
218
    /**
219
     * Writes an audit log entry to the audit log file. These audits are semantic logs; they don't record every single modification
220
     * in the database, but provide a logical "who did what" overview. The exact modification SQL statements are logged
221
     * automatically with writeSQLAudit() instead. The log file path is configurable in _config.php.
222
     * 
223
     * @param string $user persistent identifier of the user who triggered the action
224
     * @param string $category type of modification, from the fixed vocabulary: "NEW", "OWN", "MOD", "DEL"
225
     * @param string $message message to log into the audit log
226
     * @return boolean TRUE if successful. Will terminate script execution on failure. 
227
     */
228
    public static function writeAudit($user, $category, $message) {
229
        switch ($category) {
230
            case "NEW": // created a new object
231
            case "OWN": // ownership changes
232
            case "MOD": // modified existing object
233
            case "DEL": // deleted an object
234
                ob_start();
235
                printf("%-015s",microtime(TRUE));
236
                print " ($category) ";
237
                print_r(" ".$user.": ".$message."\n");
0 ignored issues
show
Security Cross-Site Scripting introduced by
' ' . $user . ': ' . $message . ' ' can contain request data and is used in output context(s) leading to a potential security vulnerability.

15 paths for user data to reach this point

  1. Path: Read from $_POST in web/admin/inc/sendinvite.inc.php on line 46
  1. Read from $_POST
    in web/admin/inc/sendinvite.inc.php on line 46
  2. Data is passed through iconv(), and Data is passed through trim()
    in vendor/web/admin/inc/input_validation.inc.php on line 87
  3. Data is passed through filter_var()
    in vendor/web/admin/inc/input_validation.inc.php on line 89
  4. Data is passed through preg_replace()
    in vendor/web/admin/inc/input_validation.inc.php on line 93
  5. $newmailaddress is assigned
    in web/admin/inc/sendinvite.inc.php on line 46
  6. 'IdP ' . $idp->identifier . ' - Token created for ' . $newmailaddress is passed to CAT::writeAudit()
    in web/admin/inc/sendinvite.inc.php on line 74
  2. Path: Read from $_GET, and $_GET['fed'] is passed to valid_Fed() in web/admin/action_fedcheck.php on line 162
  1. Read from $_GET, and $_GET['fed'] is passed to valid_Fed()
    in web/admin/action_fedcheck.php on line 162
  2. $input is passed to Federation::__construct()
    in web/admin/inc/input_validation.inc.php on line 24
  3. EntityWithDBProperties::$name is assigned
    in core/Federation.php on line 123
  4. Tainted property EntityWithDBProperties::$name is read, and 'FED ' . $my_fed->name . ' - attributes changed' is passed to CAT::writeAudit()
    in web/admin/edit_federation_result.php on line 39
  3. Path: Read from $_POST, and $_POST['fed_id'] is passed to valid_Fed() in web/admin/edit_federation.php on line 22
  1. Read from $_POST, and $_POST['fed_id'] is passed to valid_Fed()
    in web/admin/edit_federation.php on line 22
  2. $input is passed to Federation::__construct()
    in web/admin/inc/input_validation.inc.php on line 24
  3. EntityWithDBProperties::$name is assigned
    in core/Federation.php on line 123
  4. Tainted property EntityWithDBProperties::$name is read, and 'FED ' . $my_fed->name . ' - attributes changed' is passed to CAT::writeAudit()
    in web/admin/edit_federation_result.php on line 39
  4. Path: Read from $_GET, and $_GET['fed_id'] is passed to valid_Fed() in web/admin/edit_federation_result.php on line 26
  1. Read from $_GET, and $_GET['fed_id'] is passed to valid_Fed()
    in web/admin/edit_federation_result.php on line 26
  2. $input is passed to Federation::__construct()
    in web/admin/inc/input_validation.inc.php on line 24
  3. EntityWithDBProperties::$name is assigned
    in core/Federation.php on line 123
  4. Tainted property EntityWithDBProperties::$name is read, and 'FED ' . $my_fed->name . ' - attributes changed' is passed to CAT::writeAudit()
    in web/admin/edit_federation_result.php on line 39
  5. Path: Read from $_GET, and $_GET['fed_id'] is passed to valid_Fed() in web/admin/edit_federation_result.php on line 43
  1. Read from $_GET, and $_GET['fed_id'] is passed to valid_Fed()
    in web/admin/edit_federation_result.php on line 43
  2. $input is passed to Federation::__construct()
    in web/admin/inc/input_validation.inc.php on line 24
  3. EntityWithDBProperties::$name is assigned
    in core/Federation.php on line 123
  4. Tainted property EntityWithDBProperties::$name is read, and 'FED ' . $my_fed->name . ' - attributes changed' is passed to CAT::writeAudit()
    in web/admin/edit_federation_result.php on line 39
  6. Path: Read from $_POST in web/admin/inc/sendinvite.inc.php on line 83
  1. Read from $_POST
    in web/admin/inc/sendinvite.inc.php on line 83
  2. Data is passed through iconv(), and Data is passed through trim()
    in vendor/web/admin/inc/input_validation.inc.php on line 87
  3. Data is passed through filter_var()
    in vendor/web/admin/inc/input_validation.inc.php on line 89
  4. Data is passed through preg_replace()
    in vendor/web/admin/inc/input_validation.inc.php on line 93
  5. $newcountry is assigned
    in web/admin/inc/sendinvite.inc.php on line 83
  6. $newcountry is passed to Federation::__construct()
    in web/admin/inc/sendinvite.inc.php on line 85
  7. EntityWithDBProperties::$name is assigned
    in core/Federation.php on line 123
  8. Tainted property EntityWithDBProperties::$name is read, and 'FED ' . $my_fed->name . ' - attributes changed' is passed to CAT::writeAudit()
    in web/admin/edit_federation_result.php on line 39
  7. Path: Read from $_REQUEST, and $_REQUEST['country'] is passed through strtoupper(), and $c is assigned in web/basic.php on line 59
  1. Read from $_REQUEST, and $_REQUEST['country'] is passed through strtoupper(), and $c is assigned
    in web/basic.php on line 59
  2. $c is passed to Federation::__construct()
    in web/basic.php on line 71
  3. EntityWithDBProperties::$name is assigned
    in core/Federation.php on line 123
  4. Tainted property EntityWithDBProperties::$name is read, and 'FED ' . $my_fed->name . ' - attributes changed' is passed to CAT::writeAudit()
    in web/admin/edit_federation_result.php on line 39
  8. Path: Read from $_REQUEST, and $_REQUEST['idp'] is passed to IdP::__construct() in web/basic.php on line 84
  1. Read from $_REQUEST, and $_REQUEST['idp'] is passed to IdP::__construct()
    in web/basic.php on line 84
  2. EntityWithDBProperties::$identifier is assigned
    in core/IdP.php on line 69
  3. Tainted property EntityWithDBProperties::$identifier is read, and 'IdP ' . $newidp->identifier . " - {$mode} registration" is passed to CAT::writeAudit()
    in web/admin/action_enrollment.php on line 50
  9. Path: Read from $_REQUEST, and $id is assigned in web/user/API.php on line 22
  1. Read from $_REQUEST, and $id is assigned
    in web/user/API.php on line 22
  2. $idp is assigned
    in web/user/API.php on line 59
  3. $idp is passed to UserAPI::JSON_listProfiles()
    in web/user/API.php on line 61
  4. $idp_id is passed to IdP::__construct()
    in core/UserAPI.php on line 331
  5. EntityWithDBProperties::$identifier is assigned
    in core/IdP.php on line 69
  6. Tainted property EntityWithDBProperties::$identifier is read, and 'IdP ' . $newidp->identifier . " - {$mode} registration" is passed to CAT::writeAudit()
    in web/admin/action_enrollment.php on line 50
  10. Path: Read from $_REQUEST, and $idp is assigned in web/user/API.php on line 25
  1. Read from $_REQUEST, and $idp is assigned
    in web/user/API.php on line 25
  2. $idp is passed to UserAPI::JSON_listProfiles()
    in web/user/API.php on line 61
  3. $idp_id is passed to IdP::__construct()
    in core/UserAPI.php on line 331
  4. EntityWithDBProperties::$identifier is assigned
    in core/IdP.php on line 69
  5. Tainted property EntityWithDBProperties::$identifier is read, and 'IdP ' . $newidp->identifier . " - {$mode} registration" is passed to CAT::writeAudit()
    in web/admin/action_enrollment.php on line 50
  11. Path: Read from $_REQUEST, and $id is assigned in web/user/cat_back.php on line 22
  1. Read from $_REQUEST, and $id is assigned
    in web/user/cat_back.php on line 22
  2. $id is passed to UserAPI::JSON_listProfiles()
    in web/user/cat_back.php on line 46
  3. $idp_id is passed to IdP::__construct()
    in core/UserAPI.php on line 331
  4. EntityWithDBProperties::$identifier is assigned
    in core/IdP.php on line 69
  5. Tainted property EntityWithDBProperties::$identifier is read, and 'IdP ' . $newidp->identifier . " - {$mode} registration" is passed to CAT::writeAudit()
    in web/admin/action_enrollment.php on line 50
  12. Path: Read from $_REQUEST, and $_REQUEST['profile'] is passed to Profile::__construct() in web/basic.php on line 106
  1. Read from $_REQUEST, and $_REQUEST['profile'] is passed to Profile::__construct()
    in web/basic.php on line 106
  2. EntityWithDBProperties::$identifier is assigned
    in core/Profile.php on line 70
  3. Tainted property EntityWithDBProperties::$identifier is read, and 'Profile ' . $profile->identifier . ' - attributes changed' is passed to CAT::writeAudit()
    in web/admin/edit_profile_result.php on line 176
  13. Path: Read from $_REQUEST, and $profile_id is assigned in web/download.php on line 22
  1. Read from $_REQUEST, and $profile_id is assigned
    in web/download.php on line 22
  2. $profile_id is passed to Profile::__construct()
    in web/download.php on line 42
  3. EntityWithDBProperties::$identifier is assigned
    in core/Profile.php on line 70
  4. Tainted property EntityWithDBProperties::$identifier is read, and 'Profile ' . $profile->identifier . ' - attributes changed' is passed to CAT::writeAudit()
    in web/admin/edit_profile_result.php on line 176
  14. Path: Read from $_REQUEST, and $profile is assigned in web/user/API.php on line 26
  1. Read from $_REQUEST, and $profile is assigned
    in web/user/API.php on line 26
  2. $profile is passed to UserAPI::deviceInfo()
    in web/user/API.php on line 96
  3. $prof_id is passed to Profile::__construct()
    in core/UserAPI.php on line 153
  4. EntityWithDBProperties::$identifier is assigned
    in core/Profile.php on line 70
  5. Tainted property EntityWithDBProperties::$identifier is read, and 'Profile ' . $profile->identifier . ' - attributes changed' is passed to CAT::writeAudit()
    in web/admin/edit_profile_result.php on line 176
  15. Path: Read from $_REQUEST, and $profile is assigned in web/user/cat_back.php on line 24
  1. Read from $_REQUEST, and $profile is assigned
    in web/user/cat_back.php on line 24
  2. $profile is passed to UserAPI::deviceInfo()
    in web/user/cat_back.php on line 68
  3. $prof_id is passed to Profile::__construct()
    in core/UserAPI.php on line 153
  4. EntityWithDBProperties::$identifier is assigned
    in core/Profile.php on line 70
  5. Tainted property EntityWithDBProperties::$identifier is read, and 'Profile ' . $profile->identifier . ' - attributes changed' is passed to CAT::writeAudit()
    in web/admin/edit_profile_result.php on line 176

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In 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...
238
                $output = ob_get_clean();
239 View Code Duplication
                if (Config::$PATHS['logdir']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
240
                    $f = fopen(Config::$PATHS['logdir'] . "/audit-activity.log", "a");
241
                    fwrite($f, $output);
242
                    fclose($f);
243
                } else {
244
                    print $output;
245
                }
246
247
                return TRUE;
248
            default:
249
                exit(1);
250
        }
251
    }
252
253
    /**
254
     * Write an audit log entry to the SQL log file. Every SQL statement which is not a simple SELECT one will be written
255
     * to the log file. The log file path is configurable in _config.php.
256
     * 
257
     * @param string $query the SQL query to be logged
258
     */
259
    public static function writeSQLAudit($query) {
260
        // clean up text to be in one line, with no extra spaces
261
        $logtext1 = preg_replace("/[\n\r]/", "", $query);
262
        $logtext = preg_replace("/ +/", " ", $logtext1);
263
        ob_start();
264
        printf("%-015s",microtime(TRUE));
265
        print(" ".$logtext."\n");
0 ignored issues
show
Security Cross-Site Scripting introduced by
' ' . $logtext . ' ' can contain request data and is used in output context(s) leading to a potential security vulnerability.

14 paths for user data to reach this point

  1. Path: Read from $_POST, and $_POST[display_name($a) . '-priority'] is passed to Profile::addSupportedEapMethod() in web/admin/edit_profile_result.php on line 185
  1. Read from $_POST, and $_POST[display_name($a) . '-priority'] is passed to Profile::addSupportedEapMethod()
    in web/admin/edit_profile_result.php on line 185
  2. 'INSERT INTO supported_eap (profile_id, eap_method_id, preference) VALUES (' . $this->identifier . ', ' . \EAP::EAPMethodIdFromArray($type) . ', ' . $preference . ')' is passed to DBConnection::exec()
    in core/Profile.php on line 417
  3. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  4. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  5. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  2. Path: Read from $_POST in web/admin/inc/sendinvite.inc.php on line 82
  1. Read from $_POST
    in web/admin/inc/sendinvite.inc.php on line 82
  2. Data is passed through iconv(), and Data is passed through trim()
    in vendor/web/admin/inc/input_validation.inc.php on line 87
  3. Data is passed through filter_var()
    in vendor/web/admin/inc/input_validation.inc.php on line 89
  4. Data is passed through preg_replace()
    in vendor/web/admin/inc/input_validation.inc.php on line 93
  5. $newinstname is assigned
    in web/admin/inc/sendinvite.inc.php on line 82
  6. $newinstname is passed to UserManagement::createToken()
    in web/admin/inc/sendinvite.inc.php on line 91
  7. Data is passed through iconv(), and Data is passed through trim()
    in vendor/web/admin/inc/input_validation.inc.php on line 87
  8. Data is passed through filter_var()
    in vendor/web/admin/inc/input_validation.inc.php on line 89
  9. Data is passed through preg_replace()
    in vendor/web/admin/inc/input_validation.inc.php on line 93
  10. Data is escaped by mysqli_real_escape_string() for sql context(s)
    in vendor/core/DBConnection.php on line 82
  11. $newname is assigned
    in core/UserManagement.php on line 229
  12. "INSERT INTO invitations (invite_issuer_level, invite_dest_mail, invite_token,name,country, external_db_uniquehandle) VALUES('{$level}', '{$for}', '{$token}', '" . $newname . '\', \'' . $extinfo['country'] . '\', \'' . $externalhandle . '\')' is passed to DBConnection::exec()
    in core/UserManagement.php on line 232
  13. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  14. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  15. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  3. Path: Read from $_POST in web/admin/inc/sendinvite.inc.php on line 95
  1. Read from $_POST
    in web/admin/inc/sendinvite.inc.php on line 95
  2. Data is passed through iconv(), and Data is passed through trim()
    in vendor/web/admin/inc/input_validation.inc.php on line 87
  3. Data is passed through filter_var()
    in vendor/web/admin/inc/input_validation.inc.php on line 89
  4. Data is passed through preg_replace()
    in vendor/web/admin/inc/input_validation.inc.php on line 93
  5. $newexternalid is assigned
    in web/admin/inc/sendinvite.inc.php on line 95
  6. $newexternalid is passed to UserManagement::createToken()
    in web/admin/inc/sendinvite.inc.php on line 115
  7. Data is passed through iconv(), and Data is passed through trim()
    in vendor/web/admin/inc/input_validation.inc.php on line 87
  8. Data is passed through filter_var()
    in vendor/web/admin/inc/input_validation.inc.php on line 89
  9. Data is passed through preg_replace()
    in vendor/web/admin/inc/input_validation.inc.php on line 93
  10. Data is escaped by mysqli_real_escape_string() for sql context(s)
    in vendor/core/DBConnection.php on line 82
  11. $externalhandle is assigned
    in core/UserManagement.php on line 231
  12. "INSERT INTO invitations (invite_issuer_level, invite_dest_mail, invite_token,name,country, external_db_uniquehandle) VALUES('{$level}', '{$for}', '{$token}', '" . $newname . '\', \'' . $extinfo['country'] . '\', \'' . $externalhandle . '\')' is passed to DBConnection::exec()
    in core/UserManagement.php on line 232
  13. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  14. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  15. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  4. Path: Read from $_POST in web/admin/inc/sendinvite.inc.php on line 83
  1. Read from $_POST
    in web/admin/inc/sendinvite.inc.php on line 83
  2. Data is passed through iconv(), and Data is passed through trim()
    in vendor/web/admin/inc/input_validation.inc.php on line 87
  3. Data is passed through filter_var()
    in vendor/web/admin/inc/input_validation.inc.php on line 89
  4. Data is passed through preg_replace()
    in vendor/web/admin/inc/input_validation.inc.php on line 93
  5. $newcountry is assigned
    in web/admin/inc/sendinvite.inc.php on line 83
  6. $newcountry is passed to Federation::__construct()
    in web/admin/inc/sendinvite.inc.php on line 85
  7. EntityWithDBProperties::$identifier is assigned
    in core/Federation.php on line 122
  8. Tainted property EntityWithDBProperties::$identifier is read
    in web/admin/action_fedcheck.php on line 38
  9. 'UPDATE profile SET ' . 'status_dns = ' . RETVAL_SKIPPED . ', ' . 'status_cert = ' . RETVAL_SKIPPED . ', ' . 'status_reachability = ' . RETVAL_SKIPPED . ', ' . 'status_TLS = ' . RETVAL_SKIPPED . ', ' . 'last_status_check = NOW() ' . 'WHERE profile_id = ' . $profile->identifier is passed to DBConnection::exec()
    in web/admin/action_fedcheck.php on line 32
  10. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  11. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  12. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  5. Path: Read from $_GET, and $_GET['fed'] is passed to valid_Fed() in web/admin/action_fedcheck.php on line 162
  1. Read from $_GET, and $_GET['fed'] is passed to valid_Fed()
    in web/admin/action_fedcheck.php on line 162
  2. $input is passed to Federation::__construct()
    in web/admin/inc/input_validation.inc.php on line 24
  3. EntityWithDBProperties::$identifier is assigned
    in core/Federation.php on line 122
  4. Tainted property EntityWithDBProperties::$identifier is read
    in web/admin/action_fedcheck.php on line 38
  5. 'UPDATE profile SET ' . 'status_dns = ' . RETVAL_SKIPPED . ', ' . 'status_cert = ' . RETVAL_SKIPPED . ', ' . 'status_reachability = ' . RETVAL_SKIPPED . ', ' . 'status_TLS = ' . RETVAL_SKIPPED . ', ' . 'last_status_check = NOW() ' . 'WHERE profile_id = ' . $profile->identifier is passed to DBConnection::exec()
    in web/admin/action_fedcheck.php on line 32
  6. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  7. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  8. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  6. Path: Read from $_POST, and $_POST['fed_id'] is passed to valid_Fed() in web/admin/edit_federation.php on line 22
  1. Read from $_POST, and $_POST['fed_id'] is passed to valid_Fed()
    in web/admin/edit_federation.php on line 22
  2. $input is passed to Federation::__construct()
    in web/admin/inc/input_validation.inc.php on line 24
  3. EntityWithDBProperties::$identifier is assigned
    in core/Federation.php on line 122
  4. Tainted property EntityWithDBProperties::$identifier is read
    in web/admin/action_fedcheck.php on line 38
  5. 'UPDATE profile SET ' . 'status_dns = ' . RETVAL_SKIPPED . ', ' . 'status_cert = ' . RETVAL_SKIPPED . ', ' . 'status_reachability = ' . RETVAL_SKIPPED . ', ' . 'status_TLS = ' . RETVAL_SKIPPED . ', ' . 'last_status_check = NOW() ' . 'WHERE profile_id = ' . $profile->identifier is passed to DBConnection::exec()
    in web/admin/action_fedcheck.php on line 32
  6. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  7. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  8. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  7. Path: Read from $_GET, and $_GET['fed_id'] is passed to valid_Fed() in web/admin/edit_federation_result.php on line 26
  1. Read from $_GET, and $_GET['fed_id'] is passed to valid_Fed()
    in web/admin/edit_federation_result.php on line 26
  2. $input is passed to Federation::__construct()
    in web/admin/inc/input_validation.inc.php on line 24
  3. EntityWithDBProperties::$identifier is assigned
    in core/Federation.php on line 122
  4. Tainted property EntityWithDBProperties::$identifier is read
    in web/admin/action_fedcheck.php on line 38
  5. 'UPDATE profile SET ' . 'status_dns = ' . RETVAL_SKIPPED . ', ' . 'status_cert = ' . RETVAL_SKIPPED . ', ' . 'status_reachability = ' . RETVAL_SKIPPED . ', ' . 'status_TLS = ' . RETVAL_SKIPPED . ', ' . 'last_status_check = NOW() ' . 'WHERE profile_id = ' . $profile->identifier is passed to DBConnection::exec()
    in web/admin/action_fedcheck.php on line 32
  6. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  7. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  8. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  8. Path: Read from $_GET, and $_GET['fed_id'] is passed to valid_Fed() in web/admin/edit_federation_result.php on line 43
  1. Read from $_GET, and $_GET['fed_id'] is passed to valid_Fed()
    in web/admin/edit_federation_result.php on line 43
  2. $input is passed to Federation::__construct()
    in web/admin/inc/input_validation.inc.php on line 24
  3. EntityWithDBProperties::$identifier is assigned
    in core/Federation.php on line 122
  4. Tainted property EntityWithDBProperties::$identifier is read
    in web/admin/action_fedcheck.php on line 38
  5. 'UPDATE profile SET ' . 'status_dns = ' . RETVAL_SKIPPED . ', ' . 'status_cert = ' . RETVAL_SKIPPED . ', ' . 'status_reachability = ' . RETVAL_SKIPPED . ', ' . 'status_TLS = ' . RETVAL_SKIPPED . ', ' . 'last_status_check = NOW() ' . 'WHERE profile_id = ' . $profile->identifier is passed to DBConnection::exec()
    in web/admin/action_fedcheck.php on line 32
  6. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  7. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  8. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  9. Path: Read from $_REQUEST, and $_REQUEST['country'] is passed through strtoupper(), and $c is assigned in web/basic.php on line 59
  1. Read from $_REQUEST, and $_REQUEST['country'] is passed through strtoupper(), and $c is assigned
    in web/basic.php on line 59
  2. $c is passed to Federation::__construct()
    in web/basic.php on line 71
  3. EntityWithDBProperties::$identifier is assigned
    in core/Federation.php on line 122
  4. Tainted property EntityWithDBProperties::$identifier is read
    in web/admin/action_fedcheck.php on line 38
  5. 'UPDATE profile SET ' . 'status_dns = ' . RETVAL_SKIPPED . ', ' . 'status_cert = ' . RETVAL_SKIPPED . ', ' . 'status_reachability = ' . RETVAL_SKIPPED . ', ' . 'status_TLS = ' . RETVAL_SKIPPED . ', ' . 'last_status_check = NOW() ' . 'WHERE profile_id = ' . $profile->identifier is passed to DBConnection::exec()
    in web/admin/action_fedcheck.php on line 32
  6. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  7. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  8. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  10. Path: Read from $_REQUEST, and $_REQUEST['idp'] is passed to IdP::__construct() in web/basic.php on line 84
  1. Read from $_REQUEST, and $_REQUEST['idp'] is passed to IdP::__construct()
    in web/basic.php on line 84
  2. EntityWithDBProperties::$identifier is assigned
    in core/IdP.php on line 69
  3. Tainted property EntityWithDBProperties::$identifier is read
    in web/admin/action_fedcheck.php on line 38
  4. 'UPDATE profile SET ' . 'status_dns = ' . RETVAL_SKIPPED . ', ' . 'status_cert = ' . RETVAL_SKIPPED . ', ' . 'status_reachability = ' . RETVAL_SKIPPED . ', ' . 'status_TLS = ' . RETVAL_SKIPPED . ', ' . 'last_status_check = NOW() ' . 'WHERE profile_id = ' . $profile->identifier is passed to DBConnection::exec()
    in web/admin/action_fedcheck.php on line 32
  5. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  6. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  7. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  11. Path: Read from $_REQUEST, and $id is assigned in web/user/API.php on line 22
  1. Read from $_REQUEST, and $id is assigned
    in web/user/API.php on line 22
  2. $idp is assigned
    in web/user/API.php on line 59
  3. $idp is passed to UserAPI::JSON_listProfiles()
    in web/user/API.php on line 61
  4. $idp_id is passed to IdP::__construct()
    in core/UserAPI.php on line 331
  5. EntityWithDBProperties::$identifier is assigned
    in core/IdP.php on line 69
  6. Tainted property EntityWithDBProperties::$identifier is read
    in web/admin/action_fedcheck.php on line 38
  7. 'UPDATE profile SET ' . 'status_dns = ' . RETVAL_SKIPPED . ', ' . 'status_cert = ' . RETVAL_SKIPPED . ', ' . 'status_reachability = ' . RETVAL_SKIPPED . ', ' . 'status_TLS = ' . RETVAL_SKIPPED . ', ' . 'last_status_check = NOW() ' . 'WHERE profile_id = ' . $profile->identifier is passed to DBConnection::exec()
    in web/admin/action_fedcheck.php on line 32
  8. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  9. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  10. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  12. Path: Read from $_REQUEST, and $idp is assigned in web/user/API.php on line 25
  1. Read from $_REQUEST, and $idp is assigned
    in web/user/API.php on line 25
  2. $idp is passed to UserAPI::JSON_listProfiles()
    in web/user/API.php on line 61
  3. $idp_id is passed to IdP::__construct()
    in core/UserAPI.php on line 331
  4. EntityWithDBProperties::$identifier is assigned
    in core/IdP.php on line 69
  5. Tainted property EntityWithDBProperties::$identifier is read
    in web/admin/action_fedcheck.php on line 38
  6. 'UPDATE profile SET ' . 'status_dns = ' . RETVAL_SKIPPED . ', ' . 'status_cert = ' . RETVAL_SKIPPED . ', ' . 'status_reachability = ' . RETVAL_SKIPPED . ', ' . 'status_TLS = ' . RETVAL_SKIPPED . ', ' . 'last_status_check = NOW() ' . 'WHERE profile_id = ' . $profile->identifier is passed to DBConnection::exec()
    in web/admin/action_fedcheck.php on line 32
  7. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  8. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  9. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  13. Path: Read from $_REQUEST, and $id is assigned in web/user/cat_back.php on line 22
  1. Read from $_REQUEST, and $id is assigned
    in web/user/cat_back.php on line 22
  2. $id is passed to UserAPI::JSON_listProfiles()
    in web/user/cat_back.php on line 46
  3. $idp_id is passed to IdP::__construct()
    in core/UserAPI.php on line 331
  4. EntityWithDBProperties::$identifier is assigned
    in core/IdP.php on line 69
  5. Tainted property EntityWithDBProperties::$identifier is read
    in web/admin/action_fedcheck.php on line 38
  6. 'UPDATE profile SET ' . 'status_dns = ' . RETVAL_SKIPPED . ', ' . 'status_cert = ' . RETVAL_SKIPPED . ', ' . 'status_reachability = ' . RETVAL_SKIPPED . ', ' . 'status_TLS = ' . RETVAL_SKIPPED . ', ' . 'last_status_check = NOW() ' . 'WHERE profile_id = ' . $profile->identifier is passed to DBConnection::exec()
    in web/admin/action_fedcheck.php on line 32
  7. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  8. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  9. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262
  14. Path: Read from $_POST, and $device_key is assigned in web/admin/inc/toggleRedirect.inc.php on line 36
  1. Read from $_POST, and $device_key is assigned
    in web/admin/inc/toggleRedirect.inc.php on line 36
  2. $device_key is passed to processSubmittedFields()
    in web/admin/inc/toggleRedirect.inc.php on line 75
  3. $device is passed to Profile::addAttribute()
    in web/admin/inc/option_parse.inc.php on line 248
  4. Data is escaped by mysqli_real_escape_string() for sql context(s)
    in vendor/core/DBConnection.php on line 82
  5. ``"INSERT INTO {$this->entityOptionTable} ({$this->entityIdColumn}, option_name, option_value, eap_method_id" . ($device !== 0 ? ',device_id' : '') . ') VALUES(' . $this->identifier . ", '{$escapedAttrName}', '{$escapedAttrValue}', {$eapType}" . ($device !== 0 ? ',\'' . DBConnection::escape_value($this->databaseType, $device) . '\'' : '') . ')'`` is passed to DBConnection::exec()
    in core/Profile.php on line 404
  6. '[DB: ' . strtoupper($db) . '] ' . $querystring is passed to CAT::writeSQLAudit()
    in core/DBConnection.php on line 110
  7. $query is passed through preg_replace(), and $logtext1 is assigned
    in core/CAT.php on line 261
  8. $logtext1 is passed through preg_replace(), and $logtext is assigned
    in core/CAT.php on line 262

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In 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...
266
        $output = ob_get_clean();
267 View Code Duplication
        if (Config::$PATHS['logdir']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
268
            $f = fopen(Config::$PATHS['logdir'] . "/audit-SQL.log", "a");
269
            fwrite($f, $output);
270
            fclose($f);
271
        } else {
272
            print $output;
273
        }
274
    }
275
276
    /**
277
     * stores the location of the root directory
278
     * @static string $root
279
     */
280
    public static $root;
281
282
    /**
283
     * language display name for the language set by the constructor
284
     */
285
    public static $locale;
286
287
}