How to restrict endpoint access to htmx only?

Hi all,

I have started experimenting with django and the other day i also started studing htmx. So i was wandering what is the best approach to allow access to a certain set of endpoints only to htmx?

thx!

You can’t. HTMX issues the same get and post requests as anything else does. (Technically, it’s just another JavaScript framework.)
HTMX does set a header to indicate that a request is being sent by HTMX, but any JavaScript code can set the same header.

1 Like

Like the OP, I was interested in implementing this restriction. I was wondering, might there be some technique that leverages the hx-headers attribute? I don’t have a fully fleshed out solution but I thought you could code your hx-get calls to include some custom header and have its value populated with a secret key.

HTTP Rule #1 - You MUST NEVER trust anything coming from the browser.

The HTMX library is a JavaScript library. Whatever they’ve put in HTMX, someone else can copy/use in their own library. (Let’s call this “HTMY”)

If HTMX creates a header, then my bogus “HTMY” project can create the same header. Anything that HTMX sends to the server could also be sent by “HTMY”.

And from the perspective of the server, a request is a request. There is NO difference - at the request layer, in terms of structure or potential content - between requests being issued by a browser, HTMX, axios, or the Python requests library. An hx-get is still an HTTP GET.

So no, there is no solution here. That restriction simply cannot be created.

I understand that any client/hacker can create any header. But the value for that header is another matter, isn’t it?

The idea I’m fleshing out (and readying to test in my dev environment) is two steps:

  1. All my hx-get requests include a custom header via hx-headers – say, “reallyfromHTMX” – and they set this header equal to some secret key obtained from a .env file on my server.

  2. All the htmx-triggered Views look for the “reallyfromHTMX” header and check that it’s set to the expected secret key value (per that same .env file on the server).

Anyone can send a GET with that “reallyfromHTMX” header in it, yes. But how can they discover what the secret key value is? The only time it’s used is a GET request that’s fully internal to my server.

Whatever your server sends out as a “secret key” can be read by my “HTMY” script. It’s not “secret” in the browser.

I suggest you read, in detail RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1. Once you understand the protocol, you will realize that what you’re proposing is useless and doesn’t prevent anything.

Thanks, I found a somewhat quicker learning path to understand what you’re saying.

(1) To have any kind of parsed/evaluated value in a hx-headers tag, you have to embed it via a JavaScript function.

(2) If you create a JavaScript function to obtain that value from the context dictionary, the parsed value will be plainly visible to anyone opening the Developer Tools view in their web browser.

So you’re right, the approach I was looking into is useless because the secret key is exposed to anyone viewing the web page.

Yes - but what I was getting at goes a lot farther than just what you’re addressing here. You can generalize this across any framework or desired functionality.

You have no control over the browser. There is nothing you can do on the server to prevent any arbitrary set of actions from being performed by the client.

When you are thinking about your interactions with the browser, you should always keep that in mind. (That’s also why you always need to sanitize input on the server. Client-side validation is helpful and improves the UX, but cannot be relied upon by the server.)

I see that now, and to be honest it’s exactly why your previous responses weren’t helpful. I was asking a specific question about a specific use case, but you were providing responses so generalized they weren’t of any use to me. It’s like someone sitting at an intersection asking whether to turn right or left, and being told, “Here’s the city map, here’s a list of 50 points of interest you might be interested in visiting someday.” So I essentially gave up and found the answer myself.