Issues (234)

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.

Tests/Schema/IntrospectionTest.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
2
/*
3
* This file is a part of GraphQL project.
4
*
5
* @author Alexandr Viniychuk <[email protected]>
6
* created: 5/15/16 7:52 AM
7
*/
8
9
namespace Youshido\Tests\Schema;
10
11
12
use Youshido\GraphQL\Directive\Directive;
13
use Youshido\GraphQL\Directive\DirectiveLocation;
14
use Youshido\GraphQL\Execution\Processor;
15
use Youshido\GraphQL\Field\Field;
16
use Youshido\GraphQL\Field\InputField;
17
use Youshido\GraphQL\Type\Enum\EnumType;
18
use Youshido\GraphQL\Type\InterfaceType\InterfaceType;
19
use Youshido\GraphQL\Type\NonNullType;
20
use Youshido\GraphQL\Type\Object\ObjectType;
21
use Youshido\GraphQL\Type\Scalar\BooleanType;
22
use Youshido\GraphQL\Type\Scalar\IntType;
23
use Youshido\GraphQL\Type\TypeMap;
24
use Youshido\GraphQL\Type\Union\UnionType;
25
use Youshido\Tests\DataProvider\TestEmptySchema;
26
use Youshido\Tests\DataProvider\TestSchema;
27
28
class IntrospectionTest extends \PHPUnit_Framework_TestCase
29
{
30
    private $introspectionQuery = <<<TEXT
31
query IntrospectionQuery {
32
                __schema {
33
                    queryType { name }
34
                    mutationType { name }
35
                    types {
36
                        ...FullType
37
                    }
38
                    directives {
39
                        name
40
                        description
41
                        locations
42
                        args {
43
                            ...InputValue
44
                        }
45
                    }
46
                }
47
            }
48
49
            fragment FullType on __Type {
50
                kind
51
                name
52
                description
53
                fields {
54
                    name
55
                    description
56
                    args {
57
                        ...InputValue
58
                    }
59
                    type {
60
                        ...TypeRef
61
                    }
62
                    isDeprecated
63
                    deprecationReason
64
                }
65
                inputFields {
66
                    ...InputValue
67
                }
68
                interfaces {
69
                    ...TypeRef
70
                }
71
                enumValues {
72
                    name
73
                    description
74
                    isDeprecated
75
                    deprecationReason
76
                }
77
                possibleTypes {
78
                    ...TypeRef
79
                }
80
            }
81
82
            fragment InputValue on __InputValue {
83
                name
84
                description
85
                type { ...TypeRef }
86
                defaultValue
87
            }
88
89
            fragment TypeRef on __Type {
90
                kind
91
                name
92
                ofType {
93
                    kind
94
                    name
95
                    ofType {
96
                        kind
97
                        name
98
                        ofType {
99
                            kind
100
                            name
101
                        }
102
                    }
103
                }
104
            }
105
TEXT;
106
107
108
    public function testIntrospectionDirectiveRequest()
109
    {
110
        $processor = new Processor(new TestSchema());
111
112
        $processor->processPayload($this->introspectionQuery, []);
113
114
        $this->assertTrue(is_array($processor->getResponseData()));
115
    }
116
117
    /**
118
     * @param $query
119
     * @param $expectedResponse
120
     *
121
     * @dataProvider predefinedSchemaProvider
122
     */
123
    public function testPredefinedQueries($query, $expectedResponse)
124
    {
125
        $schema = new TestEmptySchema();
126
        $schema->addQueryField(new Field([
127
            'name'              => 'latest',
128
            'type'              => new ObjectType([
129
                'name'   => 'LatestType',
130
                'fields' => [
131
                    'id'   => ['type' => TypeMap::TYPE_INT],
132
                    'name' => ['type' => TypeMap::TYPE_STRING]
133
                ],
134
            ]),
135
            'args'              => [
136
                'id' => ['type' => TypeMap::TYPE_INT, 'defaultValue' => 'test'],
137
                'id2' => ['type' => TypeMap::TYPE_INT]
138
            ],
139
            'description'       => 'latest description',
140
            'deprecationReason' => 'for test',
141
            'isDeprecated'      => true,
142
            'resolve'           => function () {
143
                return [
144
                    'id'   => 1,
145
                    'name' => 'Alex'
146
                ];
147
            }
148
        ]));
149
150
        $processor = new Processor($schema);
151
152
        $processor->processPayload($query);
153
        $responseData = $processor->getResponseData();
154
155
        $this->assertEquals($expectedResponse, $responseData);
156
    }
157
158
    public function predefinedSchemaProvider()
159
    {
160
        return [
161
            [
162
                '{ __type { name } }',
163
                [
164
                    'data'   => ['__type' => null],
165
                    'errors' => [['message' => 'Require "name" arguments to query "__type"']]
166
                ]
167
            ],
168
            [
169
                '{ __type (name: "__Type") { name } }',
170
                [
171
                    'data' => [
172
                        '__type' => ['name' => '__Type']
173
                    ]
174
                ]
175
            ],
176
            [
177
                '{ __type (name: "InvalidName") { name } }',
178
                [
179
                    'data' => [
180
                        '__type' => null
181
                    ]
182
                ]
183
            ],
184
            [
185
                '{
186
                    __schema {
187
                        types {
188
                            name,
189
                            fields (includeDeprecated: true) {
190
                                name
191
                                args {
192
                                    defaultValue
193
                                }
194
                            }
195
                        }
196
                    }
197
                }',
198
                [
199
                    'data' => [
200
                        '__schema' => [
201
                            'types' => [
202
                                ['name' => 'TestSchemaQuery', 'fields' => [['name' => 'latest', 'args' => [['defaultValue' => 'test'], ['defaultValue' => null]]]]],
203
                                ['name' => 'Int', 'fields' => null],
204
                                ['name' => 'LatestType', 'fields' => [['name' => 'id', 'args' => []], ['name' => 'name', 'args' => []]]],
205
                                ['name' => 'String', 'fields' => null],
206
                                ['name' => '__Schema', 'fields' => [['name' => 'queryType', 'args' => []], ['name' => 'mutationType', 'args' => []], ['name' => 'subscriptionType', 'args' => []], ['name' => 'types', 'args' => []], ['name' => 'directives', 'args' => []]]],
207
                                ['name' => '__Type', 'fields' => [['name' => 'name', 'args' => []], ['name' => 'kind', 'args' => []], ['name' => 'description', 'args' => []], ['name' => 'ofType', 'args' => []], ['name' => 'inputFields', 'args' => []], ['name' => 'enumValues', 'args' => [['defaultValue' => 'false']]], ['name' => 'fields', 'args' => [['defaultValue' => 'false']]], ['name' => 'interfaces', 'args' => []], ['name' => 'possibleTypes', 'args' => []]]],
208
                                ['name' => '__InputValue', 'fields' => [['name' => 'name', 'args' => []], ['name' => 'description', 'args' => []], ['name' => 'isDeprecated', 'args' => []], ['name' => 'deprecationReason', 'args' => []], ['name' => 'type', 'args' => []], ['name' => 'defaultValue', 'args' => []],]],
209
                                ['name' => 'Boolean', 'fields' => null],
210
                                ['name' => '__EnumValue', 'fields' => [['name' => 'name', 'args' => []], ['name' => 'description', 'args' => []], ['name' => 'deprecationReason', 'args' => []], ['name' => 'isDeprecated', 'args' => []],]],
211
                                ['name' => '__Field', 'fields' => [['name' => 'name', 'args' => []], ['name' => 'description', 'args' => []], ['name' => 'isDeprecated', 'args' => []], ['name' => 'deprecationReason', 'args' => []], ['name' => 'type', 'args' => []], ['name' => 'args', 'args' => []]]],
212
                                ['name' => '__Directive', 'fields' => [['name' => 'name', 'args' => []], ['name' => 'description', 'args' => []], ['name' => 'args', 'args' => []], ['name' => 'locations', 'args' => []]]],
213
                                ['name' => '__DirectiveLocation', 'fields' => null],
214
                            ]
215
                        ]
216
                    ]
217
                ]
218
            ],
219
            [
220
                '{
221
                  test : __schema {
222
                    queryType {
223
                      kind,
224
                      name,
225
                      fields (includeDeprecated: true) {
226
                        name,
227
                        isDeprecated,
228
                        deprecationReason,
229
                        description,
230
                        type {
231
                          name
232
                        }
233
                      }
234
                    }
235
                  }
236
                }',
237
                ['data' => [
238
                    'test' => [
239
                        'queryType' => [
240
                            'name'   => 'TestSchemaQuery',
241
                            'kind'   => 'OBJECT',
242
                            'fields' => [
243
                                ['name' => 'latest', 'isDeprecated' => true, 'deprecationReason' => 'for test', 'description' => 'latest description', 'type' => ['name' => 'LatestType']]
244
                            ]
245
                        ]
246
                    ]
247
                ]]
248
            ],
249
            [
250
                '{
251
                  __schema {
252
                    queryType {
253
                      kind,
254
                      name,
255
                      description,
256
                      interfaces {
257
                        name
258
                      },
259
                      possibleTypes {
260
                        name
261
                      },
262
                      inputFields {
263
                        name
264
                      },
265
                      ofType{
266
                        name
267
                      }
268
                    }
269
                  }
270
                }',
271
                ['data' => [
272
                    '__schema' => [
273
                        'queryType' => [
274
                            'kind'          => 'OBJECT',
275
                            'name'          => 'TestSchemaQuery',
276
                            'description'   => null,
277
                            'interfaces'    => [],
278
                            'possibleTypes' => null,
279
                            'inputFields'   => null,
280
                            'ofType'        => null
281
                        ]
282
                    ]
283
                ]]
284
            ]
285
        ];
286
    }
287
288
    public function testCombinedFields()
289
    {
290
        $schema = new TestEmptySchema();
291
292
        $interface = new InterfaceType([
293
            'name'        => 'TestInterface',
294
            'fields'      => [
295
                'id'   => ['type' => new IntType()],
296
                'name' => ['type' => new IntType()],
297
            ],
298
            'resolveType' => function ($type) {
0 ignored issues
show
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
299
300
            }
301
        ]);
302
303
        $object1 = new ObjectType([
304
            'name'       => 'Test1',
305
            'fields'     => [
306
                'id'       => ['type' => new IntType()],
307
                'name'     => ['type' => new IntType()],
308
                'lastName' => ['type' => new IntType()],
309
            ],
310
            'interfaces' => [$interface]
311
        ]);
312
313
        $object2 = new ObjectType([
314
            'name'       => 'Test2',
315
            'fields'     => [
316
                'id'        => ['type' => new IntType()],
317
                'name'      => ['type' => new IntType()],
318
                'thirdName' => ['type' => new IntType()],
319
            ],
320
            'interfaces' => [$interface]
321
        ]);
322
323
        $unionType = new UnionType([
324
            'name'        => 'UnionType',
325
            'types'       => [$object1, $object2],
326
            'resolveType' => function () {
327
328
            }
329
        ]);
330
331
        $schema->addQueryField(new Field([
332
            'name'    => 'union',
333
            'type'    => $unionType,
334
            'args'    => [
335
                'id' => ['type' => TypeMap::TYPE_INT]
336
            ],
337
            'resolve' => function () {
338
                return [
339
                    'id'   => 1,
340
                    'name' => 'Alex'
341
                ];
342
            }
343
        ]));
344
345
        $schema->addMutationField(new Field([
346
            'name'    => 'mutation',
347
            'type'    => $unionType,
348
            'args'    => [
349
                'type' => new EnumType([
350
                    'name'   => 'MutationType',
351
                    'values' => [
352
                        [
353
                            'name'  => 'Type1',
354
                            'value' => 'type_1'
355
                        ],
356
                        [
357
                            'name'  => 'Type2',
358
                            'value' => 'type_2'
359
                        ]
360
                    ]
361
                ])
362
            ],
363
            'resolve' => function () {
364
                return null;
365
            }
366
        ]));
367
368
        $processor = new Processor($schema);
369
370
        $processor->processPayload($this->introspectionQuery);
371
        $responseData = $processor->getResponseData();
372
373
        /** strange that this test got broken after I fixed the field resolve behavior */
374
        $this->assertArrayNotHasKey('errors', $responseData);
375
    }
376
377
    public function testCanIntrospectDirectives()
378
    {
379
        $schema = new TestSchema();
380
        $schema->getDirectiveList()->addDirectives([
381
            new Directive([
382
                'name' => 'skip',
383
                'args' => [
384
                    new InputField([
385
                        'name' => 'if',
386
                        'type' => new NonNullType(new BooleanType()),
387
                        'description' => 'Skipped when true.',
388
                    ])
389
                ],
390
                'description' => 'skip',
391
                'locations' => [
392
                    DirectiveLocation::FIELD,
393
                    DirectiveLocation::FRAGMENT_SPREAD,
394
                    DirectiveLocation::INLINE_FRAGMENT
395
                ]
396
            ]),
397
            new Directive([
398
                'name' => 'include',
399
                'args' => [
400
                    new InputField([
401
                        'name' => 'if',
402
                        'type' => new NonNullType(new BooleanType()),
403
                        'description' => 'Included when true.',
404
                    ])
405
                ],
406
                'description' => 'include',
407
                'locations' => [
408
                    DirectiveLocation::FIELD,
409
                    DirectiveLocation::FRAGMENT_SPREAD,
410
                    DirectiveLocation::INLINE_FRAGMENT
411
                ]
412
            ]),
413
            new Directive([
414
                'name' => 'deprecated',
415
                'args' => [
416
                    new InputField([
417
                        'name' => 'reason',
418
                        'type' => 'string',
419
                        'description' => 'Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted in [Markdown](https://daringfireball.net/projects/markdown/).',
420
                    ])
421
                ],
422
                'description' => 'deprecated',
423
                'locations' => [
424
                    DirectiveLocation::FIELD_DEFINITION,
425
                    DirectiveLocation::ENUM_VALUE
426
                ]
427
            ])
428
        ]);
429
        $processor = new Processor($schema);
430
431
        $processor->processPayload($this->introspectionQuery);
432
        $responseData = $processor->getResponseData();
433
        $this->assertArrayNotHasKey('errors', $responseData);
434
    }
435
436
}
437