Skip to content

Releases: getgrav/grav

2.0.21

Choose a tag to compare

@rhukster rhukster released this 22 Aug 09:34
b06ece4

Bugfix

  • Form fields no longer print their HTML attributes as text above the field, a problem the Twig update in 2.0.20 introduced on every form #4256
  • A custom text escaper registered by a plugin now works again, instead of stopping the page with an error the first time a template used it

2.0.20

Choose a tag to compare

@rhukster rhukster released this 21 Aug 10:19
812e57d

Improved

  • Updated the bundled Twig fork to the current 3.x, picking up the correctness and sandbox improvements from the 3.27 and 3.28 releases.
  • Grav now runs on Twig 3.28 and newer, which tightened the escaping method that Grav's compatibility shim replaces and would otherwise stop the site with a server error.
  • The Twig content sandbox now accepts the list of tests a template uses, which newer Twig versions hand to it and will require from Twig 4.
  • The bundled Nginx configuration now sets caching headers for images, fonts, stylesheets and scripts, so visitors stop re-downloading them on every page.
  • Script and style files whose name already contains a version, such as those the Admin panel ships, are cached permanently in that same configuration, because a change always produces a new name.

Bugfix

  • [security] Page content can no longer register a script or stylesheet through the Twig content sandbox, and asset URLs are now escaped where the tag is built, closing a way to inject markup into a rendered page.
  • [security] The read_file capability no longer includes the user data folder by default, so page content can no longer be used to publish form submissions and other stored data.
  • [security] A proxy address that carries a username and password is now hidden from sandboxed page content, matching the other credentials already redacted there.
  • [security] Custom Twig sandbox denial rules now take effect regardless of how the class name is capitalised, and can no longer be silently bypassed through a parent class or interface.
  • A damaged page cache file is now rebuilt from the original page instead of stopping the site with a server error (#4239).
  • Images and links in page content now work when the file name contains a colon, such as a screenshot named after a timestamp (#3933).
  • A page that sets a full web address as its canonical route now uses that address on its own, instead of joining it onto the site's own address and breaking sitemaps and canonical links (#4023).
  • Turning on asset timestamps now gives each stylesheet and script its own marker taken from when that file last changed, so editing one file no longer waits on an unrelated change before visitors see it (#4049).
  • A canonical route set through the Flex pages API is now saved as written, instead of being stored in a form it could never be read back from.
  • Flex directory blueprints no longer lose the fields the Flex Objects plugin adds when something reads the directory early in a request (#160).
  • The scheduler's generated cron command now names the site's environment when that environment has its own configuration, and each run records which environment it used, so custom jobs defined in user/env/<host>/ no longer fail silently from cron (#4248).
  • Audio and video players generated by media.html() no longer carry an alt attribute, which isn't valid on those elements; any alternative text is kept as an accessible label instead, so the markup passes validation (#3540).

2.0.19

Choose a tag to compare

@rhukster rhukster released this 14 Aug 09:05
25f37b9

New

  • You can now tighten the Twig content sandbox below its built-in defaults with new denied_* settings in security.yaml.
  • The "Twig in Content" report can show the effective sandbox policy, so you can see exactly what page content is allowed to do.

Improved

  • A theme or plugin that ships its own .htaccess can no longer switch off the protection on its own folder, which used to leave its configuration and template files downloadable #4236
  • Twig in page content now renders on new installs by default, instead of appearing as raw text until the setting was turned on.
  • The long Twig sandbox allowlists now ship built into Grav, so security.yaml only records your own additions and future security updates to the defaults reach every site.
  • Existing sites that had trimmed those allowlists to tighten them keep exactly that policy after upgrading, now recorded as explicit denied_* entries.
  • Removed two rarely-used Twig sandbox switches (logging and admin_hint); both behaviours are now always on.

Bugfix

  • The content cross-site scripting check no longer objects to harmless <option> and <select> markup, whose original issue is fixed in the form field that actually rendered it.
  • Sites running with the Twig 2 compatibility setting no longer crash with a server error on every page once an update clears the template cache #4235

2.0.18

Choose a tag to compare

@rhukster rhukster released this 11 Aug 19:42
a18854a

Bugfix

  • [security] Updated the bundled DOM sanitizer to 1.0.14, which closes two further ways a crafted stylesheet could hide an external image reference from the checks added in the previous release (GHSA-ww22-4mqv-x5w3).
  • [security] Modular pages are now checked for cross-site scripting when they are saved, closing a way for a page editor to store a script that ran for every visitor (GHSA-fg8g-663r-f366).
  • [security] The Twig sort and find filters no longer run a plain function name as a callable inside the content sandbox, closing a way for a page editor to execute arbitrary PHP (GHSA-p6qj-p5m7-f62h).
  • A blueprint that builds on another one can again fill dropdowns from its own PHP, which mostly affected themes because their page blueprints nearly always extend the default one (getgrav/grav-plugin-email#193).
  • The Scheduler no longer fails outright on hosts that disable PHP's proc_open, so scheduled jobs can still be viewed and edited there (getgrav/grav-admin-next#16).
  • A scheduled job that cannot be started on such a host is now reported as failed with an explanation, instead of stopping the whole scheduler run.
  • Grav now works out who the site runs as without starting a shell, so that detail still appears when external commands are unavailable.
  • The record of when the scheduler last ran is now written to a fixed location rather than one relative to wherever the trigger happened to run from.

Improved

  • Grav now decides whether the scheduler is being triggered by checking that each job has run when its own schedule says it should have, instead of requiring a run in the last two minutes, so a sparse crontab, a webhook or a scheduled task on Windows all count.

2.0.17

Choose a tag to compare

@rhukster rhukster released this 07 Aug 16:14
d7bfcb5

Bugfix

  • [security] Updated the bundled DOM sanitizer to 1.0.13, which stops CSS comments from hiding dangerous values and covers image loading through image-set(), so untrusted SVG or HTML can no longer reference external resources those ways (GHSA-ww22-4mqv-x5w3).

2.0.16

Choose a tag to compare

@rhukster rhukster released this 07 Aug 16:06
804731d

Improved

  • Updated vendor libs to latest versions
  • The list of groups on the account form is now read through the current user groups system, retiring a routine deprecated since Grav 1.7.

Bugfix

  • [security] The site, system and theme settings offered to Twig written inside page content are now filtered by the same denied-paths list that already covered config, so a page editor can no longer read secrets such as a Redis password straight out of them (GHSA-p597-crqc-m349).
  • [security] Twig written into a form's email settings now runs under the same restrictions as Twig written into page content, closing a route that let someone with only page-editing rights run commands on the server (GHSA-gh8j-q67c-j53f).
  • [security] Form security tokens are now compared with a routine that takes the same amount of time whichever characters differ, so the check can no longer hint at how much of a guess was right (GHSA-38p6-h87p-r4cg).
  • [security] The check for whether a visitor arrived from your own site now requires a full address match, so another site whose domain merely begins with yours no longer counts as your own (GHSA-9ccq-2jfg-qw33).
  • [security] Scheduler job locks are now kept inside your site rather than in the shared system temp folder, so another account on the same server can no longer redirect a lock write to a file of its choosing (GHSA-q8w8-6cq5-j4h2).
  • A scheduled job set to run only one at a time now refuses to start when its lock cannot be written, instead of running unprotected. Note that bin/grav clear removes these locks along with the rest of the temporary folder.
  • [security] Deleting, renaming and copying a media file now check the whole path rather than just the file's own name, so a plugin calling those routines directly cannot reach a file outside the media folder (GHSA-jq29-c7v8-rg55).
  • [security] The media_directory() Twig function now only accepts folders inside your site, so Twig written into page content can no longer list files or republish images from elsewhere on the server (GHSA-47ch-6w46-6xm7).
  • Deleting a media file no longer also removes the retina copies and metadata belonging to a different file whose name merely ends with the same text, so deleting banner.jpg leaves my-banner@2x.jpg alone.
  • A fallback page handed to Uri::referrer() is now returned as given, instead of being trimmed away to nothing whenever the visitor did not arrive from your site.
  • Pages::referrerRoute() was comparing a full web address against a site path, so it never recognised a match and always reported that the visitor came from somewhere else.

2.0.15

Choose a tag to compare

@rhukster rhukster released this 03 Aug 14:15
d5f89d9

Bugfix

  • A plugin's blueprints can use the data providers that plugin ships again, instead of having every one of them refused by a check that only recognised the providers core itself registers (getgrav/grav-plugin-email#193). Fields defined in page frontmatter are held to the stricter rule instead, which is where the risk actually was.
  • [security] A configuration admin can no longer reach an unvetted built-in routine by writing a blueprint field's data provider as a plain function name, a spelling that was still being checked against a list of known-bad names rather than the list of approved ones (GHSA-f8wv-xp27-6gq7).
  • [security] The content security scan now reads an unpaired quote inside an unquoted attribute value the way a browser does, closing another way a page editor could hide a script from it (GHSA-vfmf-q6x9-cw96).
  • [security] The media URL in an audio or video tag is now escaped, so a filename carrying markup can no longer add its own attributes to the player (GHSA-6qw9-4vv5-jr97).
  • JSON responses no longer fail outright when the data contains invalid UTF-8. json_encode() returns false on malformed bytes, and the PSR-7 response body is type-hinted string|resource|StreamInterface, so that false came back out as an unhandled TypeError from inside the vendor stream rather than as a response. Bad bytes are now substituted, and the remaining structural failures raise a catchable JsonException instead of a silent false. Output for valid data is unchanged.
  • [security] The fast static asset server now keeps a request inside the directory the site published, instead of also allowing any neighbouring directory whose name starts with the same letters (GHSA-4v9q-p283-qc2m).
  • [security] File uploads now reject a few more extensions that browsers run script from, or that a server may hand to PHP: xhtml, xht, svgz, php7, php8, pht, phtm and phps (GHSA-66xf-ggf4-6hmc).
  • [security] The bundled Caddyfile protections did nothing. They were written as nginx-style regexes, which Caddy reads as literal paths that never match, and the respond they redirected to ran after the catch-all rewrite had already claimed the request. The rules are now named path_regexp matchers answering 403 directly, inside a route block so they run before the rewrite.

2.0.14

Choose a tag to compare

@rhukster rhukster released this 30 Jul 15:53
5192316

Improved

  • Removed old JQuery 2.1.4. However 2.2.4 and 3.7.1 remain for legacy support

Bugfix

  • [security] An administrator with account-management rights can no longer grant themselves super-admin access by saving it into a user group's permissions, a protection the account form already had (GHSA-xhfv-7758-r9hx).
  • [security] The content security scan no longer reports a page as clean when it was unable to examine it, closing two ways a page editor could hide a script from it: a single invalid character anywhere in the content, and padding a tag out to several thousand characters (GHSA-q2j8-x8hf-63ch).

2.0.13

Choose a tag to compare

@rhukster rhukster released this 25 Jul 20:22
81740e2

New

  • Added an array_group_by Twig filter and function for grouping a list of items by one of their values (#4218).

Bugfix

  • [security] A configuration admin can no longer run code on the server by pointing a dynamic field's data provider at a built-in routine named as a class-and-method pair, a form that slipped past the safety check because it only inspected the single-string spelling; both forms are now vetted the same way (GHSA-r94f-hx44-8jqf).
  • [security] A page editor without super-admin rights can no longer store an event-handler script that runs for site visitors by hiding it behind a > placed inside a quoted HTML attribute; the content security scan now reads quoted attribute values the same way a browser does (GHSA-269c-h76q-8cxw).
  • [security] A backup profile's location is now confined to the site folder, so a profile pointing outside the Grav root can no longer pull external directories into the backup archive (GHSA-fch7-cpv4-w7hg).
  • [security] Uploaded filenames may no longer contain the HTML characters <, >, or ", so a stored filename cannot carry markup that could run if it were later shown unescaped.
  • [security] The find and sort Twig filters now reject a dangerous function name given as their callback, matching the protection already applied to map, filter, and reduce, so template values cannot use them to run code (GHSA-xx48-97m4-h7qm).
  • The bundled nginx.conf security rules are now anchored to the start of the path like the .htaccess rules already are, so the admin's Tools → Logs viewer works on nginx instead of being blocked (#4223).
  • On non-FastCGI setups Grav no longer sends an invalid Content-Encoding: none header, which some strict HTTP clients rejected outright; it now closes the connection cleanly without the bogus value (#2619).

2.0.12

Choose a tag to compare

@rhukster rhukster released this 21 Jul 00:21
7453f3b

New

  • Added per-language fallbacks for unsupported browser languages during HTTP_ACCEPT_LANGUAGE negotiation, allowing them to resolve to supported languages without exposing additional language routes.

Improved

  • The read_file() Twig function can now read .css files by default, so inline stylesheets can be embedded in a template without adjusting the security config (#4215).
  • Documented that the site-wide media object resolves lazily, so its inherited collection query methods need media_directory() to filter or sort site media (#4210).

Bugfix

  • Browser language codes are now matched case-insensitively during HTTP_ACCEPT_LANGUAGE fallback negotiation.