1import{j as e}from"./index-0qbe4j-K.js";import{P as s}from"./prose-CP3GO64z.js";import{L as t}from"./react-vendor-CuqwDvgQ.js";function a(){return e.jsxs(s,{children:[e.jsxs("p",{children:[e.jsx("code",{children:"chmod 777"})," is the most reliable way to make an error message go away and the most reliable way to create a finding in the next audit. It is worth ten minutes to understand what the numbers say, because the alternative is guessing with a command that never refuses."]}),e.jsx("h3",{children:"Three digits, three audiences"}),e.jsx("p",{children:"Each digit is a sum: read is 4, write is 2, execute is 1. The digits are owner, group, everyone else - in that order."}),e.jsxs("p",{children:["So ",e.jsx("code",{children:"640"})," is owner read+write, group read, everyone else nothing. And"," ",e.jsx("code",{children:"777"})," is everyone can do everything, which on a shared host means every other account on that machine."]}),e.jsxs("p",{children:["The symbolic form says the same thing: ",e.jsx("code",{children:"-rw-r-----"})," is the leading file-type character, then three groups of three. The"," ",e.jsx(t,{to:"/tools/chmod-calculator",children:"chmod Calculator"})," converts either way, which is faster than second-guessing the arithmetic on a production box."]}),e.jsx("h3",{children:"Execute means something different on a directory"}),e.jsxs("p",{children:['This is the part that produces "permission denied" on a file that is clearly readable. On a directory, execute means ',e.jsx("em",{children:"traverse"})," - the right to enter it and reach what is inside."]}),e.jsx("p",{children:"A directory with read but not execute lets you list the names and open none of them. A directory with execute but not read lets you open a file whose name you already know while being unable to list the contents - which is occasionally exactly what you want."}),e.jsx("h3",{children:"The permissions that actually matter"}),e.jsxs("ul",{children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Private keys: 600."})," SSH refuses to use a key that others can read, and it is right to. A key at ",e.jsx("code",{children:"644"})," is readable by every account on the machine."]}),e.jsxs("li",{children:[e.jsxs("strong",{children:[e.jsx("code",{children:".env"})," and config with secrets: 600."]})," The default umask often produces ",e.jsx("code",{children:"644"}),", so this is a thing you have to do rather than a thing that happens."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Directories you own: 755."})," Traversable by others, writable only by you."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Anything world-writable: almost never."})," A ",e.jsx("code",{children:"2"})," in the last digit means any user can change the contents."]})]}),e.jsx("h3",{children:"Why 777 keeps happening"}),e.jsxs("p",{children:["Because it works. A process cannot read a file, someone runs ",e.jsx("code",{children:"chmod -R 777"}),", the error stops, and the problem is now invisible rather than solved - and it stays that way until an audit or an incident finds it."]}),e.jsxs("p",{children:["The actual fix is nearly always ownership rather than permissions: the process runs as a user that should own the file, so ",e.jsx("code",{children:"chown"}),' is the right command. Permissions describe what different people may do; they are not a way to say "let this one service in".']}),e.jsx("h3",{children:"Permissions are not encryption"}),e.jsxs("p",{children:["A file at ",e.jsx("code",{children:"600"})," is protected by the operating system's willingness to enforce it. Anyone with root, physical access, or a copy of the disk reads it regardless."]}),e.jsxs("p",{children:["So permissions are the right control for a running system and the wrong one for a file leaving it. For that, encrypt it - see"," ",e.jsx(t,{to:"/learn/encrypting-a-file-you-have-to-send",children:"encrypting a file you have to send"}),". And if a private key has been sitting at ",e.jsx("code",{children:"644"})," on a shared machine, treat it the way you would treat any exposed credential: replace it with a fresh one from the"," ",e.jsx(t,{to:"/tools/ssh-key-generator",children:"SSH Key Generator"})," and remove the old public key everywhere it was authorised."]})]})}export{a as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.