create-htaccess-md.sh
#!/bin/sh
Creates htaccess.md without relying on copy/paste of the document body.
set -eu
TARGET=${1:-htaccess.md}
case "$TARGET" in
/*) : ;;
*) TARGET="$(pwd)/$TARGET" ;;
esac
mkdir -p "$(dirname "$TARGET")"
cat > "$TARGET" <<'EOF'
.htaccess Requirements
Purpose
`.htaccess` rules are a secondary protection layer for Apache or LiteSpeed deployments. Their purpose is to ensure that only the application’s intended public files can be requested through a browser.
The primary requirement remains that DefApp’s document root is its `public/` directory, not the full application directory.
Desired document root:
```text
/home/intel145/websites/apps/defapp/public
```
Unsafe document root:
```text
/home/intel145/websites/apps/defapp
```
If the web server points at the full application directory, private source code, configuration, temporary files, logs, SQL files, prompts, and backups could become accessible from the web.
Server compatibility
These requirements apply only to Apache, LiteSpeed, or OpenLiteSpeed when `.htaccess` support is enabled. Nginx does not read or apply `.htaccess`; use Nginx virtual-host rules instead.
The server configuration must permit overrides for the public document root. If overrides are disabled, an `.htaccess` file may exist but will have no effect.
Public boundary
Only intentionally public files and directories may be browser-accessible. Typical public content is:
```text
public/index.php
public/css/
public/js/
public/img/
public/images/
public/fonts/
public/assets/
public/favicon.ico
public/robots.txt
```
Use one defined public entry path, usually `public/index.php`. Do not expose additional entry points outside `public/` without review and documentation.
Private DefApp directories
Deny direct HTTP access to:
```text
admin/
ai/
audit/
config/
data/
docs/
old/
pages/
php/
scripts/
sql/
src/
templates/
tests/
tmp/
tools/
```
These may contain source, credentials, runtime state, logs, generated AI output, database exports, templates, or internal tools. A request to any private directory or its files must return `403 Forbidden` or `404 Not Found`; `200 OK` is a deployment failure.
Private system directories
The shared `system/` tree is private unless a specific endpoint is deliberately published. Deny browser access to:
```text
system/admin/
system/backup/
system/bin/
system/config/
system/core/
system/data/
system/docs/
system/manifests/
system/moved/
system/pages/
system/php/
system/plugins/
system/policies/
system/scripts/
system/tools/
system/tmp/
```
This includes all DefApp runtime state below:
```text
system/data/apps/defapp/
```
In particular, `cache/`, `exports/`, `logs/`, `tmp/`, and `traces/` must never be public.
Directory listings
Disable directory listings everywhere. A request for a directory without an approved index file must not reveal its contents.
Never allow browsing of paths such as:
```text
/defapp/data/
/defapp/docs/
/defapp/tmp/
/defapp/sql/
/defapp/src/
/defapp/public/uploads/
/system/backup/
/system/data/
```
Sensitive files
Deny direct browser access to sensitive files accidentally placed in a public directory, including:
```text
.env
.env.*
.git/
.gitignore
.gitattributes
.gitmodules
.htaccess
.htpasswd
composer.json
composer.lock
package.json
package-lock.json
yarn.lock
pnpm-lock.yaml
phpunit.xml
phpunit.xml.dist
Dockerfile
docker-compose.yml
docker-compose.yaml
README
README.md
CHANGELOG
CHANGELOG.md
LICENSE
LICENSE.md
```
Also protect sensitive or operational file types:
```text
.bak
.backup
.log
.sql
.sqlite
.sqlite3
.ini
.conf
.config
.dist
.map
```
Any exception must be intentional and documented. Source maps may expose source structure and should not normally be public in production.
PHP execution
Limit PHP execution to approved, reviewed entry points. PHP must not execute from:
```text
config/
data/
docs/
old/
pages/
sql/
src/
templates/
tests/
tmp/
tools/
uploads/
ai/output/
audit/
backup/
```
A writable directory must never permit executable uploads. Keep writable content outside the public document root whenever possible.
Uploads and generated files
If a public upload or generated-download directory is necessary:
- Allow only expected static file types.
- Block PHP and other server-side executable file types.
- Disable directory listings.
- Validate file extensions and MIME types in application code.
- Generate server-side filenames; do not use user-provided filenames as paths.
- Treat generated AI output, logs, temporary files, and exports as private by default.
- Use an authenticated download endpoint for internal or sensitive files.
Routing and rewrites
Add rewrite rules only when the application routing design is confirmed. If DefApp uses a front controller, routes may be sent to `public/index.php` while real files and assets continue to be served directly.
Review existing direct endpoints before changing routing:
```text
search.php
docs/docs.php
admin/index.php
admin/config.php
admin/audit.php
profile.php
settings.php
logout.php
```
Routing must not expose private directories, internally forward to private files, or turn missing assets into unexpected PHP execution.
Error handling
Production responses must not disclose filesystem paths, include paths, stack traces, credentials, environment variables, SQL queries, internal hostnames, or configuration contents.
Disable displayed PHP errors in production. Log errors to a private server or application log location.
Permissions and ownership
`.htaccess` does not replace correct permissions. Restrict source and configuration access to trusted maintainers and the required service account. Grant write permission only to defined runtime directories. Do not make the application tree world-writable and do not give the web server write access to source directories without an approved need.
Validation
After deployment, test intended public routes and blocked private routes.
Expected public paths:
```text
/defapp/
/defapp/index.php
/defapp/css/app.css
/defapp/js/
/defapp/img/
```
Expected denied paths:
```text
/defapp/config/
/defapp/data/
/defapp/src/
/defapp/templates/
/defapp/tmp/
/defapp/sql/
/defapp/.env
/defapp/.git/config
/defapp/old/
/system/config/
/system/data/
/system/data/apps/defapp/logs/
/system/backup/
```
Private paths must return `403 Forbidden` or `404 Not Found`. They must never return `200 OK`, expose a directory listing, disclose source/configuration, or execute uploaded/generated code.
Required outcome
```text
Browser-accessible:
apps/defapp/public/
```
```text
Not browser-accessible:
apps/defapp/* except public/
```
```text
Not browser-accessible:
system/*
```
Use `.htaccess` only as defense in depth on Apache-compatible servers. The preferred design is a server document root restricted to the reviewed `public/` directory.
EOF
printf 'Created: %s\n' "$TARGET"