mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-11 09:37:37 +03:00
Miscellaneous fixes (#22779)
Some checks are pending
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions
Some checks are pending
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions
* block ffmpeg args in custom exports for non-admin users only * prune expired reconnect timestamps periodically in watchdog loop reconnect timestamps were only pruned when a new reconnect occurred. This meant a single reconnect would persist in the count indefinitely instead of expiring after 1 hour * formatting
This commit is contained in:
parent
e95e9b52f3
commit
ed3bebc967
@ -548,7 +548,11 @@ def export_recording_custom(
|
|||||||
|
|
||||||
export_id = f"{camera_name}_{''.join(random.choices(string.ascii_lowercase + string.digits, k=6))}"
|
export_id = f"{camera_name}_{''.join(random.choices(string.ascii_lowercase + string.digits, k=6))}"
|
||||||
|
|
||||||
# Validate user-provided ffmpeg args to prevent injection
|
# Validate user-provided ffmpeg args to prevent injection.
|
||||||
|
# Admin users are trusted and skip validation.
|
||||||
|
is_admin = request.headers.get("remote-role", "") == "admin"
|
||||||
|
|
||||||
|
if not is_admin:
|
||||||
for args_label, args_value in [
|
for args_label, args_value in [
|
||||||
("input", ffmpeg_input_args),
|
("input", ffmpeg_input_args),
|
||||||
("output", ffmpeg_output_args),
|
("output", ffmpeg_output_args),
|
||||||
|
|||||||
@ -36,22 +36,20 @@ logger = logging.getLogger(__name__)
|
|||||||
DEFAULT_TIME_LAPSE_FFMPEG_ARGS = "-vf setpts=0.04*PTS -r 30"
|
DEFAULT_TIME_LAPSE_FFMPEG_ARGS = "-vf setpts=0.04*PTS -r 30"
|
||||||
TIMELAPSE_DATA_INPUT_ARGS = "-an -skip_frame nokey"
|
TIMELAPSE_DATA_INPUT_ARGS = "-an -skip_frame nokey"
|
||||||
|
|
||||||
# ffmpeg flags that can read from or write to arbitrary files.
|
# ffmpeg flags that can read from or write to arbitrary files
|
||||||
# filter flags are blocked because source filters like movie= and
|
|
||||||
# amovie= can read arbitrary files from the filesystem.
|
|
||||||
BLOCKED_FFMPEG_ARGS = frozenset(
|
BLOCKED_FFMPEG_ARGS = frozenset(
|
||||||
{
|
{
|
||||||
"-i",
|
"-i",
|
||||||
"-filter_script",
|
"-filter_script",
|
||||||
"-vstats_file",
|
|
||||||
"-passlogfile",
|
|
||||||
"-sdp_file",
|
|
||||||
"-dump_attachment",
|
|
||||||
"-filter_complex",
|
"-filter_complex",
|
||||||
"-lavfi",
|
"-lavfi",
|
||||||
"-vf",
|
"-vf",
|
||||||
"-af",
|
"-af",
|
||||||
"-filter",
|
"-filter",
|
||||||
|
"-vstats_file",
|
||||||
|
"-passlogfile",
|
||||||
|
"-sdp_file",
|
||||||
|
"-dump_attachment",
|
||||||
"-attach",
|
"-attach",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -62,8 +60,11 @@ def validate_ffmpeg_args(args: str) -> tuple[bool, str]:
|
|||||||
|
|
||||||
Blocks:
|
Blocks:
|
||||||
- The -i flag and other flags that read/write arbitrary files
|
- The -i flag and other flags that read/write arbitrary files
|
||||||
|
- Filter flags (can read files via movie=/amovie= source filters)
|
||||||
- Absolute/relative file paths (potential extra outputs)
|
- Absolute/relative file paths (potential extra outputs)
|
||||||
- URLs and ffmpeg protocol references (data exfiltration)
|
- URLs and ffmpeg protocol references (data exfiltration)
|
||||||
|
|
||||||
|
Admin users skip this validation entirely since they are trusted.
|
||||||
"""
|
"""
|
||||||
if not args or not args.strip():
|
if not args or not args.strip():
|
||||||
return True, ""
|
return True, ""
|
||||||
|
|||||||
@ -471,8 +471,16 @@ class CameraWatchdog(threading.Thread):
|
|||||||
p["cmd"], self.logger, p["logpipe"], ffmpeg_process=p["process"]
|
p["cmd"], self.logger, p["logpipe"], ffmpeg_process=p["process"]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Update stall metrics based on last processed frame timestamp
|
# Prune expired reconnect timestamps
|
||||||
now = datetime.now().timestamp()
|
now = datetime.now().timestamp()
|
||||||
|
while (
|
||||||
|
self.reconnect_timestamps and self.reconnect_timestamps[0] < now - 3600
|
||||||
|
):
|
||||||
|
self.reconnect_timestamps.popleft()
|
||||||
|
if self.reconnects:
|
||||||
|
self.reconnects.value = len(self.reconnect_timestamps)
|
||||||
|
|
||||||
|
# Update stall metrics based on last processed frame timestamp
|
||||||
processed_ts = (
|
processed_ts = (
|
||||||
float(self.detection_frame.value) if self.detection_frame else 0.0
|
float(self.detection_frame.value) if self.detection_frame else 0.0
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user