mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-01-22 12:08:29 +03:00
Restrict go2rtc exec sources by default (#21543)
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
* Restrict go2rtc exec sources by default * add docs
This commit is contained in:
parent
047ae19191
commit
c8f55ac41f
@ -22,6 +22,11 @@ sys.path.remove("/opt/frigate")
|
|||||||
|
|
||||||
yaml = YAML()
|
yaml = YAML()
|
||||||
|
|
||||||
|
# Check if arbitrary exec sources are allowed (defaults to False for security)
|
||||||
|
ALLOW_ARBITRARY_EXEC = os.environ.get(
|
||||||
|
"GO2RTC_ALLOW_ARBITRARY_EXEC", "false"
|
||||||
|
).lower() in ("true", "1", "yes")
|
||||||
|
|
||||||
FRIGATE_ENV_VARS = {k: v for k, v in os.environ.items() if k.startswith("FRIGATE_")}
|
FRIGATE_ENV_VARS = {k: v for k, v in os.environ.items() if k.startswith("FRIGATE_")}
|
||||||
# read docker secret files as env vars too
|
# read docker secret files as env vars too
|
||||||
if os.path.isdir("/run/secrets"):
|
if os.path.isdir("/run/secrets"):
|
||||||
@ -109,14 +114,26 @@ if LIBAVFORMAT_VERSION_MAJOR < 59:
|
|||||||
elif go2rtc_config["ffmpeg"].get("rtsp") is None:
|
elif go2rtc_config["ffmpeg"].get("rtsp") is None:
|
||||||
go2rtc_config["ffmpeg"]["rtsp"] = rtsp_args
|
go2rtc_config["ffmpeg"]["rtsp"] = rtsp_args
|
||||||
|
|
||||||
for name in go2rtc_config.get("streams", {}):
|
|
||||||
|
def is_restricted_source(stream_source: str) -> bool:
|
||||||
|
"""Check if a stream source is restricted (echo, expr, or exec)."""
|
||||||
|
return stream_source.strip().startswith(("echo:", "expr:", "exec:"))
|
||||||
|
|
||||||
|
|
||||||
|
for name in list(go2rtc_config.get("streams", {})):
|
||||||
stream = go2rtc_config["streams"][name]
|
stream = go2rtc_config["streams"][name]
|
||||||
|
|
||||||
if isinstance(stream, str):
|
if isinstance(stream, str):
|
||||||
try:
|
try:
|
||||||
go2rtc_config["streams"][name] = go2rtc_config["streams"][name].format(
|
formatted_stream = stream.format(**FRIGATE_ENV_VARS)
|
||||||
**FRIGATE_ENV_VARS
|
if not ALLOW_ARBITRARY_EXEC and is_restricted_source(formatted_stream):
|
||||||
)
|
print(
|
||||||
|
f"[ERROR] Stream '{name}' uses a restricted source (echo/expr/exec) which is disabled by default for security. "
|
||||||
|
f"Set GO2RTC_ALLOW_ARBITRARY_EXEC=true to enable arbitrary exec sources."
|
||||||
|
)
|
||||||
|
del go2rtc_config["streams"][name]
|
||||||
|
continue
|
||||||
|
go2rtc_config["streams"][name] = formatted_stream
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
print(
|
print(
|
||||||
"[ERROR] Invalid substitution found, see https://docs.frigate.video/configuration/restream#advanced-restream-configurations for more info."
|
"[ERROR] Invalid substitution found, see https://docs.frigate.video/configuration/restream#advanced-restream-configurations for more info."
|
||||||
@ -124,15 +141,33 @@ for name in go2rtc_config.get("streams", {}):
|
|||||||
sys.exit(e)
|
sys.exit(e)
|
||||||
|
|
||||||
elif isinstance(stream, list):
|
elif isinstance(stream, list):
|
||||||
for i, stream in enumerate(stream):
|
filtered_streams = []
|
||||||
|
for i, stream_item in enumerate(stream):
|
||||||
try:
|
try:
|
||||||
go2rtc_config["streams"][name][i] = stream.format(**FRIGATE_ENV_VARS)
|
formatted_stream = stream_item.format(**FRIGATE_ENV_VARS)
|
||||||
|
if not ALLOW_ARBITRARY_EXEC and is_restricted_source(formatted_stream):
|
||||||
|
print(
|
||||||
|
f"[ERROR] Stream '{name}' item {i + 1} uses a restricted source (echo/expr/exec) which is disabled by default for security. "
|
||||||
|
f"Set GO2RTC_ALLOW_ARBITRARY_EXEC=true to enable arbitrary exec sources."
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
filtered_streams.append(formatted_stream)
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
print(
|
print(
|
||||||
"[ERROR] Invalid substitution found, see https://docs.frigate.video/configuration/restream#advanced-restream-configurations for more info."
|
"[ERROR] Invalid substitution found, see https://docs.frigate.video/configuration/restream#advanced-restream-configurations for more info."
|
||||||
)
|
)
|
||||||
sys.exit(e)
|
sys.exit(e)
|
||||||
|
|
||||||
|
if filtered_streams:
|
||||||
|
go2rtc_config["streams"][name] = filtered_streams
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
f"[ERROR] Stream '{name}' was removed because all sources were restricted (echo/expr/exec). "
|
||||||
|
f"Set GO2RTC_ALLOW_ARBITRARY_EXEC=true to enable arbitrary exec sources."
|
||||||
|
)
|
||||||
|
del go2rtc_config["streams"][name]
|
||||||
|
|
||||||
# add birdseye restream stream if enabled
|
# add birdseye restream stream if enabled
|
||||||
if config.get("birdseye", {}).get("restream", False):
|
if config.get("birdseye", {}).get("restream", False):
|
||||||
birdseye: dict[str, Any] = config.get("birdseye")
|
birdseye: dict[str, Any] = config.get("birdseye")
|
||||||
|
|||||||
@ -185,10 +185,35 @@ In this configuration:
|
|||||||
- `front_door` stream is used by Frigate for viewing, recording, and detection. The `#backchannel=0` parameter prevents go2rtc from establishing the audio output backchannel, so it won't block two-way talk access.
|
- `front_door` stream is used by Frigate for viewing, recording, and detection. The `#backchannel=0` parameter prevents go2rtc from establishing the audio output backchannel, so it won't block two-way talk access.
|
||||||
- `front_door_twoway` stream is used for two-way talk functionality. This stream can be used by Frigate's WebRTC viewer when two-way talk is enabled, or by other applications (like Home Assistant Advanced Camera Card) that need access to the camera's audio output channel.
|
- `front_door_twoway` stream is used for two-way talk functionality. This stream can be used by Frigate's WebRTC viewer when two-way talk is enabled, or by other applications (like Home Assistant Advanced Camera Card) that need access to the camera's audio output channel.
|
||||||
|
|
||||||
|
## Security: Restricted Stream Sources
|
||||||
|
|
||||||
|
For security reasons, the `echo:`, `expr:`, and `exec:` stream sources are disabled by default in go2rtc. These sources allow arbitrary command execution and can pose security risks if misconfigured.
|
||||||
|
|
||||||
|
If you attempt to use these sources in your configuration, the streams will be removed and an error message will be printed in the logs.
|
||||||
|
|
||||||
|
To enable these sources, you must set the environment variable `GO2RTC_ALLOW_ARBITRARY_EXEC=true`. This can be done in your Docker Compose file or container environment:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
- GO2RTC_ALLOW_ARBITRARY_EXEC=true
|
||||||
|
```
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
|
||||||
|
Enabling arbitrary exec sources allows execution of arbitrary commands through go2rtc stream configurations. Only enable this if you understand the security implications and trust all sources of your configuration.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
## Advanced Restream Configurations
|
## Advanced Restream Configurations
|
||||||
|
|
||||||
The [exec](https://github.com/AlexxIT/go2rtc/tree/v1.9.10#source-exec) source in go2rtc can be used for custom ffmpeg commands. An example is below:
|
The [exec](https://github.com/AlexxIT/go2rtc/tree/v1.9.10#source-exec) source in go2rtc can be used for custom ffmpeg commands. An example is below:
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
|
||||||
|
The `exec:`, `echo:`, and `expr:` sources are disabled by default for security. You must set `GO2RTC_ALLOW_ARBITRARY_EXEC=true` to use them. See [Security: Restricted Stream Sources](#security-restricted-stream-sources) for more information.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
NOTE: The output will need to be passed with two curly braces `{{output}}`
|
NOTE: The output will need to be passed with two curly braces `{{output}}`
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user