Issues (5)

Security Analysis    not enabled

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/Http/JsonApiTrait.php (1 issue)

Severity

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 namespace Neomerx\Limoncello\Http;
2
3
/**
4
 * Copyright 2015 [email protected] (www.neomerx.com)
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use \Neomerx\Limoncello\Config\Config as C;
20
use \Symfony\Component\HttpFoundation\Response;
21
use \Neomerx\Limoncello\Contracts\IntegrationInterface;
22
use \Neomerx\JsonApi\Contracts\Schema\ContainerInterface;
23
use \Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
24
use \Neomerx\JsonApi\Contracts\Codec\CodecMatcherInterface;
25
use \Neomerx\JsonApi\Contracts\Responses\ResponsesInterface;
26
use \Neomerx\JsonApi\Contracts\Parameters\ParametersInterface;
27
use \Neomerx\JsonApi\Contracts\Parameters\ParametersParserInterface;
28
use \Neomerx\JsonApi\Contracts\Parameters\ParametersCheckerInterface;
29
use \Neomerx\JsonApi\Contracts\Integration\ExceptionThrowerInterface;
30
use \Neomerx\JsonApi\Contracts\Parameters\Headers\MediaTypeInterface;
31
use \Neomerx\JsonApi\Contracts\Parameters\SupportedExtensionsInterface;
32
33
/**
34
 * @package Neomerx\Limoncello
35
 */
36
trait JsonApiTrait
37
{
38
    /**
39
     * If unrecognized parameters should be allowed in input parameters.
40
     *
41
     * @var bool
42
     */
43
    protected $allowUnrecognizedParams = false;
44
45
    /**
46
     * A list of allowed include paths in input parameters.
47
     *
48
     * Empty array [] means clients are not allowed to specify include paths and 'null' means all paths are allowed.
49
     *
50
     * @var string[]|null
51
     */
52
    protected $allowedIncludePaths = [];
53
54
    /**
55
     * A list of JSON API types which clients can sent field sets to.
56
     *
57
     * Possible values
58
     *
59
     * $allowedFieldSetTypes = null; // <-- for all types all fields are allowed
60
     *
61
     * $allowedFieldSetTypes = []; // <-- non of the types and fields are allowed
62
     *
63
     * $allowedFieldSetTypes = [
64
     *      'people'   => null,              // <-- all fields for 'people' are allowed
65
     *      'comments' => [],                // <-- no fields for 'comments' are allowed (all denied)
66
     *      'posts'    => ['title', 'body'], // <-- only 'title' and 'body' fields are allowed for 'posts'
67
     * ];
68
     *
69
     * @var array|null
70
     */
71
    protected $allowedFieldSetTypes = null;
72
73
    /**
74
     * A list of allowed sort field names in input parameters.
75
     *
76
     * Empty array [] means clients are not allowed to specify sort fields and 'null' means all fields are allowed.
77
     *
78
     * @var string[]|null
79
     */
80
    protected $allowedSortFields = [];
81
82
    /**
83
     * A list of allowed pagination input parameters (e.g 'number', 'size', 'offset' and etc).
84
     *
85
     * Empty array [] means clients are not allowed to specify paging and 'null' means all parameters are allowed.
86
     *
87
     * @var string[]|null
88
     */
89
    protected $allowedPagingParameters = [];
90
91
    /**
92
     * A list of allowed filtering input parameters.
93
     *
94
     * Empty array [] means clients are not allowed to specify filtering and 'null' means all parameters are allowed.
95
     *
96
     * @var string[]|null
97
     */
98
    protected $allowedFilteringParameters = [];
99
100
    /**
101
     * JSON API extensions supported by this controller (comma separated).
102
     *
103
     * @var string
104
     */
105
    protected $extensions = MediaTypeInterface::NO_EXT;
106
107
    /**
108
     * If JSON API extension should be allowed.
109
     *
110
     * @var bool
111
     */
112
    protected $allowExtensionsSupport = false;
113
114
    /**
115
     * @var IntegrationInterface
116
     */
117
    private $integration;
118
119
    /**
120
     * @var CodecMatcherInterface
121
     */
122
    private $codecMatcher;
123
124
    /**
125
     * @var ParametersParserInterface
126
     */
127
    private $parametersParser;
128
129
    /**
130
     * @var ParametersCheckerInterface
131
     */
132
    private $parametersChecker;
133
134
    /**
135
     * @var ExceptionThrowerInterface
136
     */
137
    private $exceptionThrower;
138
139
    /**
140
     * @var ParametersInterface
141
     */
142
    private $parameters = null;
143
144
    /**
145
     * @var bool
146
     */
147
    private $parametersChecked = false;
148
149
    /**
150
     * @var SupportedExtensionsInterface
151
     */
152
    private $supportedExtensions;
153
154
    /**
155
     * Init integrations with JSON API implementation.
156
     *
157
     * @param IntegrationInterface $integration
158
     *
159
     * @return void
160
     */
161 7
    private function initJsonApiSupport(IntegrationInterface $integration)
0 ignored issues
show
This method is not used, and could be removed.
Loading history...
162
    {
163 7
        $this->integration = $integration;
164
165
        /** @var FactoryInterface $factory */
166 7
        $factory = $this->getIntegration()->getFromContainer(FactoryInterface::class);
167
168 7
        $this->codecMatcher     = $integration->getFromContainer(CodecMatcherInterface::class);
169 7
        $this->exceptionThrower = $integration->getFromContainer(ExceptionThrowerInterface::class);
170
171 7
        $this->parametersParser    = $factory->createParametersParser();
172 7
        $this->supportedExtensions = $factory->createSupportedExtensions($this->extensions);
173 7
        $this->parametersChecker   = $factory->createParametersChecker(
174 7
            $this->exceptionThrower,
175 7
            $this->codecMatcher,
176 7
            $this->allowUnrecognizedParams,
177 7
            $this->allowedIncludePaths,
178 7
            $this->allowedFieldSetTypes,
179 7
            $this->allowedSortFields,
180 7
            $this->allowedPagingParameters,
181 7
            $this->allowedFilteringParameters
182 7
        );
183
184
        // information about extensions supported by the current controller might be used in exception handler
185 7
        $integration->setInContainer(SupportedExtensionsInterface::class, $this->supportedExtensions);
186 7
    }
187
188
    /**
189
     * @return mixed
190
     */
191 1
    protected function getDocument()
192
    {
193 1
        if ($this->codecMatcher->getDecoder() === null) {
194 1
            $this->codecMatcher->findDecoder($this->getParameters()->getContentTypeHeader());
195 1
        }
196
197 1
        $decoder = $this->codecMatcher->getDecoder();
198 1
        return $decoder->decode($this->getIntegration()->getContent());
199
    }
200
201
    /**
202
     * @return ParametersInterface
203
     */
204 6
    protected function getUncheckedParameters()
205
    {
206 6
        if ($this->parameters === null) {
207 6
            $this->parameters = $this->parametersParser->parse($this->getIntegration(), $this->exceptionThrower);
208 6
        }
209
210 6
        return $this->parameters;
211
    }
212
213
    /**
214
     * @return void
215
     */
216 6
    protected function checkParameters()
217
    {
218 6
        $this->parametersChecker->check($this->getUncheckedParameters());
219 6
        $this->parametersChecked = true;
220 6
    }
221
222
    /**
223
     * @return void
224
     */
225 1
    protected function checkParametersEmpty()
226
    {
227 1
        $this->getParameters()->isEmpty() === true ?: $this->exceptionThrower->throwBadRequest();
228 1
    }
229
230
    /**
231
     * @return ParametersInterface
232
     */
233 4
    protected function getParameters()
234
    {
235 4
        if ($this->parametersChecked === false) {
236 4
            $this->checkParameters();
237 4
        }
238
239 4
        return $this->getUncheckedParameters();
240
    }
241
242
    /**
243
     * Get response with HTTP code only.
244
     *
245
     * @param $statusCode
246
     *
247
     * @return Response
248
     */
249 1
    protected function getCodeResponse($statusCode)
250
    {
251 1
        $this->checkParameters();
252
253
        /** @var ResponsesInterface $responses */
254 1
        $responses = $this->getIntegration()->getFromContainer(ResponsesInterface::class);
255 1
        $outputMediaType = $this->codecMatcher->getEncoderRegisteredMatchedType();
256
257 1
        return $responses->getResponse($statusCode, $outputMediaType, null, $this->supportedExtensions);
258
    }
259
260
    /**
261
     * Get response with meta information only.
262
     *
263
     * @param array|object $meta       Meta information.
264
     * @param int          $statusCode
265
     *
266
     * @return Response
267
     */
268 1
    protected function getMetaResponse($meta, $statusCode = Response::HTTP_OK)
269
    {
270 1
        $this->checkParameters();
271
272
        /** @var ResponsesInterface $responses */
273 1
        $responses       = $this->getIntegration()->getFromContainer(ResponsesInterface::class);
274 1
        $encoder         = $this->codecMatcher->getEncoder();
275 1
        $outputMediaType = $this->codecMatcher->getEncoderRegisteredMatchedType();
276 1
        $content         = $encoder->encodeMeta($meta);
277
278 1
        return $responses->getResponse($statusCode, $outputMediaType, $content, $this->supportedExtensions);
279
    }
280
281
    /**
282
     * @return SupportedExtensionsInterface
283
     */
284 1
    protected function getSupportedExtensions()
285
    {
286 1
        return $this->supportedExtensions;
287
    }
288
289
    /**
290
     * Get response with regular JSON API Document in body.
291
     *
292
     * @param object|array                                                       $data
293
     * @param int                                                                $statusCode
294
     * @param array<string,\Neomerx\JsonApi\Contracts\Schema\LinkInterface>|null $links
295
     * @param mixed                                                              $meta
296
     *
297
     * @return Response
298
     */
299 1
    protected function getContentResponse(
300
        $data,
301
        $statusCode = Response::HTTP_OK,
302
        $links = null,
303
        $meta = null
304
    ) {
305 1
        $parameters      = $this->getParameters();
306 1
        $encoder         = $this->codecMatcher->getEncoder();
307 1
        $outputMediaType = $this->codecMatcher->getEncoderRegisteredMatchedType();
308
309 1
        $links === null ?: $encoder->withLinks($links);
310 1
        $meta  === null ?: $encoder->withMeta($meta);
311
312
        /** @var ResponsesInterface $responses */
313 1
        $responses = $this->getIntegration()->getFromContainer(ResponsesInterface::class);
314 1
        $content   = $encoder->encodeData($data, $parameters);
315
316 1
        return $responses->getResponse($statusCode, $outputMediaType, $content, $this->supportedExtensions);
317
    }
318
319
    /**
320
     * @param object                                                             $resource
321
     * @param array<string,\Neomerx\JsonApi\Contracts\Schema\LinkInterface>|null $links
322
     * @param mixed                                                              $meta
323
     *
324
     * @return Response
325
     */
326 1
    protected function getCreatedResponse(
327
        $resource,
328
        $links = null,
329
        $meta = null
330
    ) {
331 1
        $integration     = $this->getIntegration();
332 1
        $parameters      = $this->getParameters();
333 1
        $encoder         = $this->codecMatcher->getEncoder();
334 1
        $outputMediaType = $this->codecMatcher->getEncoderRegisteredMatchedType();
335
336 1
        $links === null ?: $encoder->withLinks($links);
337 1
        $meta  === null ?: $encoder->withMeta($meta);
338
339 1
        $content = $encoder->encodeData($resource, $parameters);
340
341
        /** @var ResponsesInterface $responses */
342 1
        $responses = $integration->getFromContainer(ResponsesInterface::class);
343
        /** @var ContainerInterface $schemaContainer */
344 1
        $schemaContainer = $integration->getFromContainer(ContainerInterface::class);
345
346 1
        $config    = $integration->getFromContainer(C::class);
347 1
        $urlPrefix = isset($config[C::JSON][C::JSON_URL_PREFIX]) === true ? $config[C::JSON][C::JSON_URL_PREFIX] : null;
348 1
        $location  = $urlPrefix . $schemaContainer->getSchema($resource)->getSelfSubLink($resource)->getSubHref();
349
350 1
        return $responses->getCreatedResponse($location, $outputMediaType, $content, $this->supportedExtensions);
351
    }
352
353
    /**
354
     * @return IntegrationInterface
355
     */
356 7
    private function getIntegration()
357
    {
358 7
        assert('$this->integration !== null', 'Haven\'t you forgotten to init integration with framework?');
359 7
        return $this->integration;
360
    }
361
}
362