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 theeditor
,author
,contributor
, andsubscriber
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
See Apollo's Access Control documentation. For large scale applications, you'll want to use a specific package like GraphQL Shield for quick and easy Access Control management.
Hasura
See Hasura's detailed documentation for Authorization Management.
Awsappsync
Appsync provides several methods for protecting critical information. -To learn how to implement fine-grained access control, head over to https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#fine-grained-access-control.
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": [ <--- Object name
"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": "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
- OWASP: API1:2023
- PCI DSS: 6.5.8
- CWE
- 200
- 201
- 284
- 668
- 1198
- 1212
- 1220
- WASC: WASC-22
CVSS
- 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