From a44f35e75884511d848b37581d316db9b27bfbdf Mon Sep 17 00:00:00 2001 From: poprhythm Date: Sun, 16 Aug 2026 15:41:05 +0000 Subject: [PATCH] falco: fix git-hook-tamper false-positiving on every gitea push The rule checked proc.name against gitea's managed hook names, but git's hook dispatcher always execs these as `bash ./hooks/.d/gitea` - proc.name is "bash" (the interpreter), never the hook name. That check could never match, so this fired CRITICAL 3x (pre-receive/update/ post-receive) on every single push since it was added - including two notifications the user got moments ago from this repo's own commits. Fixed to check the actual invoked script path in proc.cmdline instead. This commit's own push is the live verification. --- falco/rules/git-hook-tamper.yaml | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/falco/rules/git-hook-tamper.yaml b/falco/rules/git-hook-tamper.yaml index 7579e85..0e7f305 100644 --- a/falco/rules/git-hook-tamper.yaml +++ b/falco/rules/git-hook-tamper.yaml @@ -6,21 +6,32 @@ # ever manages four hook names per repo (post-receive, pre-receive, update, # proc-receive), each delegating to a same-named script under hooks/*.d/gitea - # anything else executing from a hooks/ path is not something Gitea put there. - -- list: gitea_managed_hook_names - items: [post-receive, pre-receive, update, proc-receive, gitea] +# +# BUG FOUND 2026-08-16: the original condition checked proc.name against +# gitea_managed_hook_names, but git's hook dispatcher always execs these as +# `bash ./hooks/.d/gitea` - proc.name is "bash" (the interpreter), +# never "pre-receive"/"gitea"/etc. That check could never match, so this +# rule fired CRITICAL on every single git push to gitea - confirmed via +# docker logs falco showing 3 alerts (pre-receive/update/post-receive) on +# every push, including this repo's own commits. Fixed to check the actual +# invoked script path in proc.cmdline instead of proc.name. - rule: Unexpected git hook execution desc: > A process executed from a path under a git repository's hooks/ directory - whose name isn't one of Gitea's own managed hook scripts. Catches planted - hooks used for persistence/RCE (e.g. a malicious uploadpack.packObjectsHook - or receive hook), independent of how the file got written. + whose script isn't one of Gitea's own managed hook scripts. Catches + planted hooks used for persistence/RCE (e.g. a malicious + uploadpack.packObjectsHook or receive hook), independent of how the + file got written. condition: > spawned_process and container.name = "gitea" and proc.cmdline contains "/hooks/" - and not proc.name in (gitea_managed_hook_names) + and not (proc.cmdline glob "*hooks/pre-receive.d/gitea" + or proc.cmdline glob "*hooks/update.d/gitea *" + or proc.cmdline glob "*hooks/post-receive.d/gitea" + or proc.cmdline glob "*hooks/proc-receive.d/gitea" + or proc.cmdline glob "*hooks/proc-receive.d/gitea *") output: > Unexpected git hook executed (user=%user.name command=%proc.cmdline exepath=%proc.exepath