Issues (13)

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/Scanners/AnnotationScanner.php (5 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
 * Scabbia2 Scanners Component
4
 * https://github.com/eserozvataf/scabbia2
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @link        https://github.com/eserozvataf/scabbia2-scanners for the canonical source repository
10
 * @copyright   2010-2016 Eser Ozvataf. (http://eser.ozvataf.com/)
11
 * @license     http://www.apache.org/licenses/LICENSE-2.0 - Apache License, Version 2.0
12
 */
13
14
namespace Scabbia\Scanners;
15
16
use Scabbia\Scanners\ScannerInterface;
17
use Scabbia\Scanners\TokenStream;
18
use LogicException;
19
use ReflectionClass;
20
21
/**
22
 * canner
23
 *
24
 * @package     Scabbia\Scanners
25
 * @author      Eser Ozvataf <[email protected]>
26
 * @since       2.0.0
27
 */
28
class AnnotationScanner implements ScannerInterface
29
{
30
    /** @type array       $result      result of scanning task */
31
    public $result = [];
32
    /** @type array       $ignoreList  annotations to be ignored */
33
    public $ignoreList = [
34
        "link",
35
        "copyright",
36
        "license",
37
        "package",
38
        "author",
39
        "since",
40
        "type",
41
        "param",
42
        "return",
43
        "throws",
44
        "todo",
45
        "see",
46
        "ignore"
47
    ];
48
49
50
    /**
51
     * Scans a file
52
     *
53
     * @param string           $uFile             file path
54
     * @param string           $uFileContents     contents of file
55
     *
56
     * @return void
57
     */
58
    public function processFile($uFile, $uFileContents)
59
    {
60
    }
61
62
    /**
63
     * Scans a token stream
64
     *
65
     * @param TokenStream      $uTokenStream      extracted tokens wrapped with tokenstream
66
     *
67
     * @return void
68
     */
69
    public function processTokenStream(TokenStream $uTokenStream)
70
    {
71
    }
72
73
    /**
74
     * Processes classes using reflection
75
     *
76
     * @param string           $uClass            class name
77
     * @param ReflectionClass  $uReflection       reflection information for the class
78
     *
79
     * @return void
80
     */
81
    public function processClass($uClass, ReflectionClass $uReflection)
82
    {
83
        $tClassAnnotations = [];
84
85
        $tDocComment = $uReflection->getDocComment();
86
        if (strlen($tDocComment) > 0) {
87
            $tParsedAnnotations = $this->parseAnnotations($tDocComment);
88
            if (count($tParsedAnnotations) > 0) {
89
                $tClassAnnotations["class"] = ["self" => $tParsedAnnotations];
90
            }
91
        }
92
93
        // methods
94 View Code Duplication
        foreach ($uReflection->getMethods() as $tMethodReflection) {
0 ignored issues
show
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...
95
            // TODO check the correctness of logic
96
            if ($tMethodReflection->class !== $uClass) {
97
                continue;
98
            }
99
100
            $tDocComment = $tMethodReflection->getDocComment();
101
            if (strlen($tDocComment) > 0) {
102
                $tParsedAnnotations = $this->parseAnnotations($tDocComment);
103
104
                if (count($tParsedAnnotations) === 0) {
0 ignored issues
show
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
105
                    // nothing
106
                } elseif ($tMethodReflection->isStatic()) {
107
                    if (!isset($tClassAnnotations["staticMethods"])) {
108
                        $tClassAnnotations["staticMethods"] = [];
109
                    }
110
111
                    $tClassAnnotations["staticMethods"][$tMethodReflection->name] = $tParsedAnnotations;
112
                } else {
113
                    if (!isset($tClassAnnotations["methods"])) {
114
                        $tClassAnnotations["methods"] = [];
115
                    }
116
117
                    $tClassAnnotations["methods"][$tMethodReflection->name] = $tParsedAnnotations;
118
                }
119
            }
120
        }
121
122
        // properties
123 View Code Duplication
        foreach ($uReflection->getProperties() as $tPropertyReflection) {
0 ignored issues
show
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...
124
            // TODO check the correctness of logic
125
            if ($tPropertyReflection->class !== $uClass) {
126
                continue;
127
            }
128
129
            $tDocComment = $tPropertyReflection->getDocComment();
130
            if (strlen($tDocComment) > 0) {
131
                $tParsedAnnotations = $this->parseAnnotations($tDocComment);
132
133
                if (count($tParsedAnnotations) === 0) {
0 ignored issues
show
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
134
                    // nothing
135
                } elseif ($tPropertyReflection->isStatic()) {
136
                    if (!isset($tClassAnnotations["staticProperties"])) {
137
                        $tClassAnnotations["staticProperties"] = [];
138
                    }
139
140
                    $tClassAnnotations["staticProperties"][$tPropertyReflection->name] = $tParsedAnnotations;
141
                } else {
142
                    if (!isset($tClassAnnotations["properties"])) {
143
                        $tClassAnnotations["properties"] = [];
144
                    }
145
146
                    $tClassAnnotations["properties"][$tPropertyReflection->name] = $tParsedAnnotations;
147
                }
148
            }
149
        }
150
151
        if (count($tClassAnnotations) > 0) {
152
            $this->result[$uClass] = $tClassAnnotations;
153
        } else {
154
            $this->result[$uClass] = null;
155
        }
156
    }
157
158
    /**
159
     * Finalizes the task
160
     *
161
     * @return void
162
     */
163
    public function finalize()
164
    {
165
    }
166
167
    /**
168
     * Parses the docblock and returns annotations in an array
169
     *
170
     * @param string $uDocComment docblock which contains annotations
171
     *
172
     * @return array set of annotations
173
     */
174
    protected function parseAnnotations($uDocComment)
175
    {
176
        preg_match_all(
177
            "/\\*[\\t| ]\\@([^\\n|\\t| ]+)(?:[\\t| ]([^\\n]+))*/",
178
            $uDocComment,
179
            $tDocCommentLines,
180
            PREG_SET_ORDER
181
        );
182
183
        $tParsedAnnotations = [];
184
185
        foreach ($tDocCommentLines as $tDocCommentLine) {
0 ignored issues
show
The expression $tDocCommentLines of type null|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
186
            if (in_array($tDocCommentLine[1], $this->ignoreList)) {
187
                continue;
188
            }
189
190
            if (!isset($tParsedAnnotations[$tDocCommentLine[1]])) {
191
                $tParsedAnnotations[$tDocCommentLine[1]] = [];
192
            }
193
194
            if (isset($tDocCommentLine[2])) {
195
                $tParsedAnnotations[$tDocCommentLine[1]][] = trim($tDocCommentLine[2]);
196
            }
197
        }
198
199
        return $tParsedAnnotations;
200
    }
201
}
202