@mariusor Yes, a forged note. I've come up with a more realistic example:
{
"type": "Create",
"id": "https://social.example/activity/345",
"actor": "https://social.example/alice"
"object": {
"type": "Note",
"id": "https://social.example/note/123",
"attributedTo": "https://social.example/alice",
"content": "This is just a note, nothing to see here",
"replies": {
"type": "Collection",
"id": "https://social.example/note/123/replies",
"items": [{
"type": Note",
"id": "https://social.example/note/987",
"attributedTo": "https://social.example/bob",
"inReplyTo": "https://social.example/note/123",
"content": "Ha ha ha... Yes!"
}]
}
}
}
If the originating server doesn't check the embedded replies collection, a recipient that processes replies and trusts same-origin embeddings unconditionally may end up trusting the forged note.
What we can do?
- Sender: find all embedded objects with local id and reject activity if they are not known.
- Recipient: trust embedded object only if the wrapping object has the same owner.
I think the second solution is much easier to implement. It reduces the utility of embedding in the use case described by @julian, but to be honest I doubt that embedding significantly reduces the number of required HTTP requests in that case.
@grishka