A permission is an allowed action or access right. Security improves when each user, process, and component receives only what it needs, rather than unlimited access. This is the principle of least privilege: limit authority so a compromised account or injected code can cause less damage. section 4.15 section 5.2
Apply permissions at several layers:
- Run the web server as a nonroot user that can reach only required code, configuration, assets, and directories. section 4.15
- Use a database account that can read and write required data without being able to alter table structures. section 4.15
- Restrict browser JavaScript access to cookies and set a content security policy. section 4.15
- Split sensitive responsibilities among roles, and grant server or database-change privileges only for a short time when possible. section 5.2
Authorization rules turn permissions into an application policy: identify user categories, then state what each category can and cannot do. Keep those rules documented outside the codebase and update them as features change, because small authorization changes can significantly affect users. section 10.5
Prevent an uploaded web shell
An uploaded script can become a remote command tool if the server writes it where it can run. Validate uploads and save files with read-write permissions, not executable permissions. Also prevent the web server from executing files in directories that accept uploads. section 11.12 section 11.16
@app.route('/upload', methods=['POST'])
def upload_file():
file = request.files['file']
file_path = os.path.join(
app.config['UPLOAD_FOLDER'], file.filename)
file.save(filepath)
os.chmod(file_path, 0o644) #1
return jsonify({'message': 'Upload successful'}), 200
#1 This “change mode” command allows all operating system account users to read the file but gives none of them execute permissions.
This upload handler saves a file with mode 0o644, allowing reads but no execution; compare it with executable upload permissions to see the safer default. section 11.12



