Private fields
Description
According to the rules provided in the configuration file, objects
and object fields
can be accessed by unauthorized users.
Remediation
When accessing the application through GraphQL, it is important to validate whether or not the user is given access to the requested elements from the schema. Access control policies must therefore be implemented on every path of the Graph leading to the given field or object.
The authorization logic belongs to the business logic layer, and from there it is accessed by GraphQL. This way, the application can have a single source of truth for authorization, which can then be used for other access points.
Among the several access control policies that can be implemented in an application, the two most popular ones are Role-Based Access Control (RBAC) and Attribute-Based Access Control (ABAC). - With Role-Based Access Control, permissions are granted based on roles which are later assigned to the users. For instance, WordPress has an administrator
role with access to all resources, and the editor
, author
, contributor
, and subscriber
roles which each restrict permissions in various degrees, such as being able to create and publish a blog post, just create it, or simply read it. - With Attribute-Based Access Control, permissions are granted based on metadata that can be assigned to different entities including users, assets, or environment conditions (the time of the day or the visitor's IP address for example). In the WordPress example, the capability edit_others_posts
is used to validate whether or not the user can edit other users' posts.
For most use cases, ABAC is preferable to RBAC as it allows for finely tuned permissions with explicit goals.
GraphQL Specific
Apollo
Yoga
Awsappsync
Graphqlgo
Graphqlruby
Hasura
REST Specific
Asp_net
Ruby_on_rails
Next_js
Laravel
Express_js
Django
Symfony
Spring_boot
Flask
Nuxt
Fastapi
Configuration
Identifier:
access_control/private_fields
Options
- empty_values_are_positive : When the API returns a None value without error is the field considered to be successfully accessed ?
Parameters
__user : (For Graphql) An object {objectName:[fieldName]}
represting object fields that the user is not supposed to have access to.
rules : (For REST) The list of private fields rules to check during a scan.
Examples
GraphQL: Accessiblity of private objects in a GraphQL API for not authenticated users.
{
"auth": {
"public": { #
"tech": "public" # Default value on a new application
}, #
... REDACTED AUTH ...
},
"users": {
"public": { #
"auth": "public" # Default value on a new application
}, #
"exampleUser": {
... REDACTED AUTH ...
}
}
... Other configuration settings ...
"checks": {
... Other checks ...
"access_control/private_fields": {
"public": { <--- Triggering on a "users" object key
"Query": [ <--- Object name
"getUsersById", <--- Field name
"getAllUsers" # Here, the public user is not supposed to
# have access to the "getUsersById" and "getAllUsers" queries.
],
"Mutation": [
...
],
"User": [ docs
"id" # Here, the public user is not supposed to
# have access to the "id" field of the "User" object
]
}
}
... Other checks ...
}
... Other configuration settings ...
}
REST: Ensure user some-user
cannot access the routes GET /admin
and PUT /user/role/{roleId}
{
"auth": { #
... REDACTED AUTH ...
},
"users": {
... Other users ...
"some-user": { # User to check
... REDACTED AUTH ...
}
... Other users ...
}
... Other configuration settings ...
"checks": {
... Other checks ...
"AccessControl_PrivateFields": {
"parameters": {
"rules": [
"user": "some-user",
"routes": [
{
"method": "GET",
"path": "/admin"
},
{
"method": "GET",
"path": "/admin/.*" # Regex are supported
},
{
"method": "PUT",
"path": "/user/role/{roleId}"
}
]
]
}
}
... Other checks ...
}
... Other configuration settings ...
}
REST: Ensure user some-user
cannot access the fields email
and credentials.apiKey
route GET /admin
{
"auth": { #
... REDACTED AUTH ...
},
"users": {
... Other users ...
"some-user": { # User to check
... REDACTED AUTH ...
}
... Other users ...
}
... Other configuration settings ...
"checks": {
... Other checks ...
"AccessControl_PrivateFields": {
"parameters": {
"rules": [
"user": "some-user",
"routes": [
{
"method": "GET",
"path": "/admin",
"fields": [
"email",
"credentials.apiKey"
]
}
]
]
}
}
... Other checks ...
}
... Other configuration settings ...
}
REST: Ensure user some-user
cannot access a field admin-*
on route GET /admin
{
"auth": { #
... REDACTED AUTH ...
},
"users": {
... Other users ...
"some-user": { # User to check
... REDACTED AUTH ...
}
... Other users ...
}
... Other configuration settings ...
"checks": {
... Other checks ...
"AccessControl_PrivateFields": {
"parameters": {
"rules": [
"user": "some-user",
"routes": [
{
"method": "GET",
"path": "/admin",
"fields": [
"admin-*",
]
}
]
]
}
}
... Other checks ...
}
... Other configuration settings ...
}
Ignore this check
checks:
access_control/private_fields:
skip: true
Score
- Escape Severity: HIGH
Compliance
OWASP: API1:2023
pci: 7.1
gdpr: Article-32
soc2: CC1
psd2: Article-95
iso27001: A.18.1
nist: SP800-53
fedramp: AC-6
Classification
- CWE: 284
Score
- CVSS_VECTOR: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N/E:H/RL:O/RC:C
- CVSS_SCORE: 5.1