Skip to content
Heist/ feed
Back to feed
HighFix available

NotrinosERP: Authenticated arbitrary file upload leads to remote code execution via HRM employee "Documents" (doc_file)

Type: advisorySources: OSV

#### Summary An authenticated user with the HR "Manage Employees" permission (`SA_EMPLOYEE`) can upload a file with an arbitrary extension through the employee **Documents** tab. The handler writes the raw client-supplied filename — extension intact — into a web-served directory with no extension, MIME, or content validation, so a `.php` file is stored under the web root and executes as code, yielding remote code execution on the server. #### Details The document-upload branch in `hrm/manage/employees.php` (function `tab_documents()`) moves the uploaded file using the client filename verbatim: ```php // hrm/manage/employees.php -> tab_documents() (HEAD lines 597-602; release 1.0.0 lines 568-573) $upload_dir = company_path().'/documents/employees'; if (!file_exists($upload_dir)) mkdir($upload_dir, 0777, true); $file_path = $upload_dir.'/'.$employee_id.'_'.time().'_'.$_FILES['doc_file']['name']; if (!move_uploaded_file($_FILES['doc_file']['tmp_name'], $file_path)) { ... } ``` There is **no** extension allow-list, `getimagesize()`, MIME check, or content inspection on this path. Contrast this with the profile-photo (`pic`) upload in the *same file*, which validates image type/extension/size, and with core `includes/ui/attachment.inc`, which deliberately generates a random extension-less name (`uniqid()`) with a comment warning that client filenames must never be trusted. The document handler ignores that established safe pattern. Reachability of the written file: - `company_path

Products
notrinos/notrinos-erp
Affected versions
0.10, 0.6, 0.7, 0.8, 0.9, 1.0.0
Fixed versions
1.1.0
CVEs
CVE-2026-76913
Confirmed fixed CVEs
Not specified
Updated in this feed
1 Nov 2026, 18:43 UTC · Revision 1

Source evidence

NotrinosERP: Authenticated arbitrary file upload leads to remote code execution via HRM employee "Documents" (doc_file)

core-osv · Original source

Published 10 Jul 2026, 19:34 UTC

#### Summary An authenticated user with the HR "Manage Employees" permission (`SA_EMPLOYEE`) can upload a file with an arbitrary extension through the employee **Documents** tab. The handler writes the raw client-supplied filename — extension intact — into a web-served directory with no extension, MIME, or content validation, so a `.php` file is stored under the web root and executes as code, yielding remote code execution on the server. #### Details The document-upload branch in `hrm/manage/employees.php` (function `tab_documents()`) moves the uploaded file using the client filename verbatim: ```php // hrm/manage/employees.php -> tab_documents() (HEAD lines 597-602; release 1.0.0 lines 568-573) $upload_dir = company_path().'/documents/employees'; if (!file_exists($upload_dir)) mkdir($upload_dir, 0777, true); $file_path = $upload_dir.'/'.$employee_id.'_'.time().'_'.$_FILES['doc_file']['name']; if (!move_uploaded_file($_FILES['doc_file']['tmp_name'], $file_path)) { ... } ``` There is **no** extension allow-list, `getimagesize()`, MIME check, or content inspection on this path. Contrast this with the profile-photo (`pic`) upload in the *same file*, which validates image type/extension/size, and with core `includes/ui/attachment.inc`, which deliberately generates a random extension-less name (`uniqid()`) with a comment warning that client filenames must never be trusted. The document handler ignores that established safe pattern. Reachability of the written file: - `company_path

osv:GHSA-qv4m-m73m-8hj7

notrinos/notrinos-erp

Fixed versions: 1.1.0

Complete source record
{
  "id": "7a44ef2896b865c7e63331aa7fa326091dd467eb8e3c627cb986cfd7917d8e0c",
  "url": "https://osv.dev/vulnerability/GHSA-qv4m-m73m-8hj7",
  "method": "structured",
  "payload": {
    "kind": "advisory",
    "title": "NotrinosERP: Authenticated arbitrary file upload leads to remote code execution via HRM employee \"Documents\" (doc_file)",
    "summary": "#### Summary An authenticated user with the HR \"Manage Employees\" permission (`SA_EMPLOYEE`) can upload a file with an arbitrary extension through the employee **Documents** tab. The handler writes the raw client-supplied filename — extension intact — into a web-served directory with no extension, MIME, or content validation, so a `.php` file is stored under the web root and executes as code, yielding remote code execution on the server. #### Details The document-upload branch in `hrm/manage/employees.php` (function `tab_documents()`) moves the uploaded file using the client filename verbatim: ```php // hrm/manage/employees.php -> tab_documents() (HEAD lines 597-602; release 1.0.0 lines 568-573) $upload_dir = company_path().'/documents/employees'; if (!file_exists($upload_dir)) mkdir($upload_dir, 0777, true); $file_path = $upload_dir.'/'.$employee_id.'_'.time().'_'.$_FILES['doc_file']['name']; if (!move_uploaded_file($_FILES['doc_file']['tmp_name'], $file_path)) { ... } ``` There is **no** extension allow-list, `getimagesize()`, MIME check, or content inspection on this path. Contrast this with the profile-photo (`pic`) upload in the *same file*, which validates image type/extension/size, and with core `includes/ui/attachment.inc`, which deliberately generates a random extension-less name (`uniqid()`) with a comment warning that client filenames must never be trusted. The document handler ignores that established safe pattern. Reachability of the written file: - `company_path",
    "evidence": "osv:GHSA-qv4m-m73m-8hj7",
    "products": [
      {
        "name": {
          "value": "notrinos/notrinos-erp",
          "evidence": "/affected/0/package/name"
        },
        "prerequisites": [],
        "fixed_versions": [
          {
            "value": "1.1.0",
            "evidence": "/affected/0/ranges"
          }
        ],
        "affected_versions": [
          {
            "value": "0.10",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "0.6",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "0.7",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "0.8",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "0.9",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "1.0.0",
            "evidence": "/affected/0/versions"
          }
        ]
      }
    ],
    "severity": "high",
    "structured": {
      "id": "GHSA-qv4m-m73m-8hj7",
      "aliases": [
        "CVE-2026-76913",
        "GHSA-qv4m-m73m-8hj7"
      ],
      "metrics": [
        {
          "type": "CVSS_V3",
          "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
        }
      ],
      "affected": [
        {
          "ranges": [
            {
              "type": "ECOSYSTEM",
              "events": [
                {
                  "introduced": "0"
                },
                {
                  "fixed": "1.1.0"
                }
              ]
            }
          ],
          "package": {
            "name": "notrinos/notrinos-erp",
            "purl": "pkg:composer/notrinos/notrinos-erp",
            "ecosystem": "Packagist"
          },
          "versions": [
            "0.10",
            "0.6",
            "0.7",
            "0.8",
            "0.9",
            "1.0.0"
          ],
          "database_specific": {
            "source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-qv4m-m73m-8hj7/GHSA-qv4m-m73m-8hj7.json",
            "last_known_affected_version_range": "<= 1.0.0"
          }
        }
      ],
      "modified": "2026-10-27T15:15:07.978557694Z",
      "provider": "osv",
      "references": [
        "https://github.com/notrinos/NotrinosERP/security/advisories/GHSA-qv4m-m73m-8hj7",
        "https://github.com/notrinos/NotrinosERP/commit/71cac7cd199e40cff7f2b18551620133e29f8967",
        "https://github.com/notrinos/NotrinosERP",
        "https://github.com/notrinos/NotrinosERP/releases/tag/1.1.0"
      ],
      "provider_metadata": {
        "cwe_ids": [
          "CWE-22",
          "CWE-434"
        ],
        "severity": "HIGH",
        "github_reviewed": true,
        "nvd_published_at": null,
        "github_reviewed_at": "2026-07-10T19:34:03Z"
      }
    },
    "related_cves": [
      {
        "value": "CVE-2026-76913",
        "evidence": "/aliases"
      }
    ],
    "security_relevant": true,
    "severity_evidence": "/database_specific/severity"
  },
  "source_id": "core-osv",
  "document_id": 462823,
  "published_at": "2026-07-10T19:34:03+00:00"
}