Skip to content

Use X-Requested-With header instead of the ajax parameter#7684

Closed
Inverle wants to merge 18 commits intoFreshRSS:edgefrom
Inverle:ajax-in-headers
Closed

Use X-Requested-With header instead of the ajax parameter#7684
Inverle wants to merge 18 commits intoFreshRSS:edgefrom
Inverle:ajax-in-headers

Conversation

@Inverle
Copy link
Member

@Inverle Inverle commented Jun 22, 2025

Prevents unintended use of ajax in requests.

@Inverle
Copy link
Member Author

Inverle commented Jun 22, 2025

Problem:
Cache-Control conflicts with these changes.
When the user opens a slider, and later the page then they get the slider content instead of the page content.
I wasn't able to fix this with Vary
edit: fixed by appending value of X-Requested-With to Etags

also TODO: update docs so they say to use the X-Requested-With header instead of ajax parameter~~
edit: done

@Alkarex
Copy link
Member

Alkarex commented Jun 22, 2025

See also

- Parameter `ajax`
<https://freshrss.example.net/i/?c=feed&a=actualize&ajax=1>
Only a status site is returned and not a complete website. Example: "OK"
- Parameter `maxFeeds`
<https://freshrss.example.net/i/?c=feed&a=actualize&maxFeeds=30>
If *maxFeeds* is set the configured amount of feeds is refreshed at once. The default setting is `10`.
- Parameter `token`
<https://freshrss.example.net/i/?c=feed&a=actualize&token=542345872345734>
Security parameter to prevent unauthorized refreshes. For detailed Documentation see "Form authentication".
### For Form Authentication
If your FreshRSS instance is using Form Authentication, you can configure an authentication token to grant access to the online cron.
![Token configuration](../img/users/token.1.png)
You can target a specific user by adding their username to the query string, with `&user=insert-username`:
The scheduled task syntax should look as follows:
<https://freshrss.example.net/i/?c=feed&a=actualize&maxFeeds=10&ajax=1&user=someone&token=my-token>

@Alkarex
Copy link
Member

Alkarex commented Jun 22, 2025

I think we should start by forbidding the ajax mode for problematic cases. Moving to an HTTP header might not be necessary

@Inverle
Copy link
Member Author

Inverle commented Jun 22, 2025

See also

Yes I've seen it but there are too many files to change, so I left it for now
edit: done

I think we should start by forbidding the ajax mode for problematic cases

We can't do that because it's needed for the slider (unless we remove it)
Maybe just omit the cache on those requests?

One other approach is to disable the buttons in HTML and later enable them with JS, but it's not the best one.
edit: fixed, see above

@Inverle
Copy link
Member Author

Inverle commented Jun 29, 2025

@Alkarex Should I generate the .po files too?
It looks like they haven't been in sync for a while now

@Inverle Inverle changed the title Use X-Requested-With header instead of the ajax parameter Use X-Ajax header instead of the ajax parameter Jun 29, 2025
@Frenzie
Copy link
Member

Frenzie commented Jun 29, 2025

Now that po4a has a sufficiently high version on GHA I was hoping to automate something about that but I haven't found the time. A few years ago I'd have needed to add compilation or a custom Docker image which seemed like too much effort but perhaps that was a bad choice because of course everybody forgets or doesn't even know about it. :-)

@Alkarex Alkarex added this to the 1.27.0 milestone Jul 31, 2025
Alkarex added a commit to Alkarex/FreshRSS that referenced this pull request Jul 31, 2025
Related to FreshRSS#7684
The form buttons requiring confirmation are disabled in HTML in the case of Ajax, and only enabled again if our own JavaScript is running
Inverle added 2 commits August 2, 2025 10:39
* Fixes
* Rename `X-Ajax` back to `X-Requested-With` again (with required value of `FreshRSS`)
@Inverle Inverle changed the title Use X-Ajax header instead of the ajax parameter Use X-Requested-With header instead of the ajax parameter Aug 2, 2025
Copy link
Member

@Frenzie Frenzie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, probably needs more testing though ;-)

@Alkarex
Copy link
Member

Alkarex commented Aug 3, 2025

Sorry 😓, but I am not so glad of this PR and would like to pursue an alternative instead:

My reasoning is that:

  • A new HTTP header will break a bunch of existing FreshRSS deployments, many of which are behind a proxy that forwards only specific headers (see the numerous tickets we have had related to nginx, to the headers for the GReader API, turn-key solutions such as Yunohost, etc.). While acceptable if very needed, I would like to make efforts to avoid it.
  • Buttons marked with confirm (at least if loaded from JavaScript) should be marked as disabled anyway until the JavaScript event that confirms when clicking on them is fully loaded / active.
  • The current solution works (mostly) without JavaScript (using HTTP Basic Auth login), and this PR breaks (some of) that. While this is not a must have, I like to keep essential features working without JavaScript for a little longer (I have a plan for a parallel all-JS UI, for that is for later, and without removing the mostly-HTML UI)
  • Not super important, but I am nevertheless not so happy of customising the http-conditional library with some non-standard conditions.

I hope that makes sense 🙈

@Inverle
Copy link
Member Author

Inverle commented Aug 3, 2025

That's fine, I do realize that my PR isn't necessarily the best solution given these circumstances.

Buttons marked with confirm (at least if loaded from JavaScript) should be marked as disabled anyway until the JavaScript event that confirms when clicking on them is fully loaded / active.

I think it would be a good addition to also require a separate "CSRF token" for AJAX requests, just as @Frenzie suggested before, to cover other buttons than those marked with confirm()

Alkarex added a commit that referenced this pull request Aug 3, 2025
Related to #7684
The form buttons requiring confirmation are disabled in HTML in the case of Ajax, and only enabled again if our own JavaScript is running
@Alkarex
Copy link
Member

Alkarex commented Aug 5, 2025

I think it would be a good addition to also require a separate "CSRF token" for AJAX requests

Yes, good idea. Help welcome

@Inverle Inverle closed this Aug 5, 2025
@Inverle Inverle deleted the ajax-in-headers branch December 6, 2025 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants