Skip to content
Merged
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
12 changes: 7 additions & 5 deletions images/ojs/rootfs/etc/confd/templates/ojs.conf.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ index index.php;
error_log /dev/stderr;
access_log /dev/stdout combined;

error_log /dev/stderr;
access_log /dev/stdout combined;

# API rewrite with redirect
location ~ ^/api/v1(.*)$ {
return 307 /index.php/api/v1$1;
Expand All @@ -18,8 +15,9 @@ location / {
try_files $uri $uri/ /index.php/$uri?$query_string;
}

# PHP processing
location ~ \.php(/|$) {
# Only the public front controller may execute through the web server. OJS
# includes many CLI and handler PHP files beneath the document root.
location ~ ^/index\.php(?:/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
Expand All @@ -36,6 +34,10 @@ location ~ \.php(/|$) {
include fastcgi_params;
}

location ~ \.php(?:/|$) {
return 404;
}

# Deny access to hidden files
location ~ /\. {
deny all;
Expand Down
30 changes: 30 additions & 0 deletions images/ojs/tests/FrontControllerSecurity/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: ojs-frontcontrollersecurity
services:
ojs:
image: ${OJS:-libops/ojs:local-php83}
environment:
DB_HOST: database
DB_PASSWORD: test-database-password
OJS_SALT: test-salt
OJS_API_KEY_SECRET: test-api-key-secret
OJS_SECRET_KEY: base64:MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDE=
OJS_ADMIN_PASSWORD: test-admin-password
volumes:
- ./test.sh:/test.sh:ro
command:
- /test.sh
depends_on:
mariadb:
condition: service_healthy
mariadb:
image: ${MARIADB11:-libops/mariadb:local-11}
environment:
DB_ROOT_PASSWORD: test-root-password
DB_NAME: ojs
DB_USER: ojs
DB_PASSWORD: test-database-password
networks:
default:
aliases:
- database
32 changes: 32 additions & 0 deletions images/ojs/tests/FrontControllerSecurity/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/command/with-contenv bash
# shellcheck shell=bash

set -euo pipefail

on_terminate() {
exit 0
}
trap 'on_terminate' SIGTERM

for _ in $(seq 1 150); do
if [ -f /installed ]; then
break
fi
sleep 2
done
test -f /installed

curl -fsSL --connect-timeout 5 --max-time 30 \
-o /dev/null http://localhost/index.php/index/login

for protected_path in \
/config.inc.php \
/tools/install.php \
/classes/core/Application.php; do
status="$(curl -sS --connect-timeout 5 --max-time 30 \
-o /dev/null -w '%{http_code}' "http://localhost${protected_path}")"
if [ "$status" != 404 ]; then
echo "Protected OJS path ${protected_path} returned HTTP ${status}" >&2
exit 1
fi
done
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,27 @@ index index.php;
error_log /dev/stderr;
access_log /dev/stdout combined;

location = /admin {
return 301 /admin/$is_args$args;
}

location /admin/ {
try_files $uri $uri/ /admin/index.php?$args;
}

location = /install {
return 301 /install/$is_args$args;
}

location /install/ {
try_files $uri $uri/ /install/install.php?$args;
}

location / {
try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
location ~ ^/(?:index|admin/index|install/install)\.php$ {
try_files $uri =404;
fastcgi_pass unix:{{ getenv "PHP_FPM_SOCKET" }};
fastcgi_index index.php;
Expand All @@ -20,6 +36,14 @@ location ~ \.php$ {
include fastcgi_params;
}

location ~ \.php(?:/|$) {
return 404;
}

location ~* \.ini$ {
deny all;
}

location ~ /\. {
deny all;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: omeka-classic-adminfrontcontrollerrouting
services:
omeka-classic:
image: ${OMEKA_CLASSIC:-libops/omeka-classic:local-php83}
environment:
DB_PASSWORD: test-database-password
OMEKA_CLASSIC_ADMIN_EMAIL: admin@example.com
OMEKA_CLASSIC_ADMIN_PASSWORD: test-admin-password
volumes:
- ./test.sh:/test.sh:ro
command:
- /test.sh
depends_on:
mariadb:
condition: service_healthy
mariadb:
image: ${MARIADB11:-libops/mariadb:local-11}
environment:
DB_ROOT_PASSWORD: test-root-password
DB_NAME: omeka_classic
DB_USER: omeka_classic
DB_PASSWORD: test-database-password
38 changes: 38 additions & 0 deletions images/omeka-classic/tests/AdminFrontControllerRouting/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/command/with-contenv bash
# shellcheck shell=bash

set -euo pipefail

on_terminate() {
exit 0
}
trap 'on_terminate' SIGTERM

for _ in $(seq 1 150); do
if [ -f /installed ]; then
break
fi
sleep 2
done
test -f /installed

response="$(mktemp)"
trap 'rm -f -- "$response"' EXIT

curl -fsSL --connect-timeout 5 --max-time 30 \
-o "$response" http://localhost/admin/users/login
grep -Eq 'action="[^"]*/admin/users/login"' "$response"

for protected_path in \
/application/config/db.ini \
/application/controllers/UsersController.php; do
status="$(curl -sS --connect-timeout 5 --max-time 30 \
-o /dev/null -w '%{http_code}' "http://localhost${protected_path}")"
case "$status" in
403 | 404) ;;
*)
echo "Protected Omeka Classic path ${protected_path} returned HTTP ${status}" >&2
exit 1
;;
esac
done
10 changes: 9 additions & 1 deletion images/omeka-s/rootfs/etc/confd/templates/omeka-s.conf.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ location / {
try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
location = /index.php {
try_files $uri =404;
fastcgi_pass unix:{{ getenv "PHP_FPM_SOCKET" }};
fastcgi_index index.php;
Expand All @@ -20,6 +20,14 @@ location ~ \.php$ {
include fastcgi_params;
}

location ~ \.php(?:/|$) {
return 404;
}

location ~* \.ini$ {
deny all;
}

location ~ /\. {
deny all;
}
24 changes: 24 additions & 0 deletions images/omeka-s/tests/FrontControllerSecurity/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: omeka-s-frontcontrollersecurity
services:
omeka-s:
image: ${OMEKA_S:-libops/omeka-s:local-php83}
environment:
DB_PASSWORD: test-database-password
OMEKA_S_ADMIN_EMAIL: admin@example.com
OMEKA_S_ADMIN_NAME: Administrator
OMEKA_S_ADMIN_PASSWORD: test-admin-password
volumes:
- ./test.sh:/test.sh:ro
command:
- /test.sh
depends_on:
mariadb:
condition: service_healthy
mariadb:
image: ${MARIADB11:-libops/mariadb:local-11}
environment:
DB_ROOT_PASSWORD: test-root-password
DB_NAME: omeka_s
DB_USER: omeka_s
DB_PASSWORD: test-database-password
38 changes: 38 additions & 0 deletions images/omeka-s/tests/FrontControllerSecurity/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/command/with-contenv bash
# shellcheck shell=bash

set -euo pipefail

on_terminate() {
exit 0
}
trap 'on_terminate' SIGTERM

for _ in $(seq 1 150); do
if [ -f /installed ]; then
break
fi
sleep 2
done
test -f /installed

response="$(mktemp)"
trap 'rm -f -- "$response"' EXIT

curl -fsSL --connect-timeout 5 --max-time 30 \
-o "$response" http://localhost/admin
grep -Fq '<h1>Log in</h1>' "$response"

for protected_path in \
/config/database.ini \
/application/src/Controller/IndexController.php; do
status="$(curl -sS --connect-timeout 5 --max-time 30 \
-o /dev/null -w '%{http_code}' "http://localhost${protected_path}")"
case "$status" in
403 | 404) ;;
*)
echo "Protected Omeka S path ${protected_path} returned HTTP ${status}" >&2
exit 1
;;
esac
done