Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent infinite relationship nesting loop #133

Closed
spawnia opened this issue Feb 20, 2018 · 7 comments
Closed

Prevent infinite relationship nesting loop #133

spawnia opened this issue Feb 20, 2018 · 7 comments

Comments

@spawnia
Copy link

spawnia commented Feb 20, 2018

All is fine if i make such a request:

this.api.get('printers', {
      include: 'paper',
    })

This works as well:

this.api.get('printers', {
      include: 'labels',
    })

And this returns 400 Bad Request:

this.api.get('printers', {
      include: 'labels,nonexistinginclude',
    })

But this causes to client to freeze, the Browsertab becomes unresponsive and i have to close it:

this.api.get('printers', {
      include: 'paper,labels',
    })

I tried sending the request from elsewhere, no problem whatsoever. Maybe Kitsu can not deal with multiple includes?

@wopian
Copy link
Owner

wopian commented Feb 20, 2018

Are you able to provide the response it's receiving? I can't replicate this issue in the demo on codepen: https://codepen.io/wopian/pen/RxmEeK

@spawnia
Copy link
Author

spawnia commented Feb 20, 2018

I put up a Mock API to test on: http://demo9418135.mockable.io/printers?include=paper,labels

I can not get codepen to call that, i tried it like this:

const printerApi = new Kitsu({
   baseURL: 'http://demo9418135.mockable.io/',
})

printerApi.get('printers', {include: 'paper,labels'})
   .then(res => {
      const pre = document.getElementsByTagName('pre')[0];
      pre.innerHTML = JSON.stringify(res, null, 2)
   })

The problem may be related to using a plural include (labels) and a singular include (paper) in the same request. paper actually refers to a resource with the type papers.

@wopian
Copy link
Owner

wopian commented Feb 20, 2018

You'd need to give it the HTTPS address (https://demo9418135.mockable.io/printers?include=paper,labels) for the request to be sent.


The response you've provided has the included papers and labels also include their own relationships. Which in this case refers to the root printers and the included papers and labels.

While this is a valid JSON:API structure, it is not a valid response for the query provided. The include=paper,labels query should only have printers' relationships resolved. The included paper and labels relationships should just contain the links (below).

{
  relationships: {
    paper: {
      links: { self: '', related: '' }
    }
  }
}

include=paper.labels,labels.paper,labels.printers would be a request that should genuinely run into this bug.

This is causing kitsu to infinitely nest the relationships into the parent printers resource, i.e:

{
  data: {
    type: 'printers',
    paper: {
      labels: [
        paper: { labels [ /* infinitely nest papers and printers */ ] },
        printers: [ { /* infinitely nest root data structure again */ } ]
      ],
    },
    labels: [
      paper: { labels [ /* infinitely nest papers and printers */ ] },
      printers: [ { /* infinitely nest root data structure again */ } ]
    ]
  }
}

Which quite quickly locks up the runtime in what's basically a DOS attack. Less of an issue in browsers as they can detect and kill the process when this happens. In node it killed my distro when added to jest's tests.

@wopian wopian changed the title Request with multiple Includes causes Client to freeze Prevent infinite relationship nesting Feb 20, 2018
@wopian wopian changed the title Prevent infinite relationship nesting Prevent infinite relationship nesting (Infinite loop) Feb 20, 2018
@wopian wopian changed the title Prevent infinite relationship nesting (Infinite loop) Prevent infinite relationship nesting (infinite loop) Feb 20, 2018
@wopian wopian changed the title Prevent infinite relationship nesting (infinite loop) Prevent infinite relationship nesting loop Feb 20, 2018
@wopian wopian added this to the 5.0.0 milestone Feb 20, 2018
@wopian wopian removed the severe label Sep 1, 2018
@nanawel
Copy link

nanawel commented Nov 15, 2019

Hi there,
is this bug being working on? I have a similar situation where relationships can sometimes create loops and it breaks the browser when the page loads (FF and Chromium).
I don't know how to fix this on the server-side because basically the structure is valid and really reflects the relationships between my entities.

@wopian wopian removed this from the 5.x.x milestone Nov 19, 2019
@wopian
Copy link
Owner

wopian commented May 7, 2020

Not being actively looked into at the moment. PRs are welcome in the meantime however.

Possible solutions

  1. Limit nesting depth. Nerfs the usability for deeply nested relationships that aren't infinitely looping.
  2. Abort when the the same relationship object is added in a relationship chain (e.g user 1 -> libraryEntry 1 -> user 1
  3. Additional parameter to Kitsu class and/or per-request to keep included relationships inside the included array.
    • Fixes the issue for those aware of the parameter
    • Package will still explode if an unaware user requests a resource that causes infinite nesting.
  4. Keep included relationships in included array and link to the relationships using Object getters in data and included[].relationshipName.data[]? with included made non-enumerable.
    • However I don't know if this would still run into the infinite relationship nesting.

@fspoettel
Copy link

Is this still an issue now after #601 landed?

@wopian
Copy link
Owner

wopian commented Nov 15, 2021

Is this still an issue now after #601 landed?

Nope, #601 should have fixed this issue and appears to have done in the circular relationship tests I've written

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants