Skip to content

4.4.0

Latest

Choose a tag to compare

@kevindb kevindb released this 07 Nov 03:15
· 4 commits to main since this release
a06a0c8

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 hasOwnProperty no 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. module points at dist/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: main is dist/jquery.form.js, and dist/jquery.form.min.js is 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/extraData values are sent as separate fields, as $.param sends them, instead of "a,b" or [object Object] (#597).
  • resetForm() on a <label> resets the control its for attribute names. This never worked before: a plain id matched nothing, and a match threw.
  • semantic: true matches form="…" controls by comparing the attribute, so a form id with quotes or brackets no longer throws or picks up unrelated fields.
  • target inserts only string responses. If jQuery has parsed the response (JSON or XML), the target is left unchanged, a message is logged under debug, and success is still called.
  • A <button> without a type attribute is captured as the submitter (#588), so its name and value are sent, as in a native submit.
  • resetForm, clearFields, fieldValue and selected accept nodes without a tag name (#600). resetForm on the document resets the fields inside it.
  • JSON responses are parsed with JSON.parse only. JSON that only eval accepted (single quotes, unquoted keys) now fails with a parse error instead of being evaluated.
  • Iframe uploads with dataType: "script" run the response, as $.ajax does.
  • Aborting an iframe upload rejects its Deferred with "aborted", fires ajaxComplete and ajaxStop, and removes the iframe. A second abort, or an abort after completion, does nothing.
  • Iframe responses that fail to parse report parsererror instead of success with no data.
  • FormData uploads serialize data with the global $.ajaxSettings.traditional, and data: {} 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: true on jQuery 3 and later, the handler is not scoped to the selected forms. Bind ajaxForm directly to the forms instead.
  • dataType: "script" on jQuery 4 delivers undefined to success, because jQuery 4 loads such requests through a script tag. The script still runs.

Full changelog: v4.3.0...v4.4.0