Data URLs do not work when selfRequestsOnly is enabled.
nedaras opened this issue · 3 comments
Code below will throw htmx:invalidPath
when htmx.config.selfRequestsOnly
is set to true.
<button
hx-get="data:text/plain,"
hx-swap="outerHTML"
>
Delete me.
</button>
to allow custom control of the url validation see https://htmx.org/events/#htmx:validateUrl
You can for example set the selfRequestsOnly to false which will allow any url to be accessed and not just local server requests only. And then you can add the below event listener script to run on the validate url htmx event and lock your requests down to just the URL's you want to keep your site more secure.
document.body.addEventListener('htmx:validateUrl', function (evt) {
// only allow requests to the current server or data:*
if (!evt.detail.sameHost && evt.detail.url.href.indexOf('data:') !== 0) {
evt.preventDefault();
}
});
If they wanted to fix this in htmx and make all data:* urls treated as sameHost internally then the change required would be to add this:
if (startsWith(path, 'data:')) {
sameHost = true
}
To the verifyPath function:
function verifyPath(elt, path, requestConfig) {
let sameHost
let url
if (typeof URL === 'function') {
url = new URL(path, document.location.href)
const origin = document.location.origin
sameHost = origin === url.origin
} else {
// IE11 doesn't support URL
url = path
sameHost = startsWith(path, document.location.origin)
}
if (startsWith(path, 'data:')) {
sameHost = true
}
if (htmx.config.selfRequestsOnly) {
if (!sameHost) {
return false
}
}
return triggerEvent(elt, 'htmx:validateUrl', mergeObjects({ url, sameHost }, requestConfig))
}
That is nice.
Sorry looks like I made a mistake in my example handler as I had === 0 when it should have been !==0
The correct script would be
document.body.addEventListener('htmx:validateUrl', function (evt) {
// only allow requests to the current server or data:*
if (!evt.detail.sameHost && evt.detail.url.href.indexOf('data:') !== 0) {
evt.preventDefault();
}
});