Repository navigation
The first release since 4.3.0 (2020). It fixes four cross-site scripting vulnerabilities, adds jQuery 4 support and a module build, and fixes several long-standing bugs. There is no API change; the changes below are the ones a page could notice. Upgrading is recommended for everyone.
Security
All four affect 4.3.0 and earlier, and are fixed in 4.4.0. CVE IDs have been requested and will be added to the advisories when assigned.
| Advisory | Severity | Affected feature |
|---|---|---|
| GHSA-x8mc-9vpg-2rc8 | Medium | The iframe upload transport (iframe: true) built HTML from field names, the clicked button's name, the csrf-param meta tag and iframeSrc |
| GHSA-8395-7m7x-q7q2 | Medium | resetForm() passed a <label>'s for attribute to $() |
| GHSA-g7mw-rwc2-4h3g | Medium | semantic: true built a selector from the form's id |
| GHSA-4w39-46xw-8jm2 | Medium | target inserted a parsed JSON response as HTML |
Thanks to Rudloff for reporting the iframe transport and resetForm() issues. The other two were found in a maintainer security review.
Hardening in the same area:
- The Rails CSRF token (
<meta name="csrf-token">) is added only to same-origin iframe uploads, and only when they post the form. A cross-origin upload no longer receives it, and a GET upload no longer puts it in the query string. - An extra field named
hasOwnPropertyno longer breaks iframe uploads.
jQuery 4 and packaging
- jQuery 4 is supported (#616). Every change is tested on jQuery 1.7.2, 3.7.1 and 4.0.0.
- A module build.
modulepoints atdist/jquery.form.mjs, which registers the plugin when imported, so bundlers such as Vite pick it up (#618). The classic script-tag, AMD and CommonJS builds are unchanged:mainisdist/jquery.form.js, anddist/jquery.form.min.jsis still there. - The published package is smaller. It contains
dist,src, the README and the license, without the tests and repository files. - Published with npm provenance from GitHub Actions.
dist/files no longer carry/* eslint */or/* global */comments, which applied to code concatenated after the plugin (#553).
Fixes and behavior changes
- The iframe transport builds its hidden inputs and iframe with DOM APIs. Array and object
data/extraDatavalues are sent as separate fields, as$.paramsends them, instead of"a,b"or[object Object](#597). resetForm()on a<label>resets the control itsforattribute names. This never worked before: a plain id matched nothing, and a match threw.semantic: truematchesform="…"controls by comparing the attribute, so a form id with quotes or brackets no longer throws or picks up unrelated fields.targetinserts only string responses. If jQuery has parsed the response (JSON or XML), the target is left unchanged, a message is logged underdebug, andsuccessis still called.- A
<button>without atypeattribute is captured as the submitter (#588), so its name and value are sent, as in a native submit. resetForm,clearFields,fieldValueandselectedaccept nodes without a tag name (#600).resetFormon the document resets the fields inside it.- JSON responses are parsed with
JSON.parseonly. JSON that onlyevalaccepted (single quotes, unquoted keys) now fails with a parse error instead of being evaluated. - Iframe uploads with
dataType: "script"run the response, as$.ajaxdoes. - Aborting an iframe upload rejects its Deferred with
"aborted", firesajaxCompleteandajaxStop, and removes the iframe. A second abort, or an abort after completion, does nothing. - Iframe responses that fail to parse report
parsererrorinstead ofsuccesswith no data. - FormData uploads serialize
datawith the global$.ajaxSettings.traditional, anddata: {}no longer adds a field with an empty name. - GET urls with a fragment keep the form data, placed before the fragment.
- Controls named like form properties (
elements,action,setAttribute,removeAttribute) no longer break serialization or iframe uploads.
Known, not changed in 4.4.0
- With
delegation: trueon jQuery 3 and later, the handler is not scoped to the selected forms. BindajaxFormdirectly to the forms instead. dataType: "script"on jQuery 4 deliversundefinedtosuccess, because jQuery 4 loads such requests through a script tag. The script still runs.
Full changelog: v4.3.0...v4.4.0