What Spring Data can teach us about API misconfiguration
A security researcher (Joel Noguera @niemand_sec) discovered a 'critical' misconfiguration bug in Spring Data’s Application Level Profile Semantics (ALPS). This bug allows unauthenticated users to perform an Application Programming Interface (API) request, which responds with sensitive user data that can be utilized, manipulated, or even deleted.
What is ALPS?
"ALPS [is] a data format for defining simple descriptions of application-level semantics, similar in complexity to HTML microformats. An ALPS document can be used as a profile to explain the application semantics of a document with an application-agnostic media type (such as HTML, HAL, Collection+JSON, Siren, etc.). This increases the reusability of profile documents across media types."
— https://tools.ietf.org/html/draft-amundsen-richardson-foster-alps-00
To put it simply, ALPS can be compared to other API definitions such as Swagger.
The main issue with this bug is that Spring Data REST allows developers to set up @Pre and @Post Security Conditions; however, these are not required to perform the queries. Without these permissions in place, unauthenticated users can perform requests that should be protected with authorization mechanisms.
In the Wild: API Authorization Bug
When using Spring Data ALPS, all user profiles can be discovered at this URL:
http://domain.com/alps/profile/users
However, in order to access the JSON schema of the user profiles, a GET Request must be sent with this header:
Accept: application/schema+json
Luckily, this is detailed in Spring Data's documentation: https://docs.spring.io/spring-data/rest/docs/current/reference/html/#metadata.json-schema
When issuing an unauthenticated GET request to retrieve user data, the following data will be returned:
curl -H 'Accept:application/schema+json' -v http://domain.com/alps/profile/users
< HTTP/1.1 200 OK
< Content-Type: application/hal+json
{
"title" : "User type",
"properties" : {
"name" : "company",
"type" : "SEMANTIC"
}, {
"name" : "nickname",
"type" : "SEMANTIC"
},
"definitions" : { },
"type" : "object",
"$schema" : "http://json-schema.org/draft-04/schema#"
}
And by removing the /profiles/ section of the URL we can access all user data at:
This is somewhat restricted with a size parameter, which is set to 50 by default. If this parameter is added into the URL, the size can be increased to essentially dump all available user data:
https://domain.com/alps/users?size=500000
Individual User Profiles can also be accessed at:
http://domain.com/alps/users/<USERID>
At this point, POST and PUT methods can be used to insert new entries, PATCH can be used to modify existing instances, and DELETE can be used to delete existing entries.
In a typical application, accessing these endpoints would be restricted to specific roles such as administrator. The key to protecting sensitive API endpoints is implementing solid authentication and authorization to prevent regular, or in this case, unauthenticated, users from accessing sensitive data.
Protection Mechanisms
In this case, Spring Security has multiple solid mechanisms in place that, when implemented, would prevent this misconfiguration vulnerability from existing.
Spring Security PreAuthorization Model
https://docs.spring.io/spring-data/rest/docs/current/reference/html/#security
Spring Security SpEL Expressions
https://docs.spring.io/spring-security/site/docs/current/reference/html5/#el-common-built-in
Disable HTTP METHODS Server Side