File Directory Security & Outside Webroot Permissions in OJS
Detailed security manual on configuring the OJS files_dir repository. Covers outside-webroot partitioning, Linux permissions, SELinux policies, and preventing unauthorized file access.
Real Problem
Many OJS installations store manuscripts in public_html/files, enabling malicious actors to bypass editorial authentication and download confidential pre-prints or upload executable PHP backdoors.
Practical Solution
Store all submitted files in a dedicated directory outside the public web root, assign strict Linux permissions (750), and enforce role-based access control via OJS download streaming gateways.
The Architecture of Academic Manuscript Repositories
Unlike standard web applications where uploaded media consists of public images, an Open Journal Systems repository contains sensitive pre-publication research, confidential peer reviewer evaluations, and author revisions. If an unpublished drug trial manuscript or patent-sensitive engineering paper is exposed prior to formal publication, the journal faces immense legal and reputational liability.
The PKP engineering architecture solves this through indirect file streaming: manuscripts are stored on disk using randomized internal identifiers and streamed to the user only after OJS verifies the requester’s active session, role, and editorial permissions.
Directory Partitioning Strategy
The public web root (e.g., /var/www/ojs) should contain only executable PHP code, Smarty templates, CSS, and public assets (such as journal logos and header banners). The files repository must reside in a completely isolated filesystem path:
- Public Web Root: /var/www/ojs
- Public Media Folder: /var/www/ojs/public (logos, styles)
- Secure Manuscript Repository: /var/ojs_files (outside webroot)
Configuring config.inc.php
Open /var/www/ojs/config.inc.php and locate the [files] section:
[files]
files_dir = "/var/ojs_files"
public_files_dir = "public"
umask = 0022
Never use relative paths like ./files or files/. Always provide a fully qualified absolute filesystem path.
Linux User and Group Permissions Hardening
Permissions must be restrictive enough to prevent other system users from reading manuscript files, while granting full read/write capabilities to the web server process:
chown -R www-data:www-data /var/ojs_files
find /var/ojs_files -type d -exec chmod 750 {} \;
find /var/ojs_files -type f -exec chmod 640 {} \;
This ensures that only the www-data user (the PHP-FPM process) can write and read submissions, while the group has read-only access and world permissions are completely zeroed out.
Handling SELinux in Enterprise Linux Environments
If deploying on AlmaLinux, Rocky Linux, or Red Hat Enterprise Linux, SELinux will block the web server from writing to outside directories even if standard chmod permissions are 777.
Execute the following commands to apply the proper SELinux security context:
semanage fcontext -a -t httpd_sys_rw_content_t "/var/ojs_files(/.*)?"
restorecon -Rv /var/ojs_files
Verification and Penetration Testing
After configuration, verify your security by attempting to craft a direct HTTP request to /ojs_files/ or any manuscript path. The web server should return an immediate 404 Not Found, proving that manuscripts are accessible strictly through authenticated OJS download controllers.
Step-by-Step Action Plan
Create Isolated Storage Directory
Create /var/ojs_files completely outside /var/www/html or any public web-accessible directory.
Assign Ownership & Permissions
Set ownership to www-data:www-data with chmod 750 on directories and chmod 640 on files.
Update config.inc.php
Set files_dir = "/var/ojs_files" in the [files] section of config.inc.php.
Configure SELinux (AlmaLinux/RHEL)
Set context chcon -R -t httpd_sys_rw_content_t /var/ojs_files to allow web server read/write operations.
Test Direct HTTP Access Blocking
Attempt to navigate directly to manuscript URLs in a browser to verify that HTTP 403 or 404 is returned.
Questions People Usually Ask
Why does OJS insist that files_dir be outside the web root?
When files are inside the web root, the web server can serve them directly via HTTP without checking whether the requester is an authorized reviewer or editor. Moving them outside ensures every request is verified by OJS PHP authentication.
What causes the "The directory specified for uploaded files does not exist or is not writable" error?
This occurs when the path defined in config.inc.php does not exist, has an incorrect absolute path, or lacks write permissions for the web server user (www-data or nginx).
Can malicious PHP files be executed from the files directory?
Not if the files directory is outside the web root. Because the web server never maps that directory to a public URL, PHP files cannot be executed via HTTP.
Secure Your Journal Against Manuscript Breaches
AcademiaTech audits your file storage architecture and relocates vulnerable manuscript repositories without disrupting existing article links.