169 - Racing Grafana, Stealing Mastadon Passwords, and Cross-Site Tracing
Bypassing an authentication check in AWS AppSync by changing the case of a JSON key.
Its a common trick but its amazing to see it somewhere so sensitive. Within AppSync you have to create a role that the AppSync service will impersonate that gives it access to whatever it needs. The developer then creates the datasource and gives AWS the Amazon Resource Name (ARN) for the role. At that time it validates that the ARN belongs to the same AWS account, if not it won’t create the data source.
In doing this validation though when sending a JSON API request it looks for the
serviceRoleArn key. If someone were to send
servicerolearn (all lower-case) the check would be bypassed and one could add an ARN belonging to any AWS account and access the data source.
This does rely on knowing the ARN that will explicitly allow the AppSync service to impersonate it which may be a bit of an ask.
Its the description that caught my eye on this one, a race condition leading to authentication bypass.
On a new request coming in, Grafana would create a new context object for the request and assign the pointer to the server’s middleware object into the context then the request specific middleware would be
append‘d to this list. The problem being that
append isn’t thread safe and will usually modify the provided slice appending to the same memory as long as there is capacity available. So multiple threads doing this at once will all be modifying the same piece of memory.
Its a good example of a Golang specific vulnerability. Sure you have race conditions in other languages, and shared memory, but the underlying implementation of
append isn’t necessarily obvious.
Starts off with a somewhat classic parser attack,, placing a parsable object inside of another context hoping to trip up the system. In this case Gareth Heyes was able to inject
:verified: within a supported HTML attribute, and have it be replaced with the emoji as an
<img> tag. Turning:
<abbr title="<a href='https://blah'>:verified:</a><iframe src=//garethheyes.co.uk/>">
<abbr title="<a href='https://blah</a>'><img draggable=" false" ... ><iframe src=//garethheyes.co.uk/>
Its a fairly classic trick, however full cross-site scripting could not be achieved here due to the strict content-security-policy. Instead he opted to go for an HTML injection attack, and abused the autofill functionality of the Chrome password manager to fill in hidden form fields that could be submitted upon interaction with the injected HTML.
Cross-Site Tracing is a vulnerability I didn’t think I’d be hearing about again, yet here we are.
If you’re not familiar with Cross-Site Tracing, it is an old technique to expose
TRACE is an HTTP verb that is bodyless (like
GET) and the response body should just echo the received headers back. It is allowed to do some modification to hide sensitive data from the response but in practice that rarely happens. So sending a
Firefox and other browsers already forbid certain HTTP verbs from being used in all situations,
TRACE is one of those verbs. However some servers support non-standard headers that will override the verb of the request, potentially transforming a “safe”
GET request that is allowed by the browser into a
TRACE request. Mozilla products have started blocking the use of
x-method-override with a value that could be interpreted as
TRACE (or other forbidden verbs).