listmonk
listmonk copied to clipboard
Back button doesn't navigate back to public subscription form
Version:
- listmonk: 2.1
- OS: Docker
Description of the bug and steps to reproduce:
- Add a public subscription form on your website
- Open the Listmonk admin or just open the main listmonk URL
- Fill in the form on your website & click Subscribe. The page /subscription/form will be shown
- Click 'Back'.
You won't be redirected to the page containing the subscription form. In my case I'm redirected to a empty browser tab (Firefox).
In my case history.length == 3, which causes the back button fire a history.go(-2). history.go(-1) does the job.
As a work around I added some custom javascript, checing the document.referrer and changing the button event handler.
For me I remember this worked. So I guess this might be a special case, we have to investigate?
Hi @toontoet. I followed the exact steps and am unable to reproduce this.
I also have this problem.
I also noticed, that the back button brought me 2 pages before, the page before the form.
Its like this:
- Any web page that links to the form
- Form, embedded on the webpage
- Listmonk Success message with back button
- Now jumps back to 1, not to 2
@knadh can you reopen this?
We have noticed that when the subscription is not completed (ie: the subscriber has not checked the checkbox), the back button does not return to the subscription form, but instead goes two pages back. It would be more user friendly if it went back to the form. Thanks!
after subscription success the back button should kick you back to
tld.com/subscription/form ( where you can subscribe with another email for another list, whatever)
but kicks you back to
tld.com/ (the combined login & subscription page)
listmonk 2.4 (today)
I have the same problem on macOS 16.5, Safari and Firefox.
I'm having the same issue. Listmonk v2.5.1 Firefox on macOS or Windows, Safari on iOS, etc.
I guess a nicer solution would be to be able to pass a redirect url to /subscription/form where it should lead after successful form submission and that should be used on the "Back" button. This way, developers could decide where they'd want to go when POST'ing from their websites.
If you want that (like me), this is the custom js to add:
const backBtn = document.querySelector("#btn-back");
if (backBtn) {
backBtn.href = new URLSearchParams(window.location.search).get('redirect')
backBtn.onclick = null
}
Afterwards you can post to .../subscription/form?redirect=[TARGET_URL]
Without the URL being added to a safe list in the backend, this would lead to an open-direction vulnerability though.
Without the URL being added to a safe list in the backend, this would lead to an open-direction vulnerability though.
While I agree that a configuration option in the backend would be preferable, I don't think this opens a new attack vector. If an attacker already manipulates the target of a form, he could easily replace that target with an address of his liking (with a redirect, data collection etc.). What am I missing?
/subscription/form?redirect=[TARGET_URL]
An attacker doesn't have to compromise the form. They can send unsuspecting users to https://listmonk.legitsite.com/subscription/form?redirect=$malicious_url. Legit domain, legit form, legit signup, but malicious redirect after.
/subscription/form?redirect=[TARGET_URL]
An attacker doesn't have to compromise the form. They can send unsuspecting users to
https://listmonk.legitsite.com/subscription/form?redirect=$malicious_url. Legit domain, legit form, legit signup, but malicious redirect after.
Well, sure, no form needed for that. But also: I'd need to first have a user-trusted website to have this link on. In both cases, I don't see why I'd need listmonk at that point.
While still no server-validation, one could easily extend the js to have a little check:
const backBtn = document.querySelector("#btn-back");
const redirect = new URLSearchParams(window.location.search).get('redirect')
if (backBtn && redirect && /^(test.com|localhost)$/.test(new URL(redirect).hostname)) {
backBtn.style.display = "inherit"
backBtn.href = redirect;
backBtn.onclick = null
}