Issues (28)

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.

src/Spec/Spec.php (2 issues)

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
 *
4
 * This file is part of Aura for PHP.
5
 *
6
 * @license http://opensource.org/licenses/bsd-license.php BSD
7
 *
8
 */
9
namespace Aura\Filter\Spec;
10
11
use Aura\Filter\Locator\Locator;
12
use Exception;
13
use Closure;
14
15
/**
16
 *
17
 * A generic rule specification.
18
 *
19
 * @package Aura.Filter
20
 *
21
 */
22
class Spec
23
{
24
    /**
25
     * Stop filtering on a field when a rule for that field fails.
26
     */
27
    const HARD_RULE = 'HARD_RULE';
28
29
    /**
30
     * Continue filtering on a field even when a rule for that field fails.
31
     */
32
    const SOFT_RULE = 'SOFT_RULE';
33
34
    /**
35
     * Stop filtering on all fields when a rule fails.
36
     */
37
    const STOP_RULE = 'STOP_RULE';
38
39
    /**
40
     *
41
     * The field name to be filtered.
42
     *
43
     * @var string
44
     *
45
     */
46
    protected $field;
47
48
    /**
49
     *
50
     * The rule name to be applied.
51
     *
52
     * @var string
53
     *
54
     */
55
    protected $rule;
56
57
    /**
58
     *
59
     * Arguments to pass to the rule.
60
     *
61
     * @var array
62
     *
63
     */
64
    protected $args = array();
65
66
    /**
67
     *
68
     * The message to use on failure.
69
     *
70
     * @var string
71
     *
72
     */
73
    protected $message;
74
75
    /**
76
     *
77
     * Allow the field to be blank?
78
     *
79
     * @var bool
80
     *
81
     */
82
    protected $allow_blank = false;
83
84
    /**
85
     *
86
     * The failure mode to use.
87
     *
88
     * @var string
89
     *
90
     */
91
    protected $failure_mode = self::HARD_RULE;
92
93
    /**
94
     *
95
     * The rule locator to use.
96
     *
97
     * @var Locator
98
     *
99
     */
100
    protected $locator;
101
102
    /**
103
     *
104
     * Constructor.
105
     *
106
     * @param Locator $locator The "sanitize" rules.
107
     *
108
     * @return self
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
109
     *
110
     */
111 31
    public function __construct(Locator $locator)
112
    {
113 31
        $this->locator = $locator;
114 31
    }
115
116
    /**
117
     *
118
     * Applies the rule specification to a subject.
119
     *
120
     * @param mixed $subject The filter subject.
121
     *
122
     * @return bool True on success, false on failure.
123
     *
124
     */
125 15
    public function __invoke($subject)
126
    {
127 15
        $rule = $this->locator->get($this->rule);
128 15
        $args = $this->args;
129 15
        array_unshift($args, $this->field);
130 15
        array_unshift($args, $subject);
131 15
        return call_user_func_array($rule, $args);
132
    }
133
134
    /**
135
     *
136
     * Sets the subject field name.
137
     *
138
     * @param string $field The subject field name.
139
     *
140
     * @return self
141
     *
142
     */
143 25
    public function field($field)
144
    {
145 25
        $this->field = $field;
146 25
        return $this;
147
    }
148
149
    /**
150
     *
151
     * Sets this specification as a "soft" rule.
152
     *
153
     * @param string $message The failure message.
154
     *
155
     * @return self
156
     *
157
     */
158 7
    public function asSoftRule($message = null)
159
    {
160 7
        return $this->setFailureMode(self::SOFT_RULE, $message);
161
    }
162
163
    /**
164
     *
165
     * Sets this specification as a "hard" rule.
166
     *
167
     * @param string $message The failure message.
168
     *
169
     * @return self
170
     *
171
     */
172 5
    public function asHardRule($message = null)
173
    {
174 5
        return $this->setFailureMode(self::HARD_RULE, $message);
175
    }
176
177
    /**
178
     *
179
     * Sets this specification as a "stop" rule.
180
     *
181
     * @param string $message The failure message.
182
     *
183
     * @return self
184
     *
185
     */
186 3
    public function asStopRule($message = null)
187
    {
188 3
        return $this->setFailureMode(self::STOP_RULE, $message);
189
    }
190
191
    /**
192
     *
193
     * Sets the failure mode for this rule specification.
194
     *
195
     * @param string $failure_mode The failure mode.
196
     *
197
     * @param string $message The failure message.
198
     *
199
     * @return self
200
     *
201
     */
202 8
    protected function setFailureMode($failure_mode, $message)
203
    {
204 8
        $this->failure_mode = $failure_mode;
205 8
        if ($message) {
206 2
            $this->setMessage($message);
207
        }
208 8
        return $this;
209
    }
210
211
    /**
212
     *
213
     * Sets the failure message for this rule specification.
214
     *
215
     * @param string $message The failure message.
216
     *
217
     * @return self
218
     *
219
     */
220 2
    public function setMessage($message)
221
    {
222 2
        $this->message = $message;
223 2
        return $this;
224
    }
225
226
    /**
227
     *
228
     * On failure, should the subject filter stop processing all fields?
229
     *
230
     * @return bool
231
     *
232
     */
233 9
    public function isStopRule()
234
    {
235 9
        return $this->failure_mode === self::STOP_RULE;
236
    }
237
238
    /**
239
     *
240
     * On failure, should the subject filter stop processing the current field?
241
     *
242
     * @return bool
243
     *
244
     */
245 9
    public function isHardRule()
246
    {
247 9
        return $this->failure_mode === self::HARD_RULE;
248
    }
249
250
    /**
251
     *
252
     * On failure, should the subject filter keep processing the current field?
253
     *
254
     * @return bool
255
     *
256
     */
257 2
    public function isSoftRule()
258
    {
259 2
        return $this->failure_mode === self::SOFT_RULE;
260
    }
261
262
    /**
263
     *
264
     * Returns the field name for this rule specification.
265
     *
266
     * @return string
267
     *
268
     */
269 11
    public function getField()
270
    {
271 11
        return $this->field;
272
    }
273
274
    /**
275
     *
276
     * Returns the failure message for this rule specification.
277
     *
278
     * @return string
279
     *
280
     */
281 16
    public function getMessage()
282
    {
283 16
        if (! $this->message) {
284 14
            $this->message = $this->getDefaultMessage();
285
        }
286 16
        return $this->message;
287
    }
288
289
    /**
290
     *
291
     * Returns the arguments for this rule specification.
292
     *
293
     * @return array
294
     *
295
     */
296 7
    public function getArgs()
297
    {
298 7
        return $this->args;
299
    }
300
301
    /**
302
     *
303
     * Initializes this specification.
304
     *
305
     * @param array $args Arguments for the rule.
306
     *
307
     * @return self
308
     *
309
     */
310 23
    protected function init($args)
311
    {
312 23
        $this->args = $args;
313 23
        $this->rule = array_shift($this->args);
314 23
        return $this;
315
    }
316
317
    /**
318
     *
319
     * Returns the default failure message for this rule specification.
320
     *
321
     * @return string
322
     *
323
     */
324 12
    protected function getDefaultMessage()
325
    {
326 12
        return $this->rule . $this->argsToString();
327
    }
328
329
    /**
330
     *
331
     * Converts the args to a string.
332
     *
333
     * @return string
334
     *
335
     */
336 12
    protected function argsToString()
337
    {
338 12
        if (! $this->args) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->args of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
339 6
            return '';
340
        }
341
342 11
        $vals = array();
343 11
        foreach ($this->args as $arg) {
344 11
            $vals[] = $this->argToString($arg);
345
        }
346 11
        return '(' . implode(', ', $vals) . ')';
347
    }
348
349
    /**
350
     *
351
     * Converts one arg to a string.
352
     *
353
     * @param mixed $arg The arg.
354
     *
355
     * @return string
356
     *
357
     */
358 11
    protected function argToString($arg)
359
    {
360
        switch (true) {
361 11
            case $arg instanceof Closure:
362 1
                return '*Closure*';
363 10
            case is_object($arg):
364
                return '*' . get_class($arg) . '*';
365 10
            case is_array($arg):
366
                return '*array*';
367 10
            case is_resource($arg):
368
                return '*resource*';
369 10
            case is_null($arg):
370
                return '*null*';
371
            default:
372 10
                return $arg;
373
        }
374
    }
375
376
    /**
377
     *
378
     * Is the subject field blank?
379
     *
380
     * @param mixed $subject The filter subject.
381
     *
382
     * @return bool
383
     *
384
     */
385 19
    protected function subjectFieldIsBlank($subject)
386
    {
387
        // the field name
388 19
        $field = $this->field;
389
390
        // not set, or null, means it is blank
391 19
        if (! isset($subject->$field) || $subject->$field === null) {
392 9
            return true;
393
        }
394
395
        // non-strings are not blank: int, float, object, array, resource, etc
396 17
        if (! is_string($subject->$field)) {
397 6
            return false;
398
        }
399
400
        // strings that trim down to exactly nothing are blank
401 17
        return trim($subject->$field) === '';
402
    }
403
}
404