Repository navigation
Description
Issues with the /collaboration/notify endpoint
We introduced a new public endpoint here that is un-documented and completely unspecified. I guess this should be reworked into something on the graph service.
Do we really need the functionality to bulk-notifiy a list of users? This provides quite some potential for abuse. If this was just a single request per notified user it should be far easier to impose rate-limits and other protection.
1. unused type field
The type field is validated as required but never read. It isn't put on the event or used for branching. The API contract forces clients to send a field that has no effect. It's documented nowhere what this field is supposed to be.
2. Requester's access to fileID is never checked, allows to send spoofed mentions
The only file-access check is that each mentioned user can Stat the file. Nothing verifies the executant has any relationship to fileID. Any user who knows/guesses a valid fileID and the userIDs of people who do have access can generate a real notification:
" mentioned you in Q3-Financials.docx" with a working
resourceLinkto the actual file.
This also means that the handler can be abused to figure out stuff like, "does user xyz have access to file abc". This could be a possible information disclosure issue.
3. No bound on userIDs, no dedup
userIDs is caller-controlled and iterated with no length cap, each iteration doing a gRPC Authenticate + Stat. A single request can fan out into a large number of gateway calls. There's also no dedup: repeating the same userID produces duplicate entries in event.UserIDs, and the downstream handleResourceMention builds recipients from that list without dedup, so a user can be emailed N times from one request. This allows to flood users with notifications.
4. A single failed recipient lookup or stat request aborts the whole notification - service.go:115-145
If any one mentioned user fails machine auth or lacks Stat access to the file, the handler returns 500 and no event is published for anyone.
5. All errors are mapped to status code 500
6 . Minor issues
-
HandleNotification()in service.go:- storagespace.ParseID(data.FileID) is called in every loop iteration, could be done outside, same is true for setting event.Ref
authResponse.Status.Code/statResponse.Status.Codeshould beGetStatus().GetCode()to avoid potential nil pointer panics
-
handleResourceMentioninservices/notification/pkg/service/resource.go:logs "could not select next gateway client" for an error fromGetServiceUserContextWithContext`.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
butonic commentedon Aug 12, 2026
In msgraph there are endpoints like /me/messages and
/chats/{id}/messagesor/teams/{id}/channels/{id}/messagesthey do not fit our mention only usecase.I found the correct endpoint: #3128 (comment)
Never mind the below.
I would propose aPOST /notifications/mentionendpoint that does not exist. Sthe like:with a response likeAlthough I don't think we should expose the delivery status.butonic commentedon Aug 14, 2026
Sorry, I finally found the right endpoint: https://learn.microsoft.com/en-us/graph/api/userteamwork-sendactivitynotification?view=graph-rest-1.0&tabs=http
{userId}in the urlThat being said, while source can also be
textthe value would then be unstructured text. WithentityUrlit MUST be a url.We can use that to point to a resource, however then we would have to parse it on the serverside to find out the actual filename so we can render a template like "{actor} mentioned you in {entity}". The ms graph API allows sending templateParameters in the request because it expects trusted clients. DO NOT ALLOW THAT! It would allow end users to impersonate other people or change the name of the file. In our case the browser directly makes the request.
The
activityType=mentionedmight be too unspecific. We actually want to say someone mentioned you in a file ... or rather a collabora session. So maybeactivityType=webofficeMentioned.I don't like it ... 👀
There is also the
teamsAppIdwhich we could use to distinguish which app mentioned the user: Collabora / EURO-Office or just the files app. Or the Maps app? The entityUrl value could then point to an app specific endpoint:But then we still have to check the url on the server side. I would prefer if we build a URL on the server side and do not trust a URL sent by the browser.
I think with
teamsAppId={some uuid for the app}+activityType=mention+topic.source=text+topic.value={cutom string}we can make this safe. For collabora we settopic.value={resourceid}. This allows us to stat the resource, check permissions and build the correct notification.The only question I have is: should the recipient open the resource directly in weboffice if he clicks it? With a fallback to the Files app if the other user already left the document? (This is another reason why a session URL in the topic.value might be bad: if the session is gone the user would get an error)
Yeah ... so, I think that covers it:
Im inclined to also allow a simple string like
webofficeormapsin theteamsAppId, but I would prefer uuids. They can be registered dynamically on the server side and are easier to maintain than dozens of apps called 'notes'.Further reading:
fschade commentedon Aug 14, 2026
@butonic, done, thanks for the hint, just for reference, theres also a bulk api available, i think its fine for now, but maybe we can make use out of it too!
https://learn.microsoft.com/en-us/graph/api/teamwork-sendactivitynotificationtorecipients?view=graph-rest-1.0&tabs=http