Issues (1)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

Classes/Domrobot.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
     * Created by PhpStorm.
4
     * User: joerg
5
     * Date: 14.02.16
6
     * Time: 20:31
7
     * copied and modified from https://github.com/inwx/php-client
8
     */
9
namespace Bingemer\InwxBundle\Classes;
10
11
/**
12
 * Class Domrobot
13
 * @package Bingemer\InwxBundle\Classes
14
 */
15
class Domrobot
16
{
17
    private $debug = false;
18
    private $address;
19
    private $language;
20
    private $customer = "";
21
    private $clTRID = null;
22
23
    private $_ver = "2.4";
24
    private $_cachedir;
25
    private $_cookiefile = NULL;
26
    private $loginResult = NULL;
27
28
    /**
29
     * Domrobot constructor.
30
     * @param $address
31
     * @param string $locale
32
     * @param $cache_dir
33
     * @param $username
34
     * @param $password
35
     * @param null $sharedSecret
36
     */
37
    public function __construct($address, $locale = 'en', $cache_dir, $username, $password, $sharedSecret = null)
38
    {
39
        $this->address = (substr($address, -1) != "/") ? $address . "/" : $address;
40
        $this->_cachedir = $cache_dir;
41
        $this->_cookiefile = tempnam($this->_cachedir, 'INWX');
42
        $this->setLanguage($locale);
43
        $this->loginResult = $this->login($username, $password, $sharedSecret);
44
    }
45
46
    /**
47
     * @param string $name
48
     * @param $ip
49
     * @param string $domain
50
     * @param string $type
51
     * @param int $ttl
52
     * @return mixed|string
53
     */
54
    public function createRecord($name, $ip, $domain = 'somedomainnameyouwishtoupgrade.de', $type = 'A', $ttl = 3600)
55
    {
56
        if (strpos($name, $domain) === false) {
57
            $name = $name . "." . $domain;
58
        }
59
        try {
60
            $result = $this->call('nameserver', 'createRecord', array(
61
                'domain' => $domain,
62
                'type' => $type,
63
                'name' => $name,
64
                'content' => $ip,
65
                'ttl' => $ttl
66
            ));
67
            return $result;
68
        } catch (\Exception $e) {
69
            return $e->getMessage();
70
        }
71
    }
72
73
    /**
74
     * @param integer $id
75
     * @param $ip
76
     * @return mixed
77
     */
78
    public function updateRecord($id, $ip)
79
    {
80
        $result = $this->call('nameserver', 'updateRecord', array(
81
            'id' => $id,
82
            'content' => $ip
83
        ));
84
        return $result;
85
    }
86
87
    /**
88
     * @param integer $id
89
     * @param bool $testing
90
     * @return mixed
91
     */
92
    public function deleteRecord($id, $testing = false)
93
    {
94
        $result = $this->call('nameserver', 'deleteRecord', array(
95
            'id' => $id,
96
            'testing' => $testing
97
        ));
98
        return $result;
99
    }
100
101
    /**
102
     * @param $username
103
     * @param $password
104
     * @param null $sharedSecret
105
     * @return mixed
106
     */
107
    public function login($username, $password, $sharedSecret = null)
108
    {
109
        $fp = fopen($this->_cookiefile, "w");
110
        fclose($fp);
111
112
        $params = array();
113
        if (!empty($this->language)) {
114
            $params['lang'] = $this->language;
115
        } else {
116
            $params['lang'] = "en"; //fallback
117
        }
118
        $params['user'] = $username;
119
        $params['pass'] = $password;
120
121
        $loginRes = $this->call('account', 'login', $params);
122
        if (!empty($sharedSecret) && $loginRes['code'] == 1000 && !empty($loginRes['resData']['tfa'])) {
123
            $_tan = $this->_getSecretCode($sharedSecret);
124
            $unlockRes = $this->call('account', 'unlock', array('tan' => $_tan));
125
            if ($unlockRes['code'] == 1000) {
126
                return $loginRes;
127
            } else {
128
                return $unlockRes;
129
            }
130
        } else {
131
            return $loginRes;
132
        }
133
    }
134
135
    /**
136
     * @param string $object
137
     * @param string $method
138
     * @param array $params
139
     * @return mixed
140
     */
141
    public function call($object, $method, array $params = array())
0 ignored issues
show
call uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
142
    {
143
        if (isset($this->customer) && $this->customer != "") {
144
            $params['subuser'] = $this->customer;
145
        }
146
        if (!empty($this->clTRID)) {
147
            $params['clTRID'] = $this->clTRID;
148
        }
149
150
        $request = xmlrpc_encode_request(strtolower($object . "." . $method), $params, array("encoding" => "UTF-8", "escaping" => "markup", "verbosity" => "no_white_space"));
151
        $header = array();
152
        $header[] = "Content-Type: text/xml";
153
        $header[] = "Connection: keep-alive";
154
        $header[] = "Keep-Alive: 300";
155
        $header[] = "X-FORWARDED-FOR: " . @$_SERVER['HTTP_X_FORWARDED_FOR'];
156
        $ch = curl_init();
157
        curl_setopt($ch, CURLOPT_URL, $this->address);
158
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
159
        curl_setopt($ch, CURLOPT_TIMEOUT, 65);
160
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
161
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
162
        curl_setopt($ch, CURLOPT_COOKIEFILE, $this->_cookiefile);
163
        curl_setopt($ch, CURLOPT_COOKIEJAR, $this->_cookiefile);
164
        curl_setopt($ch, CURLOPT_POST, true);
165
        curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
166
        curl_setopt($ch, CURLOPT_USERAGENT, "DomRobot/{$this->_ver} (PHP " . phpversion() . ")");
167
        $response = curl_exec($ch);
168
        curl_close($ch);
169
        if ($this->debug) {
170
            echo "Request:\n" . $request . "\n";
171
            echo "Response:\n" . $response . "\n";
172
        }
173
        return xmlrpc_decode($response, 'UTF-8');
174
    }
175
176
    /**
177
     * @param $secret
178
     * @return string
179
     */
180
    private function _getSecretCode($secret)
181
    {
182
        $_timeSlice = floor(time() / 30);
183
        $_codeLength = 6;
184
185
        $secretKey = $this->_base32Decode($secret);
186
        // Pack time into binary string
187
        $time = chr(0) . chr(0) . chr(0) . chr(0) . pack('N*', $_timeSlice);
188
        // Hash it with users secret key
189
        $hm = hash_hmac('SHA1', $time, $secretKey, true);
190
        // Use last nipple of result as index/offset
191
        $offset = ord(substr($hm, -1)) & 0x0F;
192
        // grab 4 bytes of the result
193
        $hashPart = substr($hm, $offset, 4);
194
195
        // Unpak binary value
196
        $value = unpack('N', $hashPart);
197
        $value = $value[1];
198
        // Only 32 bits
199
        $value = $value & 0x7FFFFFFF;
200
201
        $modulo = pow(10, $_codeLength);
202
        return str_pad($value % $modulo, $_codeLength, '0', STR_PAD_LEFT);
203
    }
204
205
    /**
206
     * @param $secret
207
     * @return string|false
208
     */
209
    private function _base32Decode($secret)
210
    {
211
        if (empty($secret)) {
212
            return '';
213
        }
214
215
        $base32chars = $this->_getBase32LookupTable();
216
        $base32charsFlipped = array_flip($base32chars);
217
218
        $paddingCharCount = substr_count($secret, $base32chars[32]);
219
        $allowedValues = array(6, 4, 3, 1, 0);
220
        if (!in_array($paddingCharCount, $allowedValues)) {
221
            return false;
222
        }
223
        for ($i = 0; $i < 4; $i++) {
224
            if ($paddingCharCount == $allowedValues[$i] &&
225
                substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])
226
            ) {
227
                return false;
228
            }
229
        }
230
        $secret = str_replace('=', '', $secret);
231
        $secret = str_split($secret);
232
        $secretCount = count($secret);
233
        $binaryString = "";
234
        for ($i = 0; $i < $secretCount; $i = $i + 8) {
235
            $x = "";
236
            if (!in_array($secret[$i], $base32chars)) {
237
                return false;
238
            }
239
            for ($j = 0; $j < 8; $j++) {
240
                $x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
241
            }
242
            $eightBits = str_split($x, 8);
243
            $eightBitsCount = count($eightBits);
244
            for ($z = 0; $z < $eightBitsCount; $z++) {
245
                $binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : "";
246
            }
247
        }
248
        return $binaryString;
249
    }
250
251
    /**
252
     * @return string[]
253
     */
254
    private function _getBase32LookupTable()
255
    {
256
        return array(
257
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
258
            'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
259
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
260
            'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
261
            '=' // padding char
262
        );
263
    }
264
265
    /**
266
     *  logout on destruct
267
     */
268
    public function __destruct()
269
    {
270
        $this->logout();
271
    }
272
273
    /**
274
     * @return mixed
275
     */
276
    public function logout()
277
    {
278
        $ret = $this->call('account', 'logout');
279
        if (file_exists($this->_cookiefile)) {
280
            unlink($this->_cookiefile);
281
        }
282
        return $ret;
283
    }
284
285
    /**
286
     * @return string
287
     */
288
    public function getLanguage()
289
    {
290
        return $this->language;
291
    }
292
293
    /**
294
     * @param string $language
295
     */
296
    public function setLanguage($language)
297
    {
298
        $this->language = $language;
299
    }
300
301
    /**
302
     * @return bool
303
     */
304
    public function getDebug()
305
    {
306
        return $this->debug;
307
    }
308
309
    /**
310
     * @param bool $debug
311
     */
312
    public function setDebug($debug = false)
313
    {
314
        $this->debug = (bool)$debug;
315
    }
316
317
    /**
318
     * @return string
319
     */
320
    public function getCookiefile()
321
    {
322
        return $this->_cookiefile;
323
    }
324
325
    /**
326
     * @param $file
327
     * @throws \Exception
328
     */
329
    public function setCookiefile($file)
330
    {
331
        if ((file_exists($file) && !is_writable($file)) || (!file_exists($file) && !is_writeable(dirname($file)))) {
332
            throw new \Exception("Cannot write cookiefile: '{$this->_cookiefile}'. Please check file/folder permissions.", 2400);
333
        }
334
        $this->_cookiefile = $file;
335
    }
336
337
    /**
338
     * @return string
339
     */
340
    public function getCustomer()
341
    {
342
        return $this->customer;
343
    }
344
345
    /**
346
     * @param $customer
347
     */
348
    public function setCustomer($customer)
349
    {
350
        $this->customer = (string)$customer;
351
    }
352
353
    /**
354
     * @return string
355
     */
356
    public function getClTrId()
357
    {
358
        return $this->clTRID;
359
    }
360
361
    /**
362
     * @param $clTrId
363
     */
364
    public function setClTrId($clTrId)
365
    {
366
        $this->clTRID = (string)$clTrId;
367
    }
368
}