Added mod_rewrite for nginx module

This commit is contained in:
alexey
2026-03-23 01:15:59 +03:00
commit 0d2c6277e1
124 changed files with 11079 additions and 0 deletions

74
cms/grav/.htaccess Normal file
View File

@@ -0,0 +1,74 @@
RewriteEngine On
# ============================================
# 1. Security Rules - Test malicious patterns
# ============================================
# Detect template injection (Mustache, Twig syntax)
RewriteCond %{REQUEST_URI} ({{|}}|{%|%}) [OR]
RewriteCond %{QUERY_STRING} ({{|}}|{%25|%25}) [OR]
# Base64 encoded payloads in query string
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
# Script injection patterns (HTML entities decoded)
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
# GLOBALS exploitation attempt
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
# _REQUEST manipulation (PHP superglobal abuse)
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
# Block malicious requests with 403 Forbidden
RewriteRule .* index.php [F]
# ============================================
# 2. Grav CMS Core Routing Rules
# ============================================
# Prevent rewriting to index.php if already there
RewriteCond %{REQUEST_URI} !^/index\.php
# Allow access to existing files
RewriteCond %{REQUEST_FILENAME} !-f
# Allow access to existing directories
RewriteCond %{REQUEST_FILENAME} !-d
# Route everything else through Grav's index.php
RewriteRule .* index.php [L]
# ============================================
# 3. Sensitive Directory Protection
# ============================================
# Block system, cache, logs, backups folders
RewriteRule ^(\.git|cache|bin|logs|backup|webserver-configs|tests)/(.*) error [F]
# Block system and vendor directories (prevent access to .txt/.xml files)
RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F]
# Block user directory access to configuration and content files
RewriteRule ^(user)/(.*)\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F]
# ============================================
# 4. File Extension Protection
# ============================================
# Block raw .md file access (content source files)
RewriteRule \.md$ error [F]
# ============================================
# 5. Hidden Files/Directories Protection
# ============================================
# Block hidden files except well-known/robots.txt directories
RewriteRule (^|/)\.(?!well-known) - [F]
# ============================================
# 6. Critical Configuration File Protection
# ============================================
# Block sensitive configuration and documentation files
RewriteRule ^(LICENSE\.txt|composer\.lock|composer\.json|\.htaccess)$ error [F]

1
cms/grav/.htaccess.test Normal file
View File

@@ -0,0 +1 @@
This is a .htaccess file - should be blocked by RewriteRule ^(LICENSE\.txt|composer\.lock|composer\.json|\.htaccess)$ error [F]

1
cms/grav/.htpasswd Normal file
View File

@@ -0,0 +1 @@
This is a hidden .htpasswd file - should be blocked by RewriteRule (^|/)\.(?!well-known) - [F]

View File

@@ -0,0 +1 @@
Robots.txt file - should be ALLOWED because it matches (.well-known) exception in RewriteRule (^|/)\.(?!well-known) - [F]

1
cms/grav/LICENSE.txt Normal file
View File

@@ -0,0 +1 @@
This is a LICENSE.txt file - should be blocked by RewriteRule ^(LICENSE\.txt|composer\.lock|composer\.json|\.htaccess)$ error [F]

119
cms/grav/README.md Normal file
View File

@@ -0,0 +1,119 @@
# Grav CMS Test Structure - Updated
## Directory Layout Overview
```
/test1/cms/grav/
├── .git/ - Git folder tests (blocked)
│ └── secret.txt
├── .well-known/ - Well-known directory (allowed exception)
│ └── robots.txt
├── .htaccess - Main Apache rules configuration
├── .htpasswd - Hidden file (blocked by Rule 5)
├── bin/ - Bin folder tests (blocked)
│ └── helper.php
├── backup/ - Backup folder tests (blocked)
│ └── archive.zip
├── cache/ - Cache folder tests (blocked)
│ └── test.txt
├── composer.json - Config file protection (blocked)
├── composer.lock - Config file protection (blocked)
├── existing.jpg - Existing file for routing test (200 OK)
├── index.php - Grav CMS entry point - routes non-existing files
│ - Returns: "Grav CMS Content Route" page
├── LICENSE.txt - Config file protection (blocked)
├── logs/ - Logs folder tests (blocked)
│ └── app.log
├── normal-page.md - Normal Grav CMS page (routes through index.php)
├── README.md - This documentation file
├── somedir/ - Empty directory for routing test (200 OK)
├── system/ - System folder tests (blocked extensions)
│ └── config.xml
├── vendor/ - Vendor folder tests (blocked extensions)
│ └── module.txt
├── user/ - User folder tests (blocked extensions)
│ ├── test.txt
│ ├── data.json
│ ├── template.twig
│ ├── script.sh
│ ├── module.php
│ ├── config.yml
│ └── settings.yaml
├── webserver-configs/ - Webserver configs folder tests (blocked)
│ └── nginx.conf
├── tests/ - Tests folder tests (blocked)
│ └── unit-test.php
├── test-mustache.php - Security: Mustache template injection pattern
├── twig-test.html - Security: Twig syntax injection pattern
├── test-rewriterules.sh - Bash script to test all rules using curl
└── README.md - Documentation
```
## Updated Test Script Features
### New Content Verification Function
The script now includes a `test_rule_content()` function that:
1. Checks HTTP status code matches expected value
2. Verifies response body contains expected content string
**Example usage:**
```bash
test_rule_content "Normal page routing via index.php" \
"$BASE_URL/normal-page/" \
"200" \
"Grav CMS Content Route"
```
This tests that:
- URL `/home/alexey/projects/workspace-zed/test1/cms/grav/normal-page/` (non-existing file)
- Returns HTTP 200 status (routed through index.php via Rule 2)
- Response body contains "Grav CMS Content Route" text from index.php
## Test Coverage Summary
### 1. Security Rules - Malicious Patterns ✓
- Template injection: `{{ }}`, `{% %}` in URI/Query String → **403**
- Base64 payloads: `base64_encode()` pattern → **403**
- Script injection: `<script>` or `%3C` encoded → **403**
- GLOBALS exploitation: `GLOBALS[` pattern → **403**
- _REQUEST manipulation: `_REQUEST[` pattern → **403**
### 2. Core Routing Rules ✓ (Updated)
- Non-existing file routes to index.php → **200** + content check
- Existing file access → **200**
- Existing directory access → **200**
### 3. Sensitive Directory Protection ✓
- Blocks: `.git`, `cache`, `bin`, `logs`, `backup` folders → **403**
- Blocks system/vendor with sensitive extensions (`.txt`, `.xml`) → **403**
### 4. File Extension Protection ✓
- Blocks raw `.md` files → **403**
### 5. Hidden Files/Directories Protection ✓
- Blocks hidden files except `.well-known`**403** / **200**
### 6. Critical Configuration File Protection ✓
- Blocks: `LICENSE.txt`, `composer.lock`, `composer.json`, `.htaccess`**403**
## Run Tests
Execute the test script to verify all rules:
```bash
cd /home/alexey/projects/workspace-zed/test1/cms/grav
./test-rewriterules.sh
```
Expected results for security tests (all should be **PASS ✓**):
- Template injection: HTTP 403 ✓
- Twig injection: HTTP 403 ✓
- Base64 payload: HTTP 403 ✓
- Script injection: HTTP 403 ✓
- GLOBALS manipulation: HTTP 403 ✓
- _REQUEST manipulation: HTTP 403 ✓
Expected results for routing tests (should be **PASS ✓**):
- Normal page routing: HTTP 200 + content "Grav CMS Content Route" ✓
- Existing file access: HTTP 200 ✓
- Directory access: HTTP 200 ✓

View File

@@ -0,0 +1 @@
Backup archive.zip file - should be blocked by RewriteRule ^(\.git|cache|bin|logs|backup|webserver-configs|tests)/(.*) error [F]

1
cms/grav/bin/helper.php Normal file
View File

@@ -0,0 +1 @@
Bin helper.php file - should be blocked by RewriteRule ^(\.git|cache|bin|logs|backup|webserver-configs|tests)/(.*) error [F]

1
cms/grav/cache/test.txt vendored Normal file
View File

@@ -0,0 +1 @@
Cache test.txt file - should be blocked by RewriteRule ^(\.git|cache|bin|logs|backup|webserver-configs|tests)/(.*) error [F]

1
cms/grav/composer.json Normal file
View File

@@ -0,0 +1 @@
{\"name\": \"test/my-site\", \"description\": \"Test Composer file\"}

1
cms/grav/composer.lock generated Normal file
View File

@@ -0,0 +1 @@
This is a composer.lock file - should be blocked by RewriteRule ^(LICENSE\.txt|composer\.lock|composer\.json|\.htaccess)$ error [F]

0
cms/grav/existing.jpg Normal file
View File

15
cms/grav/index.php Normal file
View File

@@ -0,0 +1,15 @@
<?php
/**
* Grav CMS - index.php (Test version)
* This file handles routing for non-existing files/directories
*/
// Simulated Grav CMS response
echo "<html><head><title>Grav CMS Test Site</title></head><body>";
echo "<h1>Grav CMS Content Route</h1>";
echo "<p>This page is served by index.php via RewriteRule.</p>";
echo "<div class='graviconfig'>Site Configuration Loaded</div>";
echo "</body></html>";
// Exit
exit;

159
cms/grav/nginx.conf Normal file
View File

@@ -0,0 +1,159 @@
load_module modules/ngx_http_apache_rewrite_module.so;
worker_processes 1;
error_log logs/error.log debug;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8081;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 8081;
server_name example1.com;
root /sites/site1;
HtaccessEnable on;
RewriteEngine On;
location / {
RewriteEngine On;
}
}
server {
listen 8081;
server_name example2.com;
root /sites/site2;
HtaccessEnable on;
RewriteEngine On;
index index.php;
location / {
RewriteEngine On;
autoindex on;
}
location ~* \.php$ {
RewriteEngine On;
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
server {
listen 8081;
server_name example3.com;
root /sites/site3;
HtaccessEnable on;
RewriteEngine On;
index index.php;
location / {
RewriteEngine On;
autoindex on;
}
location ~* \.php$ {
RewriteEngine On;
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/www.sock; # подключаем сокет php-fpm
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
server {
listen 8081;
server_name example4.com;
root /sites/site4;
HtaccessEnable on;
RewriteEngine On;
index index.php;
location / {
RewriteEngine On;
autoindex on;
}
location ~* \.php$ {
RewriteEngine On;
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/www.sock; # подключаем сокет php-fpm
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
server {
listen 8081;
server_name example5.com;
root /sites/site5;
HtaccessEnable on;
RewriteEngine On;
index index.php;
location / {
RewriteEngine On;
autoindex on;
}
location ~* \.php$ {
RewriteEngine On;
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/www.sock; # подключаем сокет php-fpm
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
}

1
cms/grav/normal-page.md Normal file
View File

@@ -0,0 +1 @@
Normal Grav CMS page - should be routed through index.php

14
cms/grav/site2.conf Normal file
View File

@@ -0,0 +1,14 @@
<VirtualHost *:80>
DocumentRoot "/sites/site2"
ServerName example2.com
<Directory /sites/site2>
Options +Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>

View File

View File

@@ -0,0 +1 @@
System config.xml file - should be blocked by RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F]

View File

@@ -0,0 +1 @@
This is a Mustache template injection test file with {{ variable }} syntax

150
cms/grav/test-rewriterules.sh Executable file
View File

@@ -0,0 +1,150 @@
#!/bin/bash
# ============================================
# Grav CMS .htaccess Rules Test Script
# ============================================
# This script tests each rule from cms/grav/.htaccess
# Domain: test.my.brp
# ============================================
BASE_URL="http://test.my.brp"
echo "=============================================="
echo "Grav CMS .htaccess Rules Test Suite"
echo "=============================================="
echo ""
# Function to test a rule and report result (status only)
test_rule() {
local description="$1"
local url="$2"
local expected_status="$3" # e.g., 403, 404, 200
echo "--- Test: $description ---"
response=$(curl -s -o /dev/null -w "%{http_code}" "$url")
if [ "$response" = "$expected_status" ]; then
echo "✓ PASS (HTTP $response)"
else
echo "✗ FAIL (Expected: HTTP $expected_status, Got: HTTP $response)"
fi
echo ""
}
# Function to test a rule and verify content contains expected string
test_rule_content() {
local description="$1"
local url="$2"
local expected_status="$3" # e.g., 403, 404, 200
local expected_content="$4" # Expected substring in response body
echo "--- Test: $description ---"
response=$(curl -s "$url")
http_code=$(curl -s -o /dev/null -w "%{http_code}" "$url")
# Check status code
if [ "$http_code" != "$expected_status" ]; then
echo "✗ FAIL (Status: HTTP $http_code, Expected: HTTP $expected_status)"
return 1
fi
# Check content contains expected substring
if [[ "$response" == *"$expected_content"* ]]; then
echo "✓ PASS (HTTP $http_code, Content matches '$expected_content')"
else
echo "✗ FAIL (Content missing: '$expected_content') - Response:"
echo "$response" | head -5
fi
echo ""
}
echo "=============================================="
echo "1. Security Rules - Test malicious patterns"
echo "=============================================="
# Template injection via query string with {{ }} Mustache syntax
test_rule "Template injection via query string ({{ }}" \
"$BASE_URL/test-mustache.php?\{\{config.secret\}\}" \
"403"
# Base64 encoded payloads (base64_encode function call)
test_rule "Base64 payload pattern" \
"$BASE_URL/test.php?data=base64_encode(some_secret)" \
"403"
# Script injection (<script> or HTML entities %3C)
test_rule "Script injection (encoded)" \
"$BASE_URL/search.html?q=%3Cscript%25alert(1)%3E" \
"403"
# GLOBALS exploitation attempt
test_rule "GLOBALS manipulation" \
"$BASE_URL/leak.php?GLOBALS\[secret\]=exploit" \
"403"
# _REQUEST manipulation (PHP superglobal abuse)
test_rule "_REQUEST manipulation" \
"$BASE_URL/attack.php?_REQUEST\[user\]=admin" \
"403"
echo ""
echo "=============================================="
echo "2. Grav CMS Core Routing Rules"
echo "=============================================="
# Test normal page routing through index.php (non-existing file -> index.php)
test_rule_content "Normal page routing via index.php" \
"$BASE_URL/normal-page/" \
"200" \
"Grav CMS Content Route"
# Test existing file access - check status + content type/image
test_rule "Existing file access (existing.jpg)" \
"$BASE_URL/existing.jpg" \
"200"
# Test existing directory access
test_rule "Existing directory access (somedir/)" \
"$BASE_URL/somedir/" \
"200"
echo ""
echo "=============================================="
echo "3. Sensitive Directory Protection"
echo "=============================================="
# Block system, cache, logs, backups folders
test_rule "Block .git folder" "$BASE_URL/.git/secret.txt" "403"
test_rule "Block cache folder" "$BASE_URL/cache/test.txt" "403"
test_rule "Block bin folder" "$BASE_URL/bin/helper.php" "403"
test_rule "Block logs folder" "$BASE_URL/logs/app.log" "403"
test_rule "Block backup folder" "$BASE_URL/backup/archive.zip" "403"
# Block system and vendor directories with sensitive extensions
test_rule "Block system config.xml" "$BASE_URL/system/config.xml" "403"
test_rule "Block vendor module.txt" "$BASE_URL/vendor/module.txt" "403"
echo ""
echo "=============================================="
echo "4. File Extension Protection"
echo "=============================================="
# Block raw .md file access (content source files)
test_rule "Block raw .md file" "$BASE_URL/test.md" "403"
echo ""
echo "=============================================="
echo "5. Hidden Files/Directories Protection"
echo "=============================================="
test_rule "Block hidden .htpasswd" "$BASE_URL/.htpasswd" "403"
test_rule "Allow .well-known/robots.txt" "$BASE_URL/.well-known/robots.txt" "200"
echo ""
echo "=============================================="
echo "6. Critical Configuration File Protection"
echo "=============================================="
test_rule "Block LICENSE.txt" "$BASE_URL/LICENSE.txt" "403"
test_rule "Block composer.lock" "$BASE_URL/composer.lock" "403"
test_rule "Block composer.json" "$BASE_URL/composer.json" "403"
test_rule "Block .htaccess" "$BASE_URL/.htaccess" "403"
echo ""
echo "=============================================="
echo "Test Suite Complete"
echo "=============================================="

1
cms/grav/test.md Normal file
View File

@@ -0,0 +1 @@
Test.md

View File

@@ -0,0 +1 @@
Tests unit-test.php file - should be blocked by RewriteRule ^(\.git|cache|bin|logs|backup|webserver-configs|tests)/(.*) error [F]

1
cms/grav/twig-test.html Normal file
View File

@@ -0,0 +1 @@
This is a Twig template syntax test file with {% comment %} syntax

1
cms/grav/user/config.yml Normal file
View File

@@ -0,0 +1 @@
User config.yml file - should be blocked by RewriteRule ^(user)/(.*)\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F]

1
cms/grav/user/data.json Normal file
View File

@@ -0,0 +1 @@
User data.json file - should be blocked by RewriteRule ^(user)/(.*)\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F]

1
cms/grav/user/module.php Normal file
View File

@@ -0,0 +1 @@
User module.php file - should be blocked by RewriteRule ^(user)/(.*)\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F]

1
cms/grav/user/script.sh Normal file
View File

@@ -0,0 +1 @@
User script.sh file - should be blocked by RewriteRule ^(user)/(.*)\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F]

View File

@@ -0,0 +1 @@
User settings.yaml file - should be blocked by RewriteRule ^(user)/(.*)\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F]

View File

@@ -0,0 +1 @@
User template.twig file - should be blocked by RewriteRule ^(user)/(.*)\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F]

1
cms/grav/user/test.txt Normal file
View File

@@ -0,0 +1 @@
User test.txt file - should be blocked by RewriteRule ^(user)/(.*)\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F]

1
cms/grav/vendor/module.txt vendored Normal file
View File

@@ -0,0 +1 @@
Vendor module.txt file - should be blocked by RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F]

View File

@@ -0,0 +1 @@
Webserver configs nginx.conf file - should be blocked by RewriteRule ^(\.git|cache|bin|logs|backup|webserver-configs|tests)/(.*) error [F]