# ============================================================================
# qutebrowser Hardened config.py -- Pentesting + Privacy Profile
# Place in: ~/.config/qutebrowser/config.py
# ============================================================================
config.load_autoconfig(False) # ignore autoconfig, this file is authoritative
# === CONTENT BLOCKING ===
c.content.blocking.method = "both" # use both adblock methods
c.content.blocking.adblock.lists = [ # comprehensive blocklists
"https://easylist.to/easylist/easylist.txt",
"https://easylist.to/easylist/easyprivacy.txt",
"https://easylist.to/easylist/fanboy-social.txt",
"https://secure.fanboy.co.nz/fanboy-annoyance.txt",
"https://easylist-downloads.adblockplus.org/abp-filters-anti-cv.txt",
"https://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&showintro=1&mimetype=plaintext",
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters.txt",
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/badware.txt",
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/privacy.txt",
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/resource-abuse.txt",
]
c.content.blocking.hosts.lists = [ # hosts-based blocking
"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
]
# === JAVASCRIPT ===
c.content.javascript.enabled = False # JS off by default (whitelist per-domain)
# whitelist JS for specific domains:
# config.set("content.javascript.enabled", True, "*://github.com/*")
# config.set("content.javascript.enabled", True, "*://app.hackthebox.com/*")
# config.set("content.javascript.enabled", True, "*://tryhackme.com/*")
# === COOKIES ===
c.content.cookies.accept = "no-3rdparty" # block third-party cookies
c.content.cookies.store = False # session-only cookies
# === WEBRTC (IP leak prevention) ===
c.content.webrtc_ip_handling_policy = "disable-non-proxied-udp" # prevent IP leaks
c.content.webgl = False # disable WebGL fingerprinting
# === CANVAS / FINGERPRINTING ===
c.content.canvas_reading = False # block canvas fingerprinting
c.content.reading_order = False # no reading order detection
# === HEADERS / REFERRER ===
c.content.headers.referer = "same-domain" # only same-domain referrers
c.content.headers.do_not_track = True # send DNT header
c.content.headers.custom = { # custom headers
"https://*": {
"Accept-Language": "en-US,en;q=0.5", # generic accept-language
}
}
c.content.headers.user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0" # spoof as Firefox
# === DNS ===
c.content.dns_prefetch = False # no DNS prefetching
# === NOTIFICATIONS / PERMISSIONS ===
c.content.notifications.enabled = False # block all notifications
c.content.geolocation = False # block geolocation
c.content.media.audio_capture = False # block microphone
c.content.media.video_capture = False # block camera
c.content.media.audio_video_capture = False # block both
c.content.autoplay = False # no autoplay
# === PLUGINS / FEATURES ===
c.content.plugins = False # no plugins
c.content.pdfjs = False # no built-in PDF viewer
# === DOWNLOADS ===
c.downloads.location.prompt = True # always ask download location
c.downloads.location.directory = "~/downloads" # download directory
c.downloads.remove_finished = 5000 # remove from list after 5s
# === NETWORK / PROXY ===
# Uncomment for Burp Suite proxy:
# c.content.proxy = "http://127.0.0.1:8080"
# Uncomment for Tor SOCKS5:
# c.content.proxy = "socks5://127.0.0.1:9050"
c.content.proxy = "system" # use system proxy by default
# === TLS / SSL ===
c.content.tls.certificate_errors = "ask-block-thirdparty" # ask on cert errors, block 3rd party
# === CACHE / STORAGE ===
c.content.cache.size = 52428800 # 50MB cache max
c.content.local_storage = False # disable localStorage by default
# === COMPLETION / HISTORY ===
c.completion.web_history.max_items = 0 # no web history in completion
c.completion.cmd_history_max_items = 100 # keep command history
c.history_gap_interval = -1 # no history gap detection
# === URL / SEARCH ===
c.url.start_pages = ["about:blank"] # blank start page
c.url.default_page = "about:blank" # blank default page
c.url.searchengines = { # search engines
"DEFAULT": "https://searxng.site/search?q={}", # SearXNG privacy search
"g": "https://www.google.com/search?q={}",
"ddg": "https://duckduckgo.com/?q={}",
"gh": "https://github.com/search?q={}",
"htb": "https://app.hackthebox.com/search?q={}",
"cve": "https://nvd.nist.gov/vuln/search/results?query={}&search_type=all",
"exploit": "https://www.exploit-db.com/search?q={}",
"gtfo": "https://gtfobins.github.io/#{}",
"shodan": "https://www.shodan.io/search?query={}",
}
# === KEYBINDINGS (pentesting shortcuts) ===
config.bind(",p", "set content.proxy http://127.0.0.1:8080") # toggle Burp proxy
config.bind(",P", "set content.proxy system") # back to system proxy
config.bind(",t", "set content.proxy socks5://127.0.0.1:9050") # toggle Tor
config.bind(",j", "set content.javascript.enabled true") # enable JS for current tab
config.bind(",J", "set content.javascript.enabled false") # disable JS
config.bind(",c", "set content.cookies.store true") # enable persistent cookies
config.bind(",C", "set content.cookies.store false") # session-only cookies
config.bind(",u", "spawn --userscript view-source") # view source
config.bind(",h", "devtools") # toggle devtools
# === COLORS (dark theme) ===
c.colors.webpage.preferred_color_scheme = "dark" # prefer dark mode
c.colors.webpage.darkmode.enabled = True # force dark mode