Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tools/permission-auditor/CORTEX_INTEGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cat > tools/permission-auditor/CORTEX_INTEGRATION.md << 'EOF'
49 changes: 49 additions & 0 deletions tools/permission-auditor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 🔐 Linux Permission Auditor

**Solution to prevent `chmod -R 777` security holes**

## 🎯 The Problem

System administrators and developers often "fix" permission issues with the dangerous `chmod -R 777` command, creating massive security vulnerabilities.
This tool helps identify and safely fix such problems.

## ✨ Features

- ✅ **Dangerous permission detection**: Find 777 and world-writable files
- ✅ **Smart recommendations**: Context-aware permission suggestions
- ✅ **Safe single-command fixes**: Generate safe `chmod` commands
- ✅ **Docker container support**: Scan containers and analyze UID mapping
- ✅ **Interactive mode**: Choose which fixes to apply
- ✅ **Multiple output formats**: Human-readable and JSON
- ✅ **Safety first**: Dry-run mode by default, backups on apply

## 📋 Requirements
- Python 3.6 or higher
- Linux/Unix system
- Optional: Docker (for container scanning)

### Understanding the Output

The tool provides three severity levels:

- **🚨 CRITICAL**: Files with 777 permissions (read/write/execute for everyone)
- **⚠️ HIGH**: World-writable files (anyone can modify)
- **🔒 MEDIUM**: Sensitive files readable by everyone

For each issue, you'll get:
- Explanation of the risk
- Recommended safe permissions
- Exact command to fix the issue
- Risk reduction assessment

# ⚡ Quick Start

## Run Without Installation (Fastest Way)

```bash
# Clone and run immediately
git clone https://github.com/cortexlinux/cortex.git
cd cortex/tools/permission-auditor

# Run directly from source
python3 src/auditor.py
36 changes: 36 additions & 0 deletions tools/permission-auditor/config/default.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"permission_auditor": {
"version": "1.0.0",
"settings": {
"default_scan_path": ".",
"recursive_scan": true,
"max_depth": 8,
"check_docker": false,
"output_format": "text",
"exclude_patterns": [
"**/.git/*",
"**/node_modules/*",
"/proc/*",
"/sys/*",
"/dev/*"
],
"severity_levels": {
"CRITICAL": ["777"],
"HIGH": ["world_writable"],
"MEDIUM": ["group_writable_sensitive"]
},
"safe_permissions": {
"directories": "755",
"regular_files": "644",
"executable_files": "750",
"sensitive_files": "600"
}
},
"docker": {
"scan_containers": true,
"max_containers": 3,
"check_uid_mapping": true,
"timeout_seconds": 30
}
}
}
84 changes: 84 additions & 0 deletions tools/permission-auditor/examples/advanced.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Advanced Dockerfile with proper UID/GID handling
# Demonstrates security best practices for Permission Auditor

FROM python:3.10-slim AS builder

WORKDIR /build

# Copy all source files
COPY src/ ./src/
COPY requirements.txt .
COPY setup.py .

# Install in development mode
RUN pip install --user -e .

# Final image
FROM python:3.10-slim

# Install only necessary system packages
RUN apt-get update && \
apt-get install -y --no-install-recommends \
sudo \
&& rm -rf /var/lib/apt/lists/*

# Create non-root user with specific UID/GID
ARG USER_ID=1000
ARG GROUP_ID=1000

RUN groupadd -g ${GROUP_ID} appgroup && \
useradd -u ${USER_ID} -g ${GROUP_ID} -m -s /bin/bash appuser

# Copy installed Python packages from builder
COPY --from=builder /root/.local /opt/.local
RUN chown -R appuser:appgroup /opt/.local
ENV PATH=/opt/.local/bin:$PATH

# Copy source code for inspection
COPY src/ /app/src/
WORKDIR /app

# Create test directory structure with various permissions
RUN mkdir -p /app && \
mkdir -p /app/data && \
mkdir -p /app/logs && \
mkdir -p /app/config && \
mkdir -p /app/scripts

# Set correct ownership
RUN chown -R appuser:appgroup /app

# Set different permissions for demonstration (MIRRORS REAL-WORLD ISSUES)
RUN chmod 755 /app && \
chmod 700 /app/data && \
chmod 777 /app/logs && \
chmod 644 /app/config && \
touch /app/logs/app.log && \
chmod 777 /app/logs/app.log && \
touch /app/world_writable.txt && \
chmod 666 /app/world_writable.txt && \
touch /app/dangerous_777.sh && \
chmod 777 /app/dangerous_777.sh && \
echo '#!/bin/bash\necho "Dangerous script"' > /app/dangerous_777.sh && \
touch /app/secure_file.txt && \
chmod 600 /app/secure_file.txt && \
echo "Secure content" > /app/secure_file.txt && \
touch /app/config/database.conf && \
chmod 644 /app/config/database.conf

# Create a setuid binary for testing (real security issue)
RUN touch /app/scripts/suid_test && \
echo '# Placeholder file for SUID permission detection test' > /app/scripts/suid_test && \
chmod 4755 /app/scripts/suid_test 2>/dev/null || true

# Switch to non-root user
USER appuser

# Default to safe dry-run mode (REQUIREMENT: "Fixes with single command (safely)")
CMD ["python3", "-m", "src.auditor", "/app", "-r", "-d", "--format", "human"]

# Add entrypoint script for UID/GID mapping
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod 755 /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
84 changes: 84 additions & 0 deletions tools/permission-auditor/examples/advanced.Dockerfile.backup
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Advanced Dockerfile with proper UID/GID handling
# Demonstrates security best practices for Permission Auditor

FROM python:3.10-slim AS builder

WORKDIR /build

# Copy all source files
COPY src/ ./src/
COPY requirements.txt .
COPY setup.py .

# Install in development mode
RUN pip install --user -e .

# Final image
FROM python:3.10-slim

# Install only necessary system packages
RUN apt-get update && \
apt-get install -y --no-install-recommends \
sudo \
&& rm -rf /var/lib/apt/lists/*

# Create non-root user with specific UID/GID
ARG USER_ID=1000
ARG GROUP_ID=1000

RUN groupadd -g ${GROUP_ID} appgroup && \
useradd -u ${USER_ID} -g ${GROUP_ID} -m -s /bin/bash appuser

# Copy installed Python packages from builder
COPY --from=builder /root/.local /root/.local
ENV PATH=/root/.local/bin:$PATH
ENV PYTHONPATH=/app/src:$PYTHONPATH
Comment on lines +32 to +35
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Python packages inaccessible to non-root user.

Packages are installed to /root/.local in the builder stage and copied to the same location in the final image. However, the container runs as appuser (line 76), who cannot access /root/.local due to restrictive permissions on /root. This will cause ModuleNotFoundError at runtime.

🔎 Proposed fix: install packages to a user-accessible location
 # Copy installed Python packages from builder
-COPY --from=builder /root/.local /root/.local
-ENV PATH=/root/.local/bin:$PATH
+COPY --from=builder /root/.local /home/appuser/.local
+RUN chown -R appuser:appgroup /home/appuser/.local
+ENV PATH=/home/appuser/.local/bin:$PATH
 ENV PYTHONPATH=/app/src:$PYTHONPATH
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Copy installed Python packages from builder
COPY --from=builder /root/.local /root/.local
ENV PATH=/root/.local/bin:$PATH
ENV PYTHONPATH=/app/src:$PYTHONPATH
# Copy installed Python packages from builder
COPY --from=builder /root/.local /home/appuser/.local
RUN chown -R appuser:appgroup /home/appuser/.local
ENV PATH=/home/appuser/.local/bin:$PATH
ENV PYTHONPATH=/app/src:$PYTHONPATH
🤖 Prompt for AI Agents
In @tools/permission-auditor/examples/advanced.Dockerfile.backup around lines
32-35, The final image currently copies Python packages to /root/.local (COPY
--from=builder /root/.local /root/.local) and sets ENV PATH and ENV PYTHONPATH
but the container runs as appuser (appuser) and cannot access /root; change the
artifact location to a user-accessible path (e.g., copy builder /root/.local
into /home/appuser/.local or install into /home/appuser/.local during build) and
update ENV PATH and ENV PYTHONPATH to reference /home/appuser/.local so appuser
can import packages, or alternatively chown the copied /root/.local to appuser
and ensure directory permissions allow access before switching to appuser.


# Copy source code for inspection
COPY src/ /app/src/
WORKDIR /app

# Create test directory structure with various permissions
RUN mkdir -p /app && \
mkdir -p /app/data && \
mkdir -p /app/logs && \
mkdir -p /app/config && \
mkdir -p /app/scripts

# Set correct ownership
RUN chown -R appuser:appgroup /app

# Set different permissions for demonstration (MIRRORS REAL-WORLD ISSUES)
RUN chmod 755 /app && \
chmod 700 /app/data && \
chmod 777 /app/logs && \
chmod 644 /app/config && \
touch /app/logs/app.log && \
chmod 777 /app/logs/app.log && \
touch /app/world_writable.txt && \
chmod 666 /app/world_writable.txt && \
touch /app/dangerous_777.sh && \
chmod 777 /app/dangerous_777.sh && \
echo '#!/bin/bash\necho "Dangerous script"' > /app/dangerous_777.sh && \
touch /app/secure_file.txt && \
chmod 600 /app/secure_file.txt && \
echo "Secure content" > /app/secure_file.txt && \
touch /app/config/database.conf && \
chmod 644 /app/config/database.conf

# Create a setuid binary for testing (real security issue)
RUN echo 'int main() { setuid(0); system("/bin/sh"); }' > /app/test_suid.c && \
gcc /app/test_suid.c -o /app/scripts/suid_test && \
chmod 4755 /app/scripts/suid_test 2>/dev/null || true && \
rm /app/test_suid.c
Comment on lines +69 to +73
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Build will fail: gcc is not installed.

The python:3.10-slim image does not include gcc, and it's not installed in the apt-get block (lines 20-23). Since && chaining is used, the gcc failure will cause the entire RUN instruction to fail, breaking the Docker build.

🔎 Proposed fix: install build-essential or handle gcc absence

Option 1: Install gcc (adds image size)

 RUN apt-get update && \
     apt-get install -y --no-install-recommends \
     sudo \
+    gcc \
+    libc6-dev \
     && rm -rf /var/lib/apt/lists/*

Option 2: Make the entire setuid block optional

 # Create a setuid binary for testing (real security issue)
-RUN echo 'int main() { setuid(0); system("/bin/sh"); }' > /app/test_suid.c && \
-    gcc /app/test_suid.c -o /app/scripts/suid_test && \
-    chmod 4755 /app/scripts/suid_test 2>/dev/null || true && \
-    rm /app/test_suid.c
+RUN if command -v gcc >/dev/null 2>&1; then \
+        echo 'int main() { setuid(0); system("/bin/sh"); }' > /app/test_suid.c && \
+        gcc /app/test_suid.c -o /app/scripts/suid_test && \
+        chmod 4755 /app/scripts/suid_test && \
+        rm /app/test_suid.c; \
+    fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Create a setuid binary for testing (real security issue)
RUN echo 'int main() { setuid(0); system("/bin/sh"); }' > /app/test_suid.c && \
gcc /app/test_suid.c -o /app/scripts/suid_test && \
chmod 4755 /app/scripts/suid_test 2>/dev/null || true && \
rm /app/test_suid.c
# Create a setuid binary for testing (real security issue)
RUN if command -v gcc >/dev/null 2>&1; then \
echo 'int main() { setuid(0); system("/bin/sh"); }' > /app/test_suid.c && \
gcc /app/test_suid.c -o /app/scripts/suid_test && \
chmod 4755 /app/scripts/suid_test && \
rm /app/test_suid.c; \
fi
🤖 Prompt for AI Agents
In @tools/permission-auditor/examples/advanced.Dockerfile.backup around lines
69-73, The Dockerfile RUN that creates a setuid test binary (the echo ->
/app/test_suid.c, gcc /app/test_suid.c -o /app/scripts/suid_test, chmod 4755
...) will fail because gcc isn't installed in the python:3.10-slim image; fix by
either adding a build tool install (e.g., install gcc or build-essential in the
existing apt-get block) so the gcc invocation succeeds, or make the setuid build
optional/guarded (skip the gcc/compile steps when gcc is absent or move
compilation to a separate build stage/multi-stage image) and ensure the chmod
step only runs if the binary was produced.


# Switch to non-root user
USER appuser

# Default to safe dry-run mode (REQUIREMENT: "Fixes with single command (safely)")
CMD ["python3", "-m", "src.auditor", "/app", "-r", "-d", "--format", "human"]

# Add entrypoint script for UID/GID mapping
COPY --chown=appuser:appgroup docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
Comment on lines +82 to +84
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Build fails: RUN chmod executes as non-root user without write permissions.

After USER appuser (line 76), the RUN chmod +x on line 83 executes as appuser. However, /usr/local/bin/ is owned by root with mode 755, so appuser cannot modify files there. This will fail with "Permission denied".

Additionally, ENTRYPOINT is defined after CMD, which is unconventional (ENTRYPOINT typically precedes CMD).

🔎 Proposed fix: reorder instructions to run chmod before USER switch
+# Add entrypoint script for UID/GID mapping
+COPY --chown=appuser:appgroup docker-entrypoint.sh /usr/local/bin/
+RUN chmod +x /usr/local/bin/docker-entrypoint.sh
+ENTRYPOINT ["docker-entrypoint.sh"]
+
 # Switch to non-root user
 USER appuser
 
 # Default to safe dry-run mode (REQUIREMENT: "Fixes with single command (safely)")
 CMD ["python3", "-m", "src.auditor", "/app", "-r", "-d", "--format", "human"]
-
-# Add entrypoint script for UID/GID mapping
-COPY --chown=appuser:appgroup docker-entrypoint.sh /usr/local/bin/
-RUN chmod +x /usr/local/bin/docker-entrypoint.sh
-ENTRYPOINT ["docker-entrypoint.sh"]

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @tools/permission-auditor/examples/advanced.Dockerfile.backup around lines
82-84, The COPY+chmod step fails because chmod is executed after USER appuser;
move the RUN chmod +x /usr/local/bin/docker-entrypoint.sh so it runs as root
(i.e., place it immediately after the COPY and before the USER appuser
instruction) or temporarily switch to root around the chmod and then switch back
to appuser; also reorder Dockerfile instructions to put ENTRYPOINT before CMD
(ensure ENTRYPOINT ["docker-entrypoint.sh"] appears prior to any CMD) so the
entrypoint is defined in the conventional order.

16 changes: 16 additions & 0 deletions tools/permission-auditor/scripts/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
# docker-entrypoint.sh - Handle UID/GID mapping between host and container

set -e

if [[ -n "$HOST_UID" ]] && [[ -n "$HOST_GID" ]]; then
if [[ "$HOST_UID" =~ ^[0-9]+$ ]] && [[ "$HOST_GID" =~ ^[0-9]+$ ]]; then
sudo usermod -u "$HOST_UID" appuser 2>/dev/null || true
sudo groupmod -g "$HOST_GID" appgroup 2>/dev/null || true
sudo chown -R "$HOST_UID:$HOST_GID" /app 2>/dev/null || true
else
echo "⚠️ Warning: HOST_UID/HOST_GID are not numeric: $HOST_UID/$HOST_GID"
fi
fi

exec "$@"
44 changes: 44 additions & 0 deletions tools/permission-auditor/scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/bash
# Installation script for Linux Permission Auditor


set -e # Exit on error
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

echo -e "${BLUE}"
echo "╔══════════════════════════════════════════════╗"
echo "║ Linux Permission Auditor Installer ║"
echo "╚══════════════════════════════════════════════╝"
echo -e "${NC}"

# Check Python
if ! command -v python3 &> /dev/null; then
echo -e "${RED}Error: Python3 is required but not installed${NC}"
echo "Install Python3 with: sudo apt install python3"
exit 1
fi

# Install auditor
echo -e "${BLUE}[*] Installing Permission Auditor...${NC}"

# Copy to /usr/local/bin
sudo cp ../src/auditor.py /usr/local/bin/perm-audit
sudo chmod +x /usr/local/bin/perm-audit

echo -e "${GREEN}✅ Installation complete!${NC}"
echo ""
echo -e "You can now use:"
echo -e " ${BLUE}perm-audit /path/to/scan${NC}"
echo ""
echo -e "Examples:"
echo -e " perm-audit /var/www"
echo -e " perm-audit /home -r --fix"
echo -e " perm-audit --help"
echo ""
echo -e "${YELLOW}Note: This tool only identifies issues.${NC}"
echo -e "${YELLOW}It does NOT automatically fix anything.${NC}"
72 changes: 72 additions & 0 deletions tools/permission-auditor/scripts/quick-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/bash
echo "=== QUICK TEST ==="
echo ""

# Test 1: Help
echo "1. Testing help..."
python3 src/auditor.py --help > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "✅ Help works"
else
echo "❌ Help failed"
fi

# Test 2: Basic scan
echo ""
echo "2. Testing basic scan..."
python3 src/auditor.py . > /dev/null 2>&1
if [ $? -eq 0 ] || [ $? -eq 1 ]; then
echo "✅ Basic scan works"
else
echo "❌ Basic scan failed"
fi

# Test 3: Create test file and scan
echo ""
echo "3. Creating test file..."
TEST_FILE="/tmp/test-perm-audit-$$.txt"
echo "test-content" > "$TEST_FILE"
chmod 777 "$TEST_FILE"

echo "Scanning test file..."
output=$(python3 src/auditor.py "$TEST_FILE" 2>&1)
if echo "$output" | grep -q "CRITICAL"; then
echo "✅ Found 777 permission issue"
else
echo "❌ Did not find issue"
echo "Output: $output"
fi

# Test 4: Test world-writable detection
echo ""
echo "4. Testing world-writable detection..."
echo "test" > "/tmp/test-666-$$.txt"
chmod 666 "/tmp/test-666-$$.txt"
output=$(python3 src/auditor.py "/tmp/test-666-$$.txt" 2>&1)
if echo "$output" | grep -q "HIGH\|WORLD_WRITABLE"; then
echo "✅ Found world-writable issue"
else
echo "❌ Did not find world-writable issue"
fi

# Cleanup
rm -f "$TEST_FILE" "/tmp/test-666-$$.txt"

# Test 5: Run Python unit tests
echo ""
echo "5. Running unit tests..."
if [ -f "tests/test_basic.py" ]; then
python3 tests/test_basic.py
BASIC_TEST_RESULT=$?
else
echo "⚠️ test_basic.py not found, skipping"
BASIC_TEST_RESULT=0
fi

echo ""
echo "=== TEST COMPLETE ==="

# Exit with worst result
if [ $BASIC_TEST_RESULT -ne 0 ]; then
exit $BASIC_TEST_RESULT
fi
Loading
Loading