Skip to content

Piero Bosio Social Web Site Personale Logo Fediverso

Social Forum federato con il resto del mondo. Non contano le istanze, contano le persone

Returning objects in a collection vs. IDs

Technical Discussion
27 6 124
  • @grishka I am developing a client application where this is a real concern.
    But I agree that in general, originating servers are responsible for verification of client data. This part of FEP-fe34 will likely be revised in the future.

    @silverpill do you mean that the "malicious" attachment is not a facsimile of an actual note produced by that actor, but a forgery?

    In these cases, I'll agree with
    @grishka that some validation based on the ID should be necessary.

    For embedded object attachments on the other hand (like mastodon produces), probably the validation needs to check that attributedTo corresponds to the one of the parent object or missing.

    Interesting corner case.

    @technical-discussion

  • @silverpill do you mean that the "malicious" attachment is not a facsimile of an actual note produced by that actor, but a forgery?

    In these cases, I'll agree with
    @grishka that some validation based on the ID should be necessary.

    For embedded object attachments on the other hand (like mastodon produces), probably the validation needs to check that attributedTo corresponds to the one of the parent object or missing.

    Interesting corner case.

    @technical-discussion

    @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

  • @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

    > - Recipient: trust embedded object only if the wrapping object has the same owner.

    @silverpill no, dereference object and use that instead. The canonical version of an object is the one retrieved from the originating service.

    Mastodon has popularised this behaviour where embedding collections (like your replies) is done by servers in the name of "optimizing" for request counts. But this introduces issues and personally I think it's a "code smell" for ActivityPub. Embedding should be restricted to anonymous objects. When an ID exists it should be used most of the time.

    @technical-discussion @julian @grishka

  • > - Recipient: trust embedded object only if the wrapping object has the same owner.

    @silverpill no, dereference object and use that instead. The canonical version of an object is the one retrieved from the originating service.

    Mastodon has popularised this behaviour where embedding collections (like your replies) is done by servers in the name of "optimizing" for request counts. But this introduces issues and personally I think it's a "code smell" for ActivityPub. Embedding should be restricted to anonymous objects. When an ID exists it should be used most of the time.

    @technical-discussion @julian @grishka

    mariusor@metalhead.club silverpill@mitra.social C2S brings with it a whole other rat's nest of security concerns.

    In an S2S context same origin content ought to be trusted as having been verified. I'd argue a server blindly reflecting received AP content is a vulnerability.

  • @julian I'm not sure what "blindly reflecting" means, but it's at most as vulnerable as using iframes and way less than trusting CDN scripts.

    The way GoActivityPub uses C2S is through clients that validate and sanitize content that they serve back to users, or store in a persistence layer.

    Personally I don't understand why it would make it different than S2S?

    Are you thinking about C2S from a JavaScript client perspective only?

    @silverpill

  • > - Recipient: trust embedded object only if the wrapping object has the same owner.

    @silverpill no, dereference object and use that instead. The canonical version of an object is the one retrieved from the originating service.

    Mastodon has popularised this behaviour where embedding collections (like your replies) is done by servers in the name of "optimizing" for request counts. But this introduces issues and personally I think it's a "code smell" for ActivityPub. Embedding should be restricted to anonymous objects. When an ID exists it should be used most of the time.

    @technical-discussion @julian @grishka

    @mariusor This is basically what my FEP currently recommends: you can trust embedded anonymous objects, fragments and object of Create. Everything else should be authenticated using a different method (e.g. fetched from origin).

    @julian @grishka

  • @mariusor This is basically what my FEP currently recommends: you can trust embedded anonymous objects, fragments and object of Create. Everything else should be authenticated using a different method (e.g. fetched from origin).

    @julian @grishka

    @silverpill oh, I see. I must have missed the context for the discussion, sorry. :)

    @technical-discussion @julian @grishka


Gli ultimi otto messaggi ricevuti dalla Federazione
Post suggeriti
  • 0 Votes
    3 Posts
    7 Views
    @Helge I suppose it's my own stupid fault for trying to actually follow the spec, rather than just pointing to it as an excuse for any interoperability problems. ;)
  • 0 Votes
    1 Posts
    9 Views
    BadgeFed Unconference Participant – FediForum June 2025 The verified Badge was issued to @Anca Mosoiu This badge recognizes active participation in the BadgeFed Unconference session held during FediForum's June 2025 event. BadgeFed is an initiative dedicated to exploring and advancing decentralized digital credentials within the Fediverse. This session brought together innovators, educators, enthusiasts, curious raccoons, and technologists to collaboratively shape the future of open badges and verifiable credentials in decentralized networks. Earning Criteria: To earn this badge, participants must have: * Attended the BadgeFed Unconference session at FediForum June 2025. * Actively engaging by asking questions, commenting, leading discussions, or engaging meaningfully in collaborative activities. * Demonstrated a commitment to advancing decentralized credentialing systems within the open social web.. Issued on: 06/07/2025 15:44:41 Accepted On: 06/07/2025 20:12:41 Verify the Badge here. #badgefed #openbadges #fediforum #fediverse #activitypub #IssuedByBadgeFed #_BadgeDrop
  • 0 Votes
    5 Posts
    17 Views
    @fox @Edent I have four I2P instances in my peer list. At least two of them are still active.
  • 0 Votes
    1 Posts
    13 Views
    Apologies in advance if I misrepresented anybody or missed any crucial bits of information. Jesse Karmani (jesseplusplus@mastodon.social), Ted Thibodeau Jr. (tallted@mastodon.social, and Julian Lam (julian@activitypub.space) in attendance Julian provided an update on adoption of FEP 7888 Both Piefed and Lemmy have adopted 7888, and will begin publishing resolvable context collections in their next release Jesse opened a PR to Mastodon, which received preliminary approval from Gargron@mastodon.social (ed. it was later merged, rolled back, updated, a new PR opened, which was then merged) This PR is the first of two planned pull requests. The first generates the outgoing context (the same as what Lemmy/Piefed have done recently) The seconds handles incoming contexts and backfills Jesse was asked whether it would conflict with existing reply-tree crawling methods, but the two are complementary. She expects additional discussion before the PR is opened. Julian noted that it would be helpful if statistics/analytics were gathered by the Mastodon team to see how conversation contexts and backfill works at scale; admits that existing implementations and testing has been small scale and may not reflect real-world usage. Julian noted that Lemmy's implementation (nutomic@lemmy.ml) does not paginate their resolvable context implementation. All objects are listed in one OrderedCollection Jesse noted that she followed Mastodon's pagination convention for collections. Context inheritance Julian asked for opinions on whether contexts were inherited in existing implementations. Notes that NodeBB inherits parent context, but checks further up the known parent chain for further contexts Julian admits that not everybody can and should do this, is also not sure anymore whether NodeBB actually does this. Julian notes the ideal implementation would be every object referencing their immediate parent, which would lead to the entire collection referring to the same context collection. Jesse: Decodon inherits immediate parent context only Ted: notes that this is a reinvention of inReplyTo Julian and Jesse note that there are marked differences between crawling the reply chain. A short discussion about how netnews and usenet handled reply chains was had. Julian notes that Lemmy will not inherit context. Every object will point back to its own server's context collection. This was a conscious decision by Nutomic as each instance is meant to consider its own representation of remote content as the canonical representation ActivityPub.Space Julian made a short shout-out to a new site called ActivityPub.Space, meant to be a hub for AP development discussions ("A federated space for ActivityPub discussions so that they don’t just get lost in ephemeral replies") A short double-back to NNTP and how they approach "eventual consistency" Ted: “Cloud of NNTP servers are all hosts of articles and replies.” Strictly speaking it’s not a reply tree as replies can be inReplyTo multiple parents