I'd like to recursively find all files in my public_html
folder that are not publicly readable (i.e. those files that will cause 403 error). Is there a quick bash command for that? I am using Linux servers running apache, if that is relevant. Thanks.
The -perm parameter of the find command can be used to find the files with specific permissions. The 2 ways to specify the permissions with the -perm parameter are : -perm -mode --- All of the permission bits mode are set for the file. -perm /mode --- Any of the permission bits mode are set for the file.
Alternatively referred to as recursive, recurse is a term used to describe the procedure capable of being repeated. For example, when listing files in a Windows command prompt, you can use the dir /s command to recursively list all files in the current directory and any subdirectories.
To recursively search for a pattern, invoke grep with the -r option (or --recursive ). When this option is used grep will search through all files in the specified directory, skipping the symlinks that are encountered recursively.
Use the find
command:
find . ! -perm -o=r
Will search for files within the current directory and subdirectories that has a file permission so that the "others" group cannot read that file.
The manual page for find
gives some examples of these options.
You can run this command as the www-data
user:
find . ! -readable
To find all files that are NOT readable by the web server.
Note: This answer was originally written while mcleod_ideafix's answer still contained the following broken command: find . -perm -o-r
; the last section of this answer explains why it cannot work.
find . ! -perm -o=r
.
)
-type f
.!
) have the read permission (r
) set for security principal "others (world)" (o
)This works as intended, as long as all files examined were neither created by the user account in whose context the webserver runs nor belong to a group that the web-server account is a member of. Typically, that is the case.
The above command is POSIX-compliant.
mcleod_ideafix's answer offers a more robust option available with GNU find
's (nonstandard) -readable
test:
When run in the context of the webserver's user account (on Linux, www-data
), this will only match files and directories that the webserver effectively cannot read, irrespective of what user and group own the file:
sudo -u www-data find . ! -readable -prune
Note that the -prune
prevents attempts to descend into unreadable subdirectories and thereby suppresses warnings.
sudo -u www-data find . ! -readable \( -type f -print -o -prune \)
As for what doesn't work:
find . -perm 700
and find . -perm 600
will only match files with that exact mode (700
translates to u=rwx,go=
, 600
to u=rw,go=
), so you'd have to construct commands for all possible variations for the user and group permissions to find all matches of interest.find . -perm -o-r
is fundamentally broken and invariably matches any file or directory:
-
prefix of the value passed to -perm
specifies that all the permissions that follow be set in matching files.-perm
only allows positive matching of permissions (what IS set as opposed to what's NOT set), so it is fundamentally impossible to express "match only if this permission is NOT set" logic with just a -perm
argument only.
-r
is syntactically supported (because it is valid chmod
syntax), it is pointless here and results in a no-op.-o-r
tells -perm
to subtract (remove) the read-permission bit for "others" from the starting value of the mode mask used for matching; since that starting value is 000
, or, symbolically, a=
, any attempt to subtract permissions from that will be a no-op, i.e., have no effect. To put it in the immortal words of Billy Preston and Bruce Fisher: Nothin' from nothin' leaves nothin'
-perm
itself match positively (-perm -o=r
), and then negate the result by placing find
's negation operator, !
, before it.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With