Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

595 lines
22 KiB
Bash
Executable File

#!/bin/bash
# File Whitelist Security Check Script
# Enhanced security checks with comprehensive file type detection
set -euo pipefail
# Load allowed file patterns from shared whitelist (single source of truth)
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo ".")"
WHITELIST_FILE="$REPO_ROOT/.file-whitelist.txt"
if [ ! -f "$WHITELIST_FILE" ]; then
echo "❌ Missing .file-whitelist.txt — cannot run whitelist check."
exit 1
fi
ALLOWED_PATTERNS=()
while IFS= read -r line; do
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
ALLOWED_PATTERNS+=("$line")
done < "$WHITELIST_FILE"
# Load per-check ignore lists (exact paths to skip for specific checks)
IGNORE_ENV_FILES=()
IGNORE_ENV_FILE="$REPO_ROOT/.github/security/ignore-env-files.txt"
if [ -f "$IGNORE_ENV_FILE" ]; then
while IFS= read -r line; do
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
IGNORE_ENV_FILES+=("$line")
done < "$IGNORE_ENV_FILE"
fi
IGNORE_SUSPICIOUS_FILETYPES=()
IGNORE_SUSPICIOUS_FILE="$REPO_ROOT/.github/security/ignore-suspicious-filetypes.txt"
if [ -f "$IGNORE_SUSPICIOUS_FILE" ]; then
while IFS= read -r line; do
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
IGNORE_SUSPICIOUS_FILETYPES+=("$line")
done < "$IGNORE_SUSPICIOUS_FILE"
fi
# Get list of files to check
if [ "${CHECK_ALL_FILES:-}" = "true" ]; then
echo "🔍 Checking ALL tracked files (release gate mode)..."
CHANGED_FILES=$(git ls-files)
TOTAL_FILE_COUNT=$(echo "$CHANGED_FILES" | wc -l)
echo "📋 Found $TOTAL_FILE_COUNT tracked files to check"
elif [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
# For PRs: check all files that would be added/modified in the entire PR
echo "🔍 Checking files in PR from $GITHUB_BASE_REF to HEAD..."
CHANGED_FILES=$(git diff --name-only --diff-filter=AM origin/"$GITHUB_BASE_REF"..HEAD)
FILE_COUNT=$(echo "$CHANGED_FILES" | wc -l)
echo "📋 Found $FILE_COUNT changed files with git diff"
# Also get newly added files across all commits in the PR
# Use a more robust approach that handles edge cases
ALL_NEW_FILES=$(git log --name-only --pretty=format: --diff-filter=A origin/"$GITHUB_BASE_REF"..HEAD 2>/dev/null | grep -v '^$' | sort | uniq || echo "")
NEW_FILE_COUNT=$(echo "$ALL_NEW_FILES" | wc -w)
echo "📋 Found $NEW_FILE_COUNT newly added files with git log"
# Combine both lists and remove duplicates - handle empty ALL_NEW_FILES
if [ -n "$ALL_NEW_FILES" ]; then
CHANGED_FILES=$(echo -e "$CHANGED_FILES\n$ALL_NEW_FILES" | sort | uniq | grep -v '^$')
fi
TOTAL_FILE_COUNT=$(echo "$CHANGED_FILES" | wc -l)
echo "📋 Total unique files to check: $TOTAL_FILE_COUNT"
else
# For direct pushes: check files in the current commit
echo "🔍 Checking files in latest commit..."
CHANGED_FILES=$(git diff --name-only --diff-filter=AM HEAD~1..HEAD)
TOTAL_FILE_COUNT=$(echo "$CHANGED_FILES" | wc -l)
echo "📋 Found $TOTAL_FILE_COUNT files in direct push"
fi
echo "🔍 Running comprehensive security checks..."
echo ""
FILES_CHECKED=0
WHITELIST_VIOLATIONS=()
LARGE_FILES=()
BINARY_FILES=()
SUSPICIOUS_FILES=()
RESEARCH_DATA_VIOLATIONS=()
FLASK_SECRET_VIOLATIONS=()
ENV_FILE_VIOLATIONS=()
HIGH_ENTROPY_VIOLATIONS=()
HARDCODED_PATH_VIOLATIONS=()
HARDCODED_IP_VIOLATIONS=()
SUSPICIOUS_FILETYPE_VIOLATIONS=()
# Use improved file processing that handles spaces and special characters
while IFS= read -r file; do
[ -z "$file" ] && continue
# Skip deleted files
if [ ! -f "$file" ]; then
continue
fi
FILES_CHECKED=$((FILES_CHECKED + 1))
if [ $((FILES_CHECKED % 10)) -eq 0 ]; then
printf "."
fi
# 1. Whitelist check
ALLOWED=false
for pattern in "${ALLOWED_PATTERNS[@]}"; do
if echo "$file" | grep -qE "$pattern"; then
ALLOWED=true
break
fi
done
if [ "$ALLOWED" = "false" ]; then
WHITELIST_VIOLATIONS+=("$file")
fi
# 2. Large file check (>1MB)
if [ -f "$file" ]; then
FILE_SIZE=$(stat -c%s "$file" 2>/dev/null || echo 0)
if [ "$FILE_SIZE" -gt 1048576 ]; then
LARGE_FILES+=("$file ($(echo "$FILE_SIZE" | awk '{printf "%.1fMB", $1/1024/1024}'))")
fi
fi
# 3. Binary file check
if file "$file" | grep -q "binary"; then
BINARY_FILES+=("$file")
fi
# 4. Secret pattern check - REMOVED: gitleaks workflow handles this more accurately
# 5. Suspicious filename patterns - whitelist approach
SAFE_FILENAME_PATTERNS=(
".*token_counter.*\.py$"
".*migrate.*token.*\.py$"
".*enhanced.*token.*\.md$"
"docs/.*token.*\.md$"
"tests/.*\.py$"
"docs/decisions/.*\.md$"
".*session_passwords\.py$"
".*change_password\.html$"
"tests/ui_tests/.*password.*\.js$"
".*password_validator\.py$"
".*password_utils\.py$"
)
# Check if filename looks suspicious
if echo "$file" | grep -iE "(secret|password|token|\.key$|\.pem$|\.p12$|\.pfx$|\.env$)" >/dev/null; then
# Check if filename matches whitelist patterns
FILENAME_WHITELISTED=false
for pattern in "${SAFE_FILENAME_PATTERNS[@]}"; do
if echo "$file" | grep -qE "$pattern"; then
FILENAME_WHITELISTED=true
break
fi
done
if [ "$FILENAME_WHITELISTED" = "false" ]; then
SUSPICIOUS_FILES+=("$file")
fi
fi
# 6. LDR-specific security checks
# Check for research data leakage
if [ -f "$file" ] && [ -r "$file" ]; then
# Check for hardcoded research queries in non-test files
if ! echo "$file" | grep -qE "(test|mock|example)"; then
if grep -E "(research_id|session_id|query_id).*=.*[\"'][0-9a-f]{8,}[\"']" "$file" >/dev/null 2>&1; then
RESEARCH_DATA_VIOLATIONS+=("$file")
fi
fi
# Check for Flask secret keys
if grep -E "SECRET_KEY.*=.*[\"'][^\"']{16,}[\"']" "$file" >/dev/null 2>&1; then
if ! grep -iE "(os\.environ|getenv|config\[|example|placeholder)" "$file" >/dev/null 2>&1; then
FLASK_SECRET_VIOLATIONS+=("$file")
fi
fi
# Check for environment files
if echo "$file" | grep -E "\.(env|env\.[a-zA-Z]+)$" >/dev/null; then
ENV_IGNORED=false
for epath in "${IGNORE_ENV_FILES[@]+${IGNORE_ENV_FILES[@]}}"; do
[ "$file" = "$epath" ] && ENV_IGNORED=true && break
done
if [ "$ENV_IGNORED" = "false" ]; then
ENV_FILE_VIOLATIONS+=("$file")
fi
fi
# Check for high-entropy strings (potential keys/secrets)
if [ -f "$file" ] && [ -r "$file" ]; then
# Skip HTML files and other safe file types for entropy checks
if ! echo "$file" | grep -qE "\.(html|css|js|json|yml|yaml|md)$"; then
# Skip news_strategy.py which contains example categories in prompts
if ! echo "$file" | grep -qE "news_strategy\.py$"; then
# Look for base64-like strings or hex strings that are suspiciously long
if grep -E "[a-zA-Z0-9+/]{40,}={0,2}|[a-f0-9]{40,}" "$file" >/dev/null 2>&1; then
# Exclude common false positives
if ! grep -iE "(sha256|md5|hash|test|example|fixture|integrity)" "$file" >/dev/null 2>&1; then
HIGH_ENTROPY_VIOLATIONS+=("$file")
fi
fi
fi
fi
fi
# Check for hardcoded paths (Unix/Windows)
if ! echo "$file" | grep -qE "(test|mock|example|\.md$|docker|Docker|\.yml$|\.yaml$|config/paths\.py$|security/path_validator\.py$)"; then
# Look for absolute paths and user home directories
if grep -E "(/home/[a-zA-Z0-9_-]+|/Users/[a-zA-Z0-9_-]+|C:\\\\Users\\\\[a-zA-Z0-9_-]+|/opt/|/var/|/etc/|/usr/local/)" "$file" >/dev/null 2>&1; then
# Exclude common false positives and Docker volume mounts
if ! grep -iE "(example|sample|placeholder|TODO|FIXME|/usr/local/bin|/etc/hosts|documentation|/etc/searxng|volumes?:|docker)" "$file" >/dev/null 2>&1; then
HARDCODED_PATH_VIOLATIONS+=("$file")
fi
fi
fi
# Check for hardcoded IP addresses
if ! echo "$file" | grep -qE "(test|mock|example|\.md$)"; then
# Look for IPv4 addresses (excluding common safe ones)
if grep -E "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" "$file" >/dev/null 2>&1; then
# Exclude localhost, documentation IPs, and common examples
if ! grep -E "\b(127\.0\.0\.1|0\.0\.0\.0|localhost|192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|255\.255\.255\.|192\.0\.2\.|198\.51\.100\.|203\.0\.113\.)" "$file" >/dev/null 2>&1; then
# Additional check to exclude obvious non-IPs (version numbers, etc)
if grep -E "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" "$file" | grep -vE "(version|v[0-9]+\.|release|tag)" >/dev/null 2>&1; then
HARDCODED_IP_VIOLATIONS+=("$file")
fi
fi
fi
fi
# 7. Suspicious file type check - detect potentially dangerous file types
if [ -f "$file" ]; then
# Check if file is in the suspicious-filetypes ignore list
FILETYPE_IGNORED=false
for fpath in "${IGNORE_SUSPICIOUS_FILETYPES[@]+${IGNORE_SUSPICIOUS_FILETYPES[@]}}"; do
[ "$file" = "$fpath" ] && FILETYPE_IGNORED=true && break
done
if [ "$FILETYPE_IGNORED" = "false" ]; then
# Check for suspicious file extensions
if echo "$file" | grep -iE "\.(exe|dll|so|dylib|bin|deb|rpm|msi|dmg|pkg|app)$" >/dev/null; then
SUSPICIOUS_FILETYPE_VIOLATIONS+=("$file (executable/binary)")
elif echo "$file" | grep -iE "\.(zip|tar|gz|rar|7z|tar\.gz|tar\.bz2|tgz)$" >/dev/null; then
SUSPICIOUS_FILETYPE_VIOLATIONS+=("$file (compressed archive)")
elif echo "$file" | grep -iE "\.(log|tmp|temp|cache|bak|backup|swp|swo|DS_Store|thumbs\.db|desktop\.ini|~|\.orig|\.rej|\.patch)$" >/dev/null; then
SUSPICIOUS_FILETYPE_VIOLATIONS+=("$file (temporary/cache)")
elif echo "$file" | grep -iE "\.(png|jpg|jpeg|gif|bmp|tiff|svg|ico|webp)$" >/dev/null; then
# Images are suspicious unless in specific directories
if ! echo "$file" | grep -qE "(^docs/images/|^src/local_deep_research/web/static/favicon\.png$|^installers/.*\.ico$)"; then
SUSPICIOUS_FILETYPE_VIOLATIONS+=("$file (image file)")
fi
elif echo "$file" | grep -iE "\.(mp3|mp4|wav|avi|mov|mkv|flv|wmv|webm|m4a|ogg)$" >/dev/null; then
SUSPICIOUS_FILETYPE_VIOLATIONS+=("$file (media file)")
elif echo "$file" | grep -iE "\.(csv|xlsx|xls|doc|docx|pdf|ppt|pptx)$" >/dev/null; then
# Documents are suspicious unless in docs directory
if ! echo "$file" | grep -qE "docs/"; then
SUSPICIOUS_FILETYPE_VIOLATIONS+=("$file (document file)")
fi
elif echo "$file" | grep -iE "\.(db|sqlite|sqlite3)$" >/dev/null; then
SUSPICIOUS_FILETYPE_VIOLATIONS+=("$file (database file)")
elif echo "$file" | grep -iE "node_modules/|__pycache__/|\.pyc$|\.pyo$|\.egg-info/|dist/|build/|\.cache/" >/dev/null; then
SUSPICIOUS_FILETYPE_VIOLATIONS+=("$file (build artifact/cache)")
fi
fi
fi
fi
done <<< "$CHANGED_FILES"
echo ""
echo "✓ Checked $FILES_CHECKED files"
echo ""
# Report all violations with detailed explanations
echo "📊 Security scan completed. Analyzing results..."
echo "📋 Summary of findings:"
echo " - File type violations: ${#WHITELIST_VIOLATIONS[@]}"
echo " - Large files: ${#LARGE_FILES[@]}"
echo " - Binary files: ${#BINARY_FILES[@]}"
echo " - Suspicious filenames: ${#SUSPICIOUS_FILES[@]}"
echo " - Research data leaks: ${#RESEARCH_DATA_VIOLATIONS[@]}"
echo " - Hardcoded Flask secrets: ${#FLASK_SECRET_VIOLATIONS[@]}"
echo " - Environment files: ${#ENV_FILE_VIOLATIONS[@]}"
echo " - High-entropy strings: ${#HIGH_ENTROPY_VIOLATIONS[@]}"
echo " - Hardcoded paths: ${#HARDCODED_PATH_VIOLATIONS[@]}"
echo " - Hardcoded IPs: ${#HARDCODED_IP_VIOLATIONS[@]}"
echo " - Suspicious file types: ${#SUSPICIOUS_FILETYPE_VIOLATIONS[@]}"
TOTAL_VIOLATIONS=0
if [ ${#WHITELIST_VIOLATIONS[@]} -gt 0 ]; then
echo ""
echo "❌ WHITELIST VIOLATIONS - File types not allowed in repository:"
echo " These files don't match any pattern in .file-whitelist.txt."
echo " Binary files (images, audio, etc.) bloat the repo and should NOT be committed."
echo " Only a small set of explicitly listed binary files is allowed — store others externally."
echo " If this is a legitimate text/config file, add it to .file-whitelist.txt (requires maintainer approval)."
echo ""
for violation in "${WHITELIST_VIOLATIONS[@]}"; do
echo " 🚫 $violation"
# Show file type and extension
FILE_EXT="${violation##*.}"
if [ -f "$violation" ]; then
FILE_TYPE=$(file -b "$violation" 2>/dev/null || echo "unknown")
echo " → File extension: .$FILE_EXT"
echo " → File type: $FILE_TYPE"
echo " → First few lines:"
head -3 "$violation" 2>/dev/null | while read -r line; do
echo " $line"
done
fi
echo " → Issue: File extension/type not in .file-whitelist.txt"
echo " → Fix: For text/config files, add pattern to .file-whitelist.txt"
echo " → Note: Binary files should NOT be added to the repo — store them externally"
echo ""
done
TOTAL_VIOLATIONS=$((TOTAL_VIOLATIONS + ${#WHITELIST_VIOLATIONS[@]}))
fi
if [ ${#LARGE_FILES[@]} -gt 0 ]; then
echo ""
echo "❌ LARGE FILES (>1MB) - Files too big for repository:"
echo " Large files should typically be stored externally or compressed."
echo ""
for violation in "${LARGE_FILES[@]}"; do
echo " 📏 $violation"
echo " → Issue: File size exceeds 1MB limit"
echo " → Fix: Use Git LFS, external storage, or compress the file"
echo ""
done
TOTAL_VIOLATIONS=$((TOTAL_VIOLATIONS + ${#LARGE_FILES[@]}))
fi
if [ ${#BINARY_FILES[@]} -gt 0 ]; then
echo ""
echo "⚠️ BINARY FILES DETECTED - Review these carefully:"
echo " Binary files may contain sensitive data and can't be easily reviewed."
echo ""
for violation in "${BINARY_FILES[@]}"; do
echo " 🔒 $violation"
echo " → Issue: Binary file detected (contents not reviewable)"
echo " → Action: Verify this file doesn't contain sensitive data"
echo ""
done
fi
if [ ${#SUSPICIOUS_FILES[@]} -gt 0 ]; then
echo ""
echo "❌ SUSPICIOUS FILENAMES - Files with security-sensitive names:"
echo " These filenames contain words that often indicate sensitive files."
echo ""
for violation in "${SUSPICIOUS_FILES[@]}"; do
echo " 🚨 $violation"
# Show which keyword triggered the detection
if echo "$violation" | grep -qi "secret"; then
echo " → Triggered by: 'secret' in filename"
elif echo "$violation" | grep -qi "password"; then
echo " → Triggered by: 'password' in filename"
elif echo "$violation" | grep -qi "token"; then
echo " → Triggered by: 'token' in filename"
elif echo "$violation" | grep -qi "api"; then
echo " → Triggered by: 'api' in filename"
elif echo "$violation" | grep -qi "key"; then
echo " → Triggered by: 'key' in filename"
fi
# Show file content preview if it exists
if [ -f "$violation" ]; then
FILE_TYPE=$(file -b "$violation" 2>/dev/null || echo "unknown")
FILE_SIZE=$(stat -c%s "$violation" 2>/dev/null || echo "unknown")
echo " → File info: $FILE_TYPE (${FILE_SIZE} bytes)"
echo " → Content preview:"
head -3 "$violation" 2>/dev/null | while read -r line; do
echo " $line"
done
fi
echo " → Issue: Filename contains suspicious keywords (secret/password/token/key)"
echo " → Fix: Rename file or add to SAFE_FILENAME_PATTERNS whitelist"
echo ""
done
TOTAL_VIOLATIONS=$((TOTAL_VIOLATIONS + ${#SUSPICIOUS_FILES[@]}))
fi
# LDR-specific violation reports
if [ ${#RESEARCH_DATA_VIOLATIONS[@]} -gt 0 ]; then
echo ""
echo "❌ RESEARCH DATA LEAKAGE - Hardcoded research session data found:"
echo " Research IDs and session data should never be hardcoded in production code."
echo ""
for violation in "${RESEARCH_DATA_VIOLATIONS[@]}"; do
echo " 📊 $violation"
# Show the specific lines with research data
echo " → Found hardcoded research data:"
grep -n -E "(research_id|session_id|query_id).*=.*[\"'][0-9a-f]{8,}[\"']" "$violation" 2>/dev/null | head -3 | while read -r line; do
echo " $line"
done
echo " → Issue: Hardcoded research/session IDs in non-test file"
echo " → Fix: Use environment variables or configuration files"
echo ""
done
TOTAL_VIOLATIONS=$((TOTAL_VIOLATIONS + ${#RESEARCH_DATA_VIOLATIONS[@]}))
fi
if [ ${#FLASK_SECRET_VIOLATIONS[@]} -gt 0 ]; then
echo ""
echo "❌ FLASK SECRET KEY - Hardcoded Flask secret keys found:"
echo " Flask secret keys must never be hardcoded for security reasons."
echo ""
for violation in "${FLASK_SECRET_VIOLATIONS[@]}"; do
echo " 🔐 $violation"
# Show the specific lines with secret keys
echo " → Found hardcoded Flask secret key:"
grep -n -E "SECRET_KEY.*=.*[\"'][^\"']{16,}[\"']" "$violation" 2>/dev/null | head -3 | while read -r line; do
echo " $line"
done
echo " → Issue: Hardcoded Flask SECRET_KEY"
echo " → Fix: Use os.environ or load from secure config file"
echo ""
done
TOTAL_VIOLATIONS=$((TOTAL_VIOLATIONS + ${#FLASK_SECRET_VIOLATIONS[@]}))
fi
if [ ${#ENV_FILE_VIOLATIONS[@]} -gt 0 ]; then
echo ""
echo "❌ ENVIRONMENT FILES - .env files detected:"
echo " Environment files contain sensitive configuration and should never be committed."
echo ""
for violation in "${ENV_FILE_VIOLATIONS[@]}"; do
echo " 🌍 $violation"
echo " → Issue: Environment file in repository"
echo " → Fix: Add to .gitignore and use .env.example instead"
echo ""
done
TOTAL_VIOLATIONS=$((TOTAL_VIOLATIONS + ${#ENV_FILE_VIOLATIONS[@]}))
fi
if [ ${#HIGH_ENTROPY_VIOLATIONS[@]} -gt 0 ]; then
echo ""
echo "❌ HIGH ENTROPY STRINGS - Potential secrets or keys detected:"
echo " Long random strings may be API keys, tokens, or other secrets."
echo ""
for violation in "${HIGH_ENTROPY_VIOLATIONS[@]}"; do
echo " 🎲 $violation"
# Show sample of high entropy strings
echo " → Found high-entropy strings:"
grep -n -E "[a-zA-Z0-9+/]{40,}={0,2}|[a-f0-9]{40,}" "$violation" 2>/dev/null | head -3 | while read -r line; do
# Truncate long lines for readability
echo " ${line:0:120}..."
done
echo " → Issue: High-entropy strings that could be secrets"
echo " → Fix: Review and move to environment variables if sensitive"
echo ""
done
TOTAL_VIOLATIONS=$((TOTAL_VIOLATIONS + ${#HIGH_ENTROPY_VIOLATIONS[@]}))
fi
if [ ${#HARDCODED_PATH_VIOLATIONS[@]} -gt 0 ]; then
echo ""
echo "❌ HARDCODED PATHS - System-specific paths detected:"
echo " Absolute paths can expose system structure and break portability."
echo ""
for violation in "${HARDCODED_PATH_VIOLATIONS[@]}"; do
echo " 📁 $violation"
# Show the specific hardcoded paths
echo " → Found hardcoded paths:"
grep -n -E "(/home/[a-zA-Z0-9_-]+|/Users/[a-zA-Z0-9_-]+|C:\\\\Users\\\\[a-zA-Z0-9_-]+|/opt/|/var/|/etc/|/usr/local/)" "$violation" 2>/dev/null | head -5 | while read -r line; do
echo " $line"
done
echo " → Issue: Hardcoded absolute paths reduce portability"
echo " → Fix: Use relative paths, environment variables, or config files"
echo ""
done
TOTAL_VIOLATIONS=$((TOTAL_VIOLATIONS + ${#HARDCODED_PATH_VIOLATIONS[@]}))
fi
if [ ${#HARDCODED_IP_VIOLATIONS[@]} -gt 0 ]; then
echo ""
echo "❌ HARDCODED IP ADDRESSES - External IP addresses detected:"
echo " Hardcoded IPs can expose infrastructure and cause connectivity issues."
echo ""
for violation in "${HARDCODED_IP_VIOLATIONS[@]}"; do
echo " 🌐 $violation"
# Show the specific IP addresses
echo " → Found hardcoded IP addresses:"
grep -n -E "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" "$violation" 2>/dev/null | grep -v -E "(127\.0\.0\.1|0\.0\.0\.0|localhost|192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|255\.255\.255\.|192\.0\.2\.|198\.51\.100\.|203\.0\.113\.)" | head -5 | while read -r line; do
echo " $line"
done
echo " → Issue: Hardcoded IP addresses (non-private/localhost)"
echo " → Fix: Use DNS names, environment variables, or config files"
echo ""
done
TOTAL_VIOLATIONS=$((TOTAL_VIOLATIONS + ${#HARDCODED_IP_VIOLATIONS[@]}))
fi
if [ ${#SUSPICIOUS_FILETYPE_VIOLATIONS[@]} -gt 0 ]; then
echo ""
echo "❌ SUSPICIOUS FILE TYPES - Potentially dangerous file types detected:"
echo " These file types are commonly used for malware, data leaks, or bloat the repository."
echo ""
for violation in "${SUSPICIOUS_FILETYPE_VIOLATIONS[@]}"; do
echo " 🚨 $violation"
FILE_PATH="${violation%% (*}"
FILE_CATEGORY="${violation##*\\(}"
FILE_CATEGORY="${FILE_CATEGORY%\\)}"
# Provide specific guidance based on file category
case "$FILE_CATEGORY" in
"executable/binary")
echo " → Issue: Executable/binary files can contain malware"
echo " → Fix: Remove executable files, use package managers instead"
;;
"compressed archive")
echo " → Issue: Compressed archives hide their contents from review"
echo " → Fix: Extract contents and commit individual files instead"
;;
"temporary/cache")
echo " → Issue: Temporary/cache files should not be committed"
echo " → Fix: Add to .gitignore and remove from repository"
;;
"image file")
echo " → Issue: Binary image files bloat the repo and should NOT be committed"
echo " → Fix: Store images externally. Only a few explicitly listed images in docs/images/ are allowed"
;;
"media file")
echo " → Issue: Media files are large and rarely needed in code repos"
echo " → Fix: Use external hosting or remove if unnecessary"
;;
"document file")
echo " → Issue: Office documents should be in docs/ directory if needed"
echo " → Fix: Move to docs/ directory or convert to markdown"
;;
"database file")
echo " → Issue: Database files contain data that shouldn't be in source control"
echo " → Fix: Add to .gitignore and use migrations/seeds instead"
;;
"build artifact/cache")
echo " → Issue: Build artifacts and cache files bloat the repository"
echo " → Fix: Add to .gitignore and remove from repository"
;;
esac
# Show file info if available
if [ -f "$FILE_PATH" ]; then
FILE_SIZE=$(stat -c%s "$FILE_PATH" 2>/dev/null || echo "unknown")
if [ "$FILE_SIZE" != "unknown" ]; then
READABLE_SIZE=$(echo "$FILE_SIZE" | awk '{if($1>=1048576) printf "%.1fMB", $1/1048576; else if($1>=1024) printf "%.1fKB", $1/1024; else printf "%dB", $1}')
echo " → File size: $READABLE_SIZE"
fi
fi
echo ""
done
TOTAL_VIOLATIONS=$((TOTAL_VIOLATIONS + ${#SUSPICIOUS_FILETYPE_VIOLATIONS[@]}))
fi
# Final result
if [ $TOTAL_VIOLATIONS -eq 0 ]; then
echo ""
echo "✅ All security checks passed!"
exit 0
else
echo ""
echo "💡 To fix these issues:"
echo " - For text/config files: add pattern to .file-whitelist.txt (requires maintainer approval)"
echo " - For binary files (images, audio, video, archives): do NOT add to the repo"
echo " Binary files permanently bloat git history. Store them externally instead."
echo " Only a small set of explicitly listed binary files is permitted."
echo " - Use environment variables for secrets"
echo " - Never hardcode research data or session IDs"
echo " - Use .env.example files instead of .env"
echo " - Replace absolute paths with relative paths or configs"
echo " - Use DNS names instead of hardcoded IP addresses"
echo ""
echo "⚠️ SECURITY REMINDER: This is a public repository!"
echo " Never commit sensitive data, API keys, or personal information."
exit 1
fi