bump version + disable-htmx security feature

This commit is contained in:
carson 2021-04-04 04:03:52 -06:00
parent 0bcfd0ace8
commit 0488f233ae
5 changed files with 71 additions and 2 deletions

View File

@ -5,7 +5,7 @@
"AJAX",
"HTML"
],
"version": "1.3.3",
"version": "1.3.4",
"homepage": "https://htmx.org/",
"bugs": {
"url": "https://github.com/bigskysoftware/htmx/issues"

View File

@ -49,7 +49,8 @@ return (function () {
swappingClass:'htmx-swapping',
allowEval:true,
attributesToSettle:["class", "style", "width", "height"],
wsReconnectDelay: 'full-jitter'
wsReconnectDelay: 'full-jitter',
disableSelector: "[disable-htmx], [data-disable-htmx]",
},
parseInterval:parseInterval,
_:internalEval,
@ -1355,6 +1356,9 @@ return (function () {
}
function initNode(elt) {
if (elt.closest && elt.closest(htmx.config.disableSelector)) {
return;
}
var nodeData = getInternalData(elt);
if (!nodeData.initialized) {
nodeData.initialized = true;

32
test/core/security.js Normal file
View File

@ -0,0 +1,32 @@
describe("security options", function() {
beforeEach(function() {
this.server = makeServer();
clearWorkArea();
});
afterEach(function() {
this.server.restore();
clearWorkArea();
});
it("can disable a single elt", function(){
this.server.respondWith("GET", "/test", "Clicked!");
var btn = make('<button disable-htmx hx-get="/test">Initial</button>')
btn.click();
this.server.respond();
btn.innerHTML.should.equal("Initial");
})
it("can disable a parent elt", function(){
this.server.respondWith("GET", "/test", "Clicked!");
var div = make('<div disable-htmx><button id="b1" hx-get="/test">Initial</button></div>')
var btn = byId("b1");
btn.click();
this.server.respond();
btn.innerHTML.should.equal("Initial");
})
});

View File

@ -85,6 +85,7 @@
<script src="core/parameters.js"></script>
<script src="core/headers.js"></script>
<script src="core/regressions.js"></script>
<script src="core/security.js"></script>
<script src="core/perf.js"></script>
<script src="core/validation.js"></script>
<script src="core/tokenizer.js"></script>

View File

@ -34,6 +34,7 @@ title: </> htmx - Documentation
* [debugging](#debugging)
* [hyperscript](#hyperscript)
* [3rd party integration](#3rd-party)
* [security](#security)
* [configuring](#config)
</div>
@ -900,6 +901,37 @@ htmx attributes in it, you would need to add a call to `htmx.process()` like thi
.then(data => { myDiv.innerHTML = data; htmx.process(myDiv); } );
```
## <a name="security"></a>[Security](#security)
htmx allows you to define logic directly in your DOM. This has a number of advantages, the
largest being [Locality of Behavior](https://htmx.org/essays/locality-of-behaviour/) making your system
more coherent.
One concern with this approach, however, is security. This is especially the case if you are injecting user-created
content into your site without any sort of HTML escaping discipline.
You should, of course, escape all 3rd party untrusted content that is injected into your site to prevent, among other
issues, [XSS attacks](https://en.wikipedia.org/wiki/Cross-site_scripting). Attributes starting with `hx-` and `data-hx`,
as well as inline `<script>` tags should all be filtered.
Note that it is important to understand that htmx does *not* use eval for most of its features. You (or your security
team) may use a [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) that disallows inline scripting. This will
have *no effect* on htmx functionality, and is almost certainly not what you (or your security team) intends.
To address this, if you don't want a particular part of the DOM to allow for htmx functionality, you may place a
`disable-htmx` or `data-disable-htmx` attribute on the enclosing element of that area.
This will prevent htmx from executing within that area in the DOM:
```html
<div disable-htmx>
<%= user_content %>
</div>
```
This approach allows you enjoy the benefits of [Locality of Behavior](https://htmx.org/essays/locality-of-behaviour/)
while still providing additional safety if your HTML-escaping discipline fails.
## <a name="config"></a>[Configuring htmx](#config)
Htmx has some configuration options that can be accessed either programatically or declaratively. They are