We invite you to test BleachBit 6.0.3 beta. This release includes important security fixes, hardening, bug fixes, performance improvements, and minor enhancements.
Highlights of enhancements and features:
- Early support for macOS.
- DNF5 interpretation (for Fedora and similar)
- Delete top-level log files in the Claude cleaner
- Remember GUI zoom level
- New cleaners for Python history, fish shell, Zsh shell
- Redesigned CI download page for nightly Windows releases
- Speed improvements
Special thanks to XhmikosR for making many of the improvements in this release.
Since version 6.0.2:
Security
Special thanks to XhmikosR for development of all these security fixes.
This release fixes several security vulnerabilities. Most are local
attacks that require an attacker to be able to create files in a
location BleachBit scans or writes to; two are remote attacks through
the update check. All are fixed in this release.
Affected versions: all versions prior to 6.0.3.
Fixed in: 6.0.3.
CVE identifiers: not yet filed.
Fixed in: 6.0.3.
CVE identifiers: not yet filed.
Symlink / reparse point following in delete, wipe, and truncate
Several code paths that delete, overwrite (wipe), or truncate files followed a symlink or Windows reparse point before acting on it. A local attacker who could plant a symlink in a directory BleachBit cleans (for example a world-writable temp directory, or a user's home when run with elevated privileges) could redirect the operation to an arbitrary file chosen by the attacker, causing that file to be deleted, overwritten, or truncated.
Affected paths: file truncation on all platforms, file wiping on
POSIX and Windows, deep-scan results, writing of configuration /
JSON / LibreOffice registrymodifications.xcu output,
and deletion of locale contents through a symlinked locale
directory. All of these now refuse to follow a symlink or reparse
point and use O_NOFOLLOW / lchown /
equivalent guards where applicable.
Privilege escalation when run under sudo
When BleachBit was run via sudo and invoked external
tools (such as dnf, yum, or
paccache) as root, it passed the invoking user's
environment through unchanged. A hostile inherited environment
(LD_PRELOAD, LD_LIBRARY_PATH,
PATH pointing at user-writable directories,
PYTHONPATH, BASH_ENV, and similar) could
redirect the privileged child process and escalate to root.
Additionally, the chownself() function followed symlinks and
matched the /root prefix non-canonically, so a symlink
planted in the invoking user's home could redirect an
os.chown call to an attacker-chosen target, and paths
such as /rootfoo were treated as the /root directory.
Both are fixed: the root environment is sanitized before spawning
children, and chownself() uses lchown and
canonical path comparison.
Arbitrary command / registry actions from untrusted cleaner files
CleanerML and winapp2.ini files loaded from user-writable
directories (the personal cleaners directory, or any world-writable
directory) could declare process actions that run
arbitrary commands, or winreg actions that delete
arbitrary registry keys. A lower-integrity process that could write
to those directories could thus execute commands or delete registry
keys in the context of the BleachBit user.
Cleaner files are now classified as trusted or untrusted based on
whether they live in the system cleaners directory, and
process / winreg actions from untrusted
files are ignored. Cleaner files in world-writable directories are
skipped entirely.
Thank you to ElvisBlue for reporting this issue (CVE requested/pending).
SQLite URI and SQL injection in cookie / history handling
When BleachBit opened a SQLite database (browser cookies, history)
by path, the path was interpolated into a file: URI
without percent-encoding. A ? in the filename could be
misparsed as the start of the URI query string and defeat the
mode=ro flag, causing a database intended to be opened
read-only to be opened read/write. Table and column names were also
interpolated into SQL without quoting.
Paths are now percent-encoded, identifiers are quoted, and string literals are escaped.
XML external entity (XXE) and insecure update URLs
All XML parsing entry points (CleanerML, winapp2.ini, the update check, protected-path files, and Windows cleaner definitions) accepted DTDs with internal subsets, allowing an XML entity expansion attack from a malicious cleaner or update response.
Separately, the update check and winapp2 download accepted
http:// URLs and the URL came from a remote XML
response. A network attacker could perform a man-in-the-middle
attack and substitute a malicious winapp2.ini, which would then be
loaded as a cleaner with full trusted privileges.
DTDs with internal subsets are now rejected at every parsing entry
point, and update / winapp2 URLs are required to be
https://.
Windows DLL search path
On Windows, the DLL search path included the current directory
(and, in the frozen builds commonly used by end users, the full PATH).
A malicious DLL planted next to the executable, or in a directory on PATH,
would be loaded with the user's privileges.
The search path is now hardened at startup via
SetDefaultDllDirectories (frozen builds) or
SetDllDirectoryW("") (non-frozen), before any DLL
that could be targeted is loaded.
Additional hardening
-
open_url()now restricts URLs to thehttp(s)schemes, preventing an attacker-supplied URL from invoking arbitrary OS URL handlers. - Downloaded chaff models are now verified against a pinned SHA-512 hash, preventing a man-in-the-middle from substituting model files.
-
UAC argument encoding on Windows now uses
subprocess.list2cmdline, closing an argument injection in the elevation path. -
The debug log file and download directories are now created
with restrictive permissions (
0600and0700respectively).
All Platforms
Safer shredding, race condition and crash fixes, performance improvements, and new cleaners.
- ea3bc57f - Refuse to shred the working directory or its parent directory when shredding arbitrary files, preventing accidental data loss from a path that collapses to the current directory (such as an empty string, `.`, or `..`)From a terminal, run `bleachbit --shred .` and `bleachbit --shred ..` and verify each is refused with a warning instead of shredding the current/parent directory. Also run unit test `tests/TestCleaner.py::CleanerTestCase::test_create_simple_cleaner_refuses_cwd`.
- b7a8bd19 - Fix cleaners sometimes missing files when the auto-hide feature scanned the same folder at startup
- 106c34a6 - Delete top-level log files in the Claude cleaner
- 301995c5 - Add support for filtering options by operating system in CleanerML files.
- 2d1952c0 - Improve error handling and error reporting with SQLite operations
- f93ff721 - Fix race condition where a setting change could be saved to disk in an inconsistent state
- 08fd3c89 - Avoid initializing GTK, which opens a socket, when using CLI, TUI, or wxWidgets
- 8b70f96d - Fix GTK crash from logging on worker threads
- 036dda4e - Prevent crash in case of deeply nested directory tree
- c0464c61 - Improve robustness in case of permission error while scanning a directory
- 91b60036 - Skip malformed file URIs (such as `file://`) that resolved to an empty path and then to the working directory, which could have caused accidental data loss when shredding files dragged from a file manager. No standard file manager produces these URIs, so this is a defensive fix.Run the unit test `tests/TestFileUtilities.py::FileUtilitiesTestCase::test_uris_to_paths` covering `file:`, `file://`, and `file:///`; verify `file://` yields no path and a warning is logged.
- 1a9e275d - Fix: when using F11 to toggle full screen, the opposite state was restored on next startup
- 54c9e516 - Fix crash in desktop notifications caused by importing importlib instead of importlib.util before calling importlib.util.find_specTrigger an action that shows a desktop notification and confirm it appears without error
- d7c36077 - Warn instead of crashing on an invalid wildcard cleaner, on CLI with foo.*
- 6a872350 - Remember zoom level
- 67ac349c - Add cleaner for Python command history
- 6be435f2 - Update coverage, requests, and certifi dependencies
- fe2cac73 - Skip files that vanish between scan and size measurement, instead of abortingskip
- 29999639 - Skip files that vanish between scan and size measurement, instead of abortingskip
- a781e6ed - Skip cleaner XML files that disappear during startup
- 53b86c1d - Fix race condition where a configuration change could be lost if settings were reloaded from disk at the same time
- aadac56f - Improve performance by avoiding redundant directory metadata checks
- 377eea2e - Cache sorted cleaner option keys instead of re-sorting each call
- 7639e048 - Drop redundant path normalization in children_in_directory
- bbd6a737 - Skip islink() in whitelisted_posix when keep-list is empty
- 895d57d7 - Index cleaner actions by option to avoid quadratic dispatch
- 505775c6 - Compile constant regexes once instead of per call
- 64997999 - Update requests to 2.33.0, setuptools to 83.0.0 (except on Python 3.9)
- ae1e980c - Cleaner.py: don't overwrite Cleaner attributes in subclass
- 40c15674 - Improve detection of space saved reportde by APT autoclean
- aa4015eb - Code cleanup
- 541f425e - Improve detection of size reported by pacman
- ba4a90fd - Add defensive check for GTK typelib directory
- 7790a71c - Fix crash in SQLite error handler (Python 3 exceptions have no .message attribute) and when handling very short file URIs
- 18e14e13 - Add defensive checks to prevent crash in csae of two delayed cleanup operations with same priority level
- 03794cfa - Fix dark-background detection misidentifying some GTK themes as dark
- d4e140ec - Add defensive checks for parsing XMLs with update information
- 73d256de - Fix parsing of same_user attribute in CleanerML files
- b53c30cc - Fix bug causing some cleaning operations to run twice, causing redundant work
- 0a38c4e4 - Hoist bytes_to_human prefix lists to module constants
- b0731ebd - Batch Chrome bookmark id lookups into chunked queries
- f08c5761 - Use a set for mozilla favicon bookmark domain lookup
- 5256b34d - Defer path join past deep-scan filename filters
- 4c28ce77 - Iterate CleanerML elements without a throwaway list()
- 72078b94 - Use frozensets for Options boolean_keys and int_keys
- f8e6bbd1 - Build cleaner tree without re-sorting options twice
- c66eb55c - Drop executable bit from assets and menu.ui
- 8c2b9019 - Remove Python 2 coding declarations and __future__ import
- d0f8b472 - Use zero-arg super() and drop redundant object base class
- 12300bd3 - Use vanilla RawConfigParser.write in clean_ini: uses less code
- d2a125df - Drop unused local variable assignments
- c659c847 - Drop redundant comparisons in logical_ranges_to_extents and write_zero_fill
- 6cdffd01 - Close devnull descriptor after redirecting stdout on BrokenPipeError
- 3c2bd0db - Initialize locals before conditional assignment
- 3fd32029 - fnmatch_translate: fix compatibility with Python 3.14
- 047a4f88 - Fixed the Mozilla Firefox favicons cleaner, which could fail or incorrectly identify favicons to keep.On a system with Mozilla Firefox, run the Mozilla cleaner's favicons operation. Verify it completes without errors and that favicons not associated with bookmarks are removed while bookmarked favicons are preserved.
- 6add79bc - Improve performance of the keep list (whitelist)
- 70860387 - Improve efficiency in detecting file encoding
- 06316540 - Fix crash in the debug log handler when an empty message is written, and append the full buffered text instead of just the last fragment
- add44f3b - Improve randomness in generating filenames when wiping
- 96f22d98 - Narrow the scope of the .angular deepscan cleaner
- 190bf9a7 - Support chardet version 6
- 4686c56b - Restrict open_url() to http(s) schemes
- 456c0550 - Verify SHA-512 of downloaded chaff models
- bd863c07 - Harden SQLite/URI construction in Special.py against injection
- 7a7d11ca - Do not follow symlinks anywhere in wipe_write()/wipe_contents()
- a2d404af - Reject all insecure winapp2 and update-check URLs
- f71cb536 - Reject DTDs across all XML parsing entry points
- c753694e - Reject reparse points when truncating files
- a2219f7f - Skip junctions and symlinks in deep scan
- b33d7f0f - Block process and winreg actions from untrusted cleaners
Windows
Security hardening, file wiping fixes, junction/symlink handling, Winapp2.ini improvements, and UI consistency with Linux.
- e2ca6ee6 - Use absolute paths for ipconfig and taskkill to prevent binary-planting attack via executable search pathTo test ipconfig, clean DNS cache. To test taskkill, clean Windows Explorer - Thumbnails.
- 86c70f59 - Fix secure file wiping skipping some clusters that should have been overwrittenIn the prefeferences, enable Overwriting contents. Then, delete files.
- 91b14526 - Fix secure file wiping not fully overwriting fragmented filesIn the prefeferences, enable Overwriting contents. Then, delete files.
- e0bb73e3 - Migrate Windows CI builds from ci.bleachbit.org to download.bleachbit.org/ci/ to consolidate on one subdomain. The new Windows CI download page has many enhancements such as filtering by branch and one-click to copy checksums.
- 766f883f - Fix failure to start application from UNC (network) pathsPlace BleachBit portable in a path such as \\server\share and start the application: it should start.
- b7788677 - Preserve the root of folders for temporary filesPreview System - Temporary Files, and verify c:\windows\temp and %localappdata%\temp themselves are not listed. (Their contents may be listed.)
- 8c2f2f66 - Fix toast notification was brokenIn the Windows frozen build, trigger a cleaning operation that takes longer than 10 seconds (e.g., deep scan), then switch focus away from the BleachBit window (e.g. focus another application) before it finishes. When the operation completes, a 'Done.' toast notification should appear. Verify it does not raise an error and that no notification backend traceback is logged.
- 61358440 - Fix cleaning of folder shortcuts (junctions) and directory symlinks being skipped when the target folder contained filesOn Windows, create a junction or directory symlink pointing at a non-empty folder (e.g. put a file in the target), then run a cleaner that matches the junction/symlink path. Confirm the junction/symlink itself is removed while the target folder and its contents are left untouched. Repeat with an empty target folder: the junction/symlink should still be removed, and the (empty) target folder should remain.
- b60a27e9 - Fix slashes in amule, Adobe Flash, Vuze, VLCTest the four cleaners.
- db590127 - Fix Pale Moon base variable on WindowsClean Pale Moon
- 8c186cc4 - Fixed winapp2.ini ExcludeKey with the *.* pattern, which should exclude the whole folder but was not working. The normal Winapp2.ini file does not contain this pattern, so the bug does not normally affect users.On Windows, create a folder with an extensionless file (e.g. 'deleteme') and a file with an extension (e.g. 'deleteme.log'). Define a winapp2.ini cleaner with FileKey1=
|deleteme* and ExcludeKey1=PATH| |*.*. Run the cleaner; both files should remain because *.* excludes the whole folder. Without the ExcludeKey, the extensionless file should be deleted. - 3ebef8af - When cleaning system.tmp, preserve new GLib D-Bus nonce files to not allow multiple instances of the application to be open.Preview System - Temporary Files, and there should be no new gdbus-nonce-file-XXXXXX files listed.
- b32bfee5 - Handle interrupted console outputRun `bleachbit.exe -p system.tmp | more` and type the letter Q. There should not be a traceback.
- e9c1b974 - Move the menu from application icon on left side to hamburger on right side (now consistent with Linux)Verify the hamburger menu is usable.
- c8d69146 - Clean Windows clipboard in TUI or wx GUI without requiring GTKPut text in the clipboard. Verify it can be pasted. Then, clean the clipboard. Verify it can no longer be pasted.
- 194be82a - Write the GTK error report to a unique temporary file
- 625a7f8f - Improve speed of importing Winapp2.ini cleanersIn the preferences, enable Winapp2.ini cleaners. Restart the application, and browse and preview the Winapp2.ini cleaners to verify they imported correctly.
- 9c9418ae - Skip unknown winapp2 options instead of aborting the section
- 869d6c61 - Ensure that file wiping releases system resources in case of error
- 6a026160 - Cache the Windows temporary directory for the keep list (whitelist)See other test: 'roots of folders for temporary files'
- 4699d86f - Call match directly on precompiled winapp2 regexes
- f8a412e1 - Cache the Windows versionUsed in Winapp2.ini import process, but low risk change.
- c7b0535c - Hoist loop invariants in winapp2.ini parsingLow risk change.
- e4a61e8e - Skip the unused world-writable stat on WindowsLow risk change regarding importing CleanerML.
- 50696597 - Refuse to follow a symlink when opening a file for wiping
- dfcb7540 - Cap wildcard count in winapp2.ini glob patterns
- d5b9fb76 - Use subprocess.list2cmdline for UAC argument encoding
- d55f4245 - Harden Windows DLL search path against preloading attacks
POSIX
Improved reliability and compatibility across POSIX systems with better clipboard shredding, process handling, shell cleaners, error handling, and performance.
- 9a362856 - Gracefully handle missing sqlite3: show message instead of crashing on startupStart BleachBit on a system without sqlite3. FreeBSD is a system that normally does not include sqlite.
- 52d957a2 - Fix UnicodeDecodeError reading clipboard target names when shredding files from clipboardOn Linux, select a file in a file manager, copy file to clipboard, and in BleachBit press CTRL+V to paste and shred it.
- 1f170f14 - Fix shredding files from the clipboard, which failed to detect files in some casesCopy files in a file manager, then in BleachBit use the clipboard shred feature to verify the file paths are detected and shredded.
- e818be82 - Handle spaces in process names, like for Google Chrome, from /proc and ps aux on POSIX systems without psutil installedRun BleachBit on Linux or macOS without psutil. Naturally observing process names with spaces seems most common on macOS.
- d4ea92a9 - Add cleaner for fish shell
- 7395b5d2 - Add cleaner for Zsh shell
- 4fcbba35 - Fix error when file disappears when cleaning system temporary files
- 5b678e8e - Suppress asyncio deprecation warnings with Python 3.14
- 1a5742b4 - Add defensive check to prevent crash when the LOGNAME environment variable contains digit-like Unicode characters that are not valid decimal numbersOn Linux, run: LOGNAME=$'\u00b2' python3 -c 'from bleachbit.General import get_real_uid; print(get_real_uid())'. Before the fix it raises ValueError; after, it falls through to os.getuid().
- 28dd391a - Improve performance of open-files cache
- 9dbdf23c - Fall back to PATH when a POSIX tool is not in a standard directory
- ca9153bb - Do not delete locale contents through a symlinked locale directory
- 21c85902 - Extract _open_nofollow_fd() and reuse it in truncate_file() and wipe_write()
- c4ce96c8 - Create the debug log file with 0600 permissions
- 4fe5c2e6 - Refuse to write config/JSON/registrymodifications.xcu output through a symlink
- c17b54c0 - Create download directories with 0o700 permissions
- 9452fc08 - Skip cleaner files in world-writable files or directories
- e951fb3e - Sanitize PATH and drop code-loading env vars for subprocesses when root
- 3a413af8 - Use absolute path for POSIX tools
- c25efed7 - Harden chownself() against symlinks and non-canonical /root paths
- 67c444b7 - Validate SUDO_UID before use
Linux
Fixed memory, process, filesystem, package-manager, profile-detection, whitelist, and Chromium-cleaning issues while improving DNF support.
- 562bd818 - Report disk usage covered by DNF4 (instead of 0B). Improve accuracy of disk usage recovered by DNF autoremove (instead of estimation).Run DNF preview (without BleachBit) and note the expected size. Then, clean DNF with BleachBit and verify the size matches.
- 49ce41c4 - Use XDG_CONFIG_HOME to find Firefox profile folders
- 1b248c02 - Fix memory wiping on Linux with systemdClean System - Memory on a Linux system with systemd. Example: Ubuntu 26.04
- edba5e55 - Do not count SwapCached as free memoryRun `python3 bleachbit.py --clean system.memory --debug` and note the `Physical free memory is X` line. Separately compute the expected value from the MemFree and Cached lines of `/proc/meminfo` (e.g. `awk '/^(MemFree|Cached):/{s+=$2} END{print s*1024}' /proc/meminfo`). The reported value should match and should NOT include the SwapCached line, which previously inflated it.
- 5deea38a - Fix crash when enumerating running processes on Linux caused by non-numeric /proc entries such as /proc/self and /proc/thread-selfOn Linux, run a preview or operation that enumerates running processes and confirm it does not crash
- 72f22fd2 - Handle vanishing file while checking open files
- b57347f6 - Escape literal dots in the keep-list (whitelist) regexes to improve precision of pattern matching
- d64da3ce - Relay error from DNF5 (package manager on Fedora, RHEL, and similar distributions)
- 89f7891f - Fix DNF4 freed space parsing to use IEC units
- 0c9d1b7e - Fix apt_autoclean and locale encoding regexes
- 9c6639f7 - Fix incorrect debug message during swap cleaning
- 0c963dc1 - Fix file descriptor leaks when an error occurs while reading /proc/swaps or wiping file contents
- b235ca0e - Fix DNF clean without root permission
- 8608ac50 - Fix overcleaning Chromium if installed from snap
macOS
Added early macOS-specific cleaner support and improved compatibility, path handling, username detection, synchronization, and automated testing.
- ae425231 - Add early support for macOS-specific cleaners
- 16a2fb9a - Switch macOS path protection to case-insensitive
- af25daad - Create .zshrc to pass test_expanduser()
- 2b4cccb8 - Fix get_real_username() on macOS
- 7739d843 - Fix sed call in Makefile for BSD
- 03e4209a - Add GitHub Actions workflow for macOS
- 07fa7588 - Filter urllib3 warning about OpenSSL vs LibreSSL
- 007fb58f - Fix sync() for macOS
- afa8b4b6 - Fix low-level code to run on macOS
- a68b2983 - Use absolute path for vm_stat on macOS
BSD
Improved FreeBSD support and testing infrastructure while improving portability in dependency installation, shell detection, Makefiles, and SQL.
Developers
Modernized CI/CD across Windows, macOS, and Linux with faster builds and tests, stronger security analysis, improved warnings coverage, refactoring, and translation testing
- 2537230e - Set PYTHONWARNINGS in local Docker with Python 3.14 environment: catch more warnings during testing
- 051614a5 - Fix DeprecationWarning in GTK GUI when PYTHONWARNINGS=error is setSet PYTHONWARNINGS=error and run GTK GUI
- c9357cd6 - Use fast build mode for Windows builds, which disables English-only installer and size optimizations for CI builds found on download.bleachbit.org/ci/
- 4db395c4 - Windows build: run UPX compression as parallel batches
- 10391fe6 - CI: parallelize windows-test admin suite with pytest-xdist
- 2554f303 - Skip building English-only installer to upload to https://download.bleachbit.org/ci/ except for tags (releases)
- 66b1afd8 - Test also Ubuntu 26.04, swap Python 3.12 for 3.13
- 24a0a758 - Streamline usage of "IS_*" system constants across the codebase
- 6c36b05f - Add zimzor workflow, a static analysis tool for CI/CD systems
- f536e6a0 - Fix potential code injection in CI during translation update
- be17f0da - Optimize Windows pip caching and suppress version check
- 25b610cf - CI: switch from AppVeyor to GitHub Actions for Windows
- 8eaf5820 - Refactor some functions from FileUtilities and ProtectedPath to PathUtils
- 5a43044a - Improve security of GitHub workflows
- dd409c20 - Add CodeQL workflow for finding bugs
- 0bb842bc - Add macOS support to script for installing dependencies
- 181a7bb6 - Add translation (.po) tests
- b9d10179 - Add pytest-rerunfailures to retry flaky clipboard test
For more info, see also commit log (since 6.0.2), list of closed issues (fixed in 6.0.3).
Downloads
Downloads are available at download.bleachbit.org and SourceForge.
Linux users can download .deb or .rpm packages, while Windows users can download a digitally signed installer or a portable package.
After testing
If something is broken, please file a bug report.
- andrew's blog
- Log in or register to post comments