PLANT OPERATIONS PORTAL

Administrator & IT Guide · Daily Operations Report
CONFIDENTIAL · IT & OPS USE ONLY

CRITICAL — Immediate Action Required

The Daily Operations Report is viewable by anyone on the internet, and can be attacked without logging in.

→ Take dashboard.php, weekly_index.php, api/submit_report.php, and reset_user.php offline immediately. See Section 2 and 13 for full details.

1. How This Guide was prepared & file inventory

This guide comes from a full read of every file in the handover archive — 31 files in total, including several old, duplicate, or unused copies. Working out which file is actually "live" mattered: several pairs of files share the same purpose but different behavior.

Section 12 lists every file with a plain-language note on what it is and whether it's still needed.

2. CRITICAL — full details
Unauthenticated report page with SQL injection
dashboard.php has no session check; $_GET['date'] interpolated directly into SQL. Exploitable by anyone, anywhere.
Unauthenticated write endpoint
api/submit_report.php has no admin check at all. Anyone who finds the URL can POST data with no login.
Unprotected admin-reset script
reset_user.php recreates admin@plant.com / admin123 with no access check. Anyone can take over the admin account.

Recommendation: take these four files offline (or add authentication and parameterized queries) before anything else. See Section 13 for the complete list of findings.

3. System Overview & roles

PHP + MySQL portal (Hostinger) that lets plant staff record and review daily operations: safety man-hours, production, stock, and sales by customer.

adminFull access: view report, add/edit daily entries, bulk-upload CSVs, manage users.
viewerRead-only: view report and switch dates, but no Data Entry, Manage Users, or logout button.

Core files (live versions only)

login.php — sign-in page
index.php — main menu
dashboard.php — report + data entry
api/submit.php — save manual entry
upload.php — bulk CSV import
manage_users.php — user admin
api/check_update.php — poll for updates
logout.php — end session
db.php — connection + auto-login
reset_user.php — admin reset (unprotected)
reset.php — wipe all data
fix_plans.php, update_plans.php — monthly sales plan
4. Initial Admin setup

The master admin account is created by visiting reset_user.php once. It creates (or resets):

  1. Visit reset_user.php once, from a trusted, internal connection only.
  2. Log in immediately with the default credentials.
  3. Change the password to something strong right away (no in-app change-password screen exists — direct DB update or build a feature).
  4. Delete or relocate reset_user.php from the live server.
Don't confuse with setup_admin.php
A second file, setup_admin.php, also exists but targets an older, incompatible table structure. It should be deleted.
5. Logging In & the Main Menu

Go to login.php and sign in with either your email address or username and your password. A "Stay logged in" cookie keeps you signed in for 30 days.

After login, you land on index.php (Main Menu) with up to four options:

6. Reading & entering daily data

6.1 The Report screen

6.2 Adding a Daily Entry (admin only)

Tap "Add Entry" → Data Entry screen, three tabs:

OpsHSE Man Hours, Plant Rate, Prod Daily, Plan Target, Silo Adjustment
StockPTA Warehouse & Silo, PX EVTL & Plant, AA EVTL & Plant, Trading AA EVTL & Chempro
SaleActual sales + plan/target per customer

Anything left blank keeps its previous saved value — safe to submit partial updates.

7. Bulk CSV upload

From Data Entry, tap "Upload Bulk Data (Excel)" to open upload.php.

  1. Prepare CSV with one row per day, in the column order your file was given.
  2. Dates in YYYY/MM/DD or DD/MM/YYYY format (detected automatically).
  3. Choose the file and click "Upload."
  4. Blank cells keep previous values.
Do not use the provided template.csv as-is — it is out of date
The importer expects a "Silo Adjustment" column right after "Prod Plan" (5th column). The template.csv does not have that column — values from that point onward are saved against the wrong field. Fix: add a "Silo_Adj" column in the 6th position, or update upload.php to match the template.
8. Managing users
Security gaps in this screen — see Section 13.5–13.7. SQL injection and stored XSS risks exist here.
9. Monthly Sales Plan maintenance

There is currently no on-screen way to set a customer's monthly sales target. It's done today by editing PHP files:

Fragile — worth replacing
Each file stays live, hardcoded to a specific month, with no audit trail. A small admin screen would be much safer.
10. Wiping All Operational data (reset.php)
reset.php permanently deletes every row from daily_metrics and transaction_lines with a single page load. No confirmation, no undo. Runs on GET — vulnerable to CSRF/accidental triggers.

Recommendation: add a typed confirmation step, move to POST with CSRF token, consider requiring a second admin confirmation.

11. Data Model reference

daily_metrics (one row per day)

transaction_lines (per customer, per day)

users

12. Stale, Duplicate & orphaned files
13aug_login.php — older backup, safe to delete
12aug_manage_users.php, ok_manage_users.php — old backups, safe to delete
dsfeb3_dashboard.php — draft redesign, not linked, confirm before delete
weekly_index.php — older report with receipts, same security issues, delete or fix
default.php — Hostinger placeholder, unrelated
setup_admin.php — legacy, incompatible, delete
api/submit_report.php — orphaned, no login check, delete
api/new_submit.php, api/old_submit.php, api/04jan_submit.php — superseded, remove
sw.js, assets/js/charts.js — empty, dead
mainfest.jason — misspelled manifest, 404s, delete with weekly_index.php
assets/img/old_icon.png — superseded, safe to delete
13. Full Security & reliability findings
13.1 Unauthenticated report page with SQL injection — dashboard.php, weekly_index.php. Fix: add login check + parameterized queries.
13.2 Unauthenticated write endpoint — api/submit_report.php. Fix: delete (superseded) or add admin check.
13.3 Unprotected admin-reset — reset_user.php. Fix: delete after initial setup.
13.4 Database password hardcoded in plain text — db.php. Rotate password, move to env variables.
13.5 SQL injection in manage_users.php — Edit/Delete/load actions. Rewrite with prepared statements.
13.6 Destructive GET-based actions — reset.php, manage_users.php delete. Convert to POST + CSRF token.
13.7 Stored XSS in manage_users.php — unescaped user names. Use htmlspecialchars().
13.8 CSV bulk upload SQL injection — upload.php SELECT. Parameterize the date query.
13.9 Outdated CSV template — mismatched columns, silently misfiles data. Fix template or upload.php.
13.10 No password-reset flow, no audit trail — no self-service reset, no log of destructive actions.
14. A Business-Logic quirk worth knowing

A client named "Dewan Salman" appears to have been renamed/merged into "Lucky Core." dashboard.php has a hardcoded rule: if report month is December 2025, "Dewan Salman" is relabeled as "Lucky Core." In any other month, "Dewan Salman" records are skipped entirely.

Recommendation: remove "Dewan Salman" from the CSV template and from upload.php's client list, so all historical data is consistently mapped to "Lucky Core."
15. Recommendations summary
  1. Take dashboard.php, weekly_index.php, api/submit_report.php, reset_user.php offline or fix immediately.
  2. Rotate database password, move credentials to environment variables.
  3. Parameterize every SQL query built with string interpolation.
  4. Add CSRF protection and confirmation step to reset.php and Delete User.
  5. Escape all user-entered fields in manage_users.php with htmlspecialchars().
  6. Fix or replace template.csv to match upload.php column order.
  7. Delete stale/duplicate/orphaned files (Section 12).
  8. Replace monthly "edit a PHP file" sales-target process with an admin screen.
  9. Add password-reset flow and basic audit log for destructive actions.
  10. Remove "Dewan Salman" from CSV template and upload.php's client list.