# QKiSS: deny high-value targets - /etc/apparmor.d/abstractions/qkiss-deny-high-value
#
# Included by the qkiss profile AND by its lha / unar child profiles.
# For QKiSS itself (`allow all,`), these are its only restrictions. QKiSS should
# never need these paths, but browsing into them (e.g. in a file dialog) fails.
# Apps opened by QKiSS ("Open this item", the `pux` rule) do not get these rules.
# Allow rules in local/ files cannot override these explicit denies.
#
# `audit deny` (not plain deny): never legitimate here, so a denied attempt is a
# security signal worth logging. An explicit deny also stays enforced while a
# profile is in complain mode.

abi <abi/4.0>,

# =============================================
# Kernel attack surface
# =============================================
# Denies the AppArmor-mediated kernel interfaces a normal desktop app never needs - the
# recurring gateways in recent Linux kernel LPEs.
#
# What abi/4.0 enforces (checked with apparmor_parser 4.1.0 on Linux 6.12):
# - userns: yes.
# - io_uring: no, it is mediated only from abi/5.0. Even then, AppArmor mediates only
#   two io_uring features (sqpoll, override_creds), not io_uring itself; blocking
#   io_uring_setup() needs seccomp.
# - mqueue: only on kernels that support it (Linux 6.12 does not).

audit deny capability,    # any capability (incl. CAP_BPF -> eBPF verifier LPEs); general apps need none
audit deny userns,        # unprivileged user namespace creation: prerequisite for ~44-63% of recent kernel LPEs
audit deny io_uring,      # io_uring: ~60% of kernel exploits in Google's 2022 bug-bounty targeted it
audit deny mount,         # mount / remount: namespace-escape and overlay tricks
audit deny umount,
audit deny pivot_root,
audit deny mqueue,        # POSIX + System V message queues: rarely-used IPC, extra kernel surface

# =============================================
# Cryptographic key stores: ssh, gpg, syncthing
# =============================================
audit deny @{HOME}/.ssh/{,**} mrwklx,
audit deny @{HOME}/.gnupg/{,**} mrwklx,
audit deny @{HOME}/.config/syncthingtray.ini mrwklx,
audit deny @{HOME}/.local/state/syncthing/{,**} mrwklx,

# =============================================
# Incidental secret stores: clipboard history, notes
# =============================================
# Klipper (KDE Plasma clipboard manager) history. Anything the user has
# ever copy-pasted lives here - passwords, API tokens, SSH key fragments,
# private URLs - so it's a credential store by accident, treated as such.
# Klipper itself talks to the clipboard via Wayland / X11 sockets, never
# reads its own history file from another process, so no legitimate
# external reader exists; any DENIED hit here is a signal worth seeing
# in audit log.
audit deny @{HOME}/.local/share/klipper/{,**} mrwklx,
# KDE Plasma Notes plasmoid (sticky-note widget) note content. Notes may hold
# secrets (passwords, codes), so a confined app reading them is never
# legitimate -> audit deny (sensitive target, a denied hit is a signal).
# (Distinct from the KNotes PIM app, which uses ~/.local/share/notes/.)
audit deny @{HOME}/.local/share/plasma_notes/{,**} mrwklx,

# =============================================
# Browser data: sessions, cookies, saved passwords, history
# =============================================
audit deny @{HOME}/.mozilla/{,**} mrwklx,
audit deny @{HOME}/.cache/mozilla/{,**} mrwklx,
audit deny @{HOME}/.config/chromium/{,**} mrwklx,
audit deny @{HOME}/.cache/chromium/{,**} mrwklx,
audit deny @{HOME}/.config/microsoft-edge/{,**} mrwklx,
audit deny @{HOME}/.cache/microsoft-edge/{,**} mrwklx,
audit deny @{HOME}/.cache/Microsoft/Edge/{,**} mrwklx,
audit deny @{HOME}/.config/google-chrome/{,**} mrwklx,
audit deny @{HOME}/.cache/google-chrome/{,**} mrwklx,
audit deny @{HOME}/.config/BraveSoftware/{,**} mrwklx,

# =============================================
# Writes to persistence locations
# =============================================
# Covers shell init files, SSH, editor configs, session managers, window managers,
# XDG autostart, package managers, cron/at jobs, other execution-triggering paths,
# system-level vectors (boot, EFI variables), and dangerous kernel interfaces.
# Home-level paths deny write only - read is left unrestricted to avoid breaking shell-adjacent tooling.
# System-level paths (boot, EFI, firmware, kernel interfaces) deny mrwklx - no user-space profile has a legitimate reason to access these.
# audit deny ensures access attempts are logged.
#
# ~/.dotfiles/** is denied because shell init files are typically symlinks into this directory;
# AppArmor resolves symlinks to the final path, so denying ~/.bashrc w alone does not protect
# the real file at ~/.dotfiles/bash/bashrc (or similar layout).
audit deny @{HOME}/.dotfiles*/{,**} w,

# Ansible: plugins and collections under ~/.ansible/ are Python code that runs with
# ansible, and ansible.cfg can run commands (e.g. ssh_args with a ProxyCommand).
# `.ansible*/` also covers other dirs whose name starts with .ansible, but not the
# ~/.ansible.cfg file, hence its own rule.
audit deny @{HOME}/.ansible*/{,**} w,
audit deny @{HOME}/.ansible.cfg w,
audit deny /etc/ansible/{,**} w,

# Shell init files - bash
audit deny @{HOME}/.bashrc w,
audit deny @{HOME}/.bash_profile w,
audit deny @{HOME}/.bash_login w,
audit deny @{HOME}/.bash_logout w,
audit deny @{HOME}/.profile w,

# Shell init files - zsh
audit deny @{HOME}/.zshrc w,
audit deny @{HOME}/.zprofile w,
audit deny @{HOME}/.zshenv w,
audit deny @{HOME}/.zlogin w,
audit deny @{HOME}/.zlogout w,

# Shell init files - fish
audit deny @{HOME}/.config/fish/{,**} w,

# Shell init files - csh/tcsh
audit deny @{HOME}/.cshrc w,
audit deny @{HOME}/.tcshrc w,
audit deny @{HOME}/.login w,
audit deny @{HOME}/.logout w,

# Shell init files - ksh
audit deny @{HOME}/.kshrc w,

# Shell fragment directories
audit deny @{HOME}/.bashrc.d/{,**} w,
audit deny @{HOME}/.bash_completion.d/{,**} w,
audit deny @{HOME}/.profile.d/{,**} w,
audit deny @{HOME}/.zsh.d/{,**} w,
audit deny @{HOME}/.local/share/bash-completion/completions/{,**} w,

# SSH persistence
# authorized_keys2 is the legacy alternate authorized keys file
audit deny @{HOME}/.ssh/authorized_keys w,
audit deny @{HOME}/.ssh/authorized_keys2 w,
# rc is executed by sshd after successful authentication, before the user shell
audit deny @{HOME}/.ssh/rc w,
# config can set ProxyCommand to hijack connections
audit deny @{HOME}/.ssh/config w,

# PAM environment
audit deny @{HOME}/.pam_environment w,

# X11 session hooks
audit deny @{HOME}/.xinitrc w,
audit deny @{HOME}/.xprofile w,
audit deny @{HOME}/.xsession w,
audit deny @{HOME}/.Xsession w,
# Xmodmap key remapping is sourced at X session start
audit deny @{HOME}/.Xmodmap w,

# systemd user units and environment overrides
audit deny @{HOME}/.config/systemd/{,**} w,
audit deny @{HOME}/.config/environment.d/{,**} w,

# XDG autostart
audit deny @{HOME}/.config/autostart/{,**} w,

# Desktop application entries (.desktop files can specify Exec= to run arbitrary commands)
audit deny @{HOME}/.local/share/applications/{,**} w,

# D-Bus user-session activation (service files auto-start processes when methods are called)
audit deny @{HOME}/.local/share/dbus-1/services/{,**} w,

# Wayland and X11 session definitions
audit deny @{HOME}/.local/share/wayland-sessions/{,**} w,
audit deny @{HOME}/.local/share/xsessions/{,**} w,

# KDE session hooks
audit deny @{HOME}/.config/plasma-workspace/env/{,**} w,
audit deny @{HOME}/.config/plasma-workspace/shutdown/{,**} w,
audit deny @{HOME}/.config/plasma-workspace/scripts/{,**} w,
# autostart-scripts are shell scripts executed at KDE session startup (distinct from XDG autostart)
audit deny @{HOME}/.config/autostart-scripts/{,**} w,

# GNOME session hooks
audit deny @{HOME}/.config/gnome-session/{,**} w,
audit deny @{HOME}/.local/share/gnome-session/{,**} w,

# Window manager startup configs (all support exec directives evaluated at session start)
audit deny @{HOME}/.config/sway/{,**} w,
audit deny @{HOME}/.config/hypr/{,**} w,
audit deny @{HOME}/.config/i3/{,**} w,
audit deny @{HOME}/.config/openbox/{,**} w,
audit deny @{HOME}/.config/awesome/{,**} w,
audit deny @{HOME}/.fluxbox/{,**} w,

# Editor init files - vim/neovim (vimscript and Lua configs execute on editor load)
audit deny @{HOME}/.vimrc w,
audit deny @{HOME}/.vim/{,**} w,
audit deny @{HOME}/.config/nvim/{,**} w,
audit deny @{HOME}/.local/share/nvim/{,**} w,

# Editor init files - emacs (init files execute arbitrary Emacs Lisp on load)
audit deny @{HOME}/.emacs w,
audit deny @{HOME}/.emacs.d/{,**} w,
audit deny @{HOME}/.config/emacs/{,**} w,

# Editor init files - helix
audit deny @{HOME}/.config/helix/{,**} w,

# Terminal multiplexers (run-shell and exec directives run commands on attach)
audit deny @{HOME}/.tmux.conf w,
audit deny @{HOME}/.config/tmux/{,**} w,
audit deny @{HOME}/.screenrc w,

# Python package management
# pip config can redirect installs; .pth files in site-packages execute code at import time
audit deny @{HOME}/.config/pip/{,**} w,
audit deny @{HOME}/.pip/{,**} w,
audit deny @{HOME}/.pydistutils.cfg w,
audit deny @{HOME}/.local/lib/python*/site-packages/{,**} w,

# Node.js package management (npmrc can set lifecycle script hooks and install prefix)
audit deny @{HOME}/.npmrc w,
audit deny @{HOME}/.yarnrc w,
audit deny @{HOME}/.yarnrc.yml w,
audit deny @{HOME}/.config/npm/{,**} w,
audit deny @{HOME}/.config/yarn/{,**} w,

# Git global configuration and hooks
# git config sets core.hooksPath to redirect hook execution to an arbitrary directory
audit deny @{HOME}/.gitconfig w,
audit deny @{HOME}/.config/git/config w,
audit deny @{HOME}/.config/git/hooks/{,**} w,

# Cron and at jobs
audit deny /var/spool/cron/crontabs/{,**} w,
audit deny /var/spool/at/{,**} w,

# User-local executables on PATH (dropping executables here persists across sessions)
audit deny @{HOME}/.local/bin/{,*} w,

# XDG MIME handlers (custom entries map file types to Exec= commands)
audit deny @{HOME}/.local/share/mime/{,**} w,

# XDG thumbnailers (Exec= is invoked by file managers to generate thumbnails)
audit deny @{HOME}/.local/share/thumbnailers/{,**} w,

# Polkit local authorization rules
audit deny @{HOME}/.local/share/polkit-1/{,**} w,

# Boot, firmware, and bootloader config - mrwklx (not just w) because no normal user-space
# program has any legitimate reason to read these paths either. The only programs that
# access them are root-level system tools (grub-mkconfig, grub-install, dracut, mkinitcpio,
# fwupd, efibootmgr, bootctl) which would never be confined by these rules.
# /efi/ covers systems that mount the ESP there instead of /boot/efi/.
# grub.d and /etc/default/grub are indirect persistence: fragments are compiled into the
# bootloader config when grub-mkconfig / update-grub is run.
audit deny /boot/{,**} mrwklx,
audit deny /efi/{,**} mrwklx,
audit deny /sys/firmware/{,**} mrwklx,
audit deny /etc/grub.d/{,**} mrwklx,
audit deny /etc/default/grub mrwklx,

# Dangerous kernel interfaces
audit deny /proc/sysrq-trigger mrwklx,       # triggers immediate reboot, crash, or kill-all
audit deny /proc/kcore mrwklx,               # raw physical memory as ELF core image
audit deny /proc/mem mrwklx,                 # raw physical memory read/write
audit deny /proc/kmem mrwklx,                # raw kernel virtual memory
audit deny /proc/irq/{,**} mrwklx,           # hardware interrupt routing control
audit deny /proc/bus/{,**} mrwklx,           # hardware bus device access
audit deny /proc/sys/** w,                   # kernel parameter writes; read left unrestricted
audit deny /sys/kernel/security/{,**} mrwklx, # LSM policy - writes could alter AppArmor state

# Apparmor itself
audit deny /etc/apparmor*/{,**} mrwklx,
