CVE-2026-14480 (GCVE-0-2026-14480)
Vulnerability from cvelistv5
Published
2026-07-10 22:17
Modified
2026-07-13 15:41
CWE
Summary
OpenPLC Runtime v3 contains an authenticated arbitrary file write vulnerability in the legacy web UI program‑upload workflow. The application stores an attacker‑supplied filename (prog_file) directly into the Programs.File database field and later uses this value as the destination path for an uploaded file without validating or restricting the path. Because Python os.path.join() honors attacker‑controlled absolute paths, an authenticated user can write arbitrary files anywhere writable by the OpenPLC webserver process. In the default build pipeline, all C++ source files within the OpenPLC runtime core directory are automatically compiled into the executable runtime binary. By writing a malicious .cpp file into this directory, an authenticated attacker can escalate the arbitrary file write into arbitrary native code execution when the operator triggers a normal program compilation and runtime start.
Impacted products
Vendor Product Version
OpenPLC OpenPLC Version: v3
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "adp": [
      {
        "metrics": [
          {
            "other": {
              "content": {
                "id": "CVE-2026-14480",
                "options": [
                  {
                    "Exploitation": "none"
                  },
                  {
                    "Automatable": "no"
                  },
                  {
                    "Technical Impact": "total"
                  }
                ],
                "role": "CISA Coordinator",
                "timestamp": "2026-07-13T15:40:59.399646Z",
                "version": "2.0.3"
              },
              "type": "ssvc"
            }
          }
        ],
        "providerMetadata": {
          "dateUpdated": "2026-07-13T15:41:57.195Z",
          "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
          "shortName": "CISA-ADP"
        },
        "title": "CISA ADP Vulnrichment"
      }
    ],
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "OpenPLC",
          "vendor": "OpenPLC",
          "versions": [
            {
              "status": "affected",
              "version": "v3"
            },
            {
              "status": "unaffected",
              "version": "v4"
            }
          ]
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "Grady DeRosa reported this vulnerability to CISA."
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "OpenPLC Runtime v3 contains an authenticated arbitrary file write \nvulnerability in the legacy web UI program\u2011upload workflow. The \napplication stores an attacker\u2011supplied filename (prog_file) directly \ninto the Programs.File database field and later uses this value as the \ndestination path for an uploaded file without validating or restricting \nthe path. Because Python os.path.join() honors attacker\u2011controlled \nabsolute paths, an authenticated user can write arbitrary files anywhere\n writable by the OpenPLC webserver process. In the default build \npipeline, all C++ source files within the OpenPLC runtime core directory\n are automatically compiled into the executable runtime binary. By \nwriting a malicious .cpp file into this directory, an authenticated \nattacker can escalate the arbitrary file write into arbitrary native \ncode execution when the operator triggers a normal program compilation \nand runtime start."
            }
          ],
          "value": "OpenPLC Runtime v3 contains an authenticated arbitrary file write \nvulnerability in the legacy web UI program\u2011upload workflow. The \napplication stores an attacker\u2011supplied filename (prog_file) directly \ninto the Programs.File database field and later uses this value as the \ndestination path for an uploaded file without validating or restricting \nthe path. Because Python os.path.join() honors attacker\u2011controlled \nabsolute paths, an authenticated user can write arbitrary files anywhere\n writable by the OpenPLC webserver process. In the default build \npipeline, all C++ source files within the OpenPLC runtime core directory\n are automatically compiled into the executable runtime binary. By \nwriting a malicious .cpp file into this directory, an authenticated \nattacker can escalate the arbitrary file write into arbitrary native \ncode execution when the operator triggers a normal program compilation \nand runtime start."
        }
      ],
      "metrics": [
        {
          "cvssV3_1": {
            "attackComplexity": "LOW",
            "attackVector": "NETWORK",
            "availabilityImpact": "HIGH",
            "baseScore": 9.9,
            "baseSeverity": "CRITICAL",
            "confidentialityImpact": "HIGH",
            "integrityImpact": "HIGH",
            "privilegesRequired": "LOW",
            "scope": "CHANGED",
            "userInteraction": "NONE",
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
            "version": "3.1"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        },
        {
          "cvssV4_0": {
            "Automatable": "NOT_DEFINED",
            "Recovery": "NOT_DEFINED",
            "Safety": "NOT_DEFINED",
            "attackComplexity": "LOW",
            "attackRequirements": "NONE",
            "attackVector": "NETWORK",
            "baseScore": 8.7,
            "baseSeverity": "HIGH",
            "exploitMaturity": "NOT_DEFINED",
            "privilegesRequired": "LOW",
            "providerUrgency": "NOT_DEFINED",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "NONE",
            "userInteraction": "NONE",
            "valueDensity": "NOT_DEFINED",
            "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
            "version": "4.0",
            "vulnAvailabilityImpact": "HIGH",
            "vulnConfidentialityImpact": "HIGH",
            "vulnIntegrityImpact": "HIGH",
            "vulnerabilityResponseEffort": "NOT_DEFINED"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-73",
              "description": "CWE-73",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-07-10T22:17:49.406Z",
        "orgId": "7d14cffa-0d7d-4270-9dc0-52cabd5a23a6",
        "shortName": "icscert"
      },
      "references": [
        {
          "url": "https://www.cisa.gov/news-events/ics-advisories/icsa-26-190-01"
        },
        {
          "url": "https://github.com/cisagov/CSAF/blob/develop/csaf_files/OT/white/2026/icsa-26-190-01.json"
        }
      ],
      "solutions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "OpenPLC recommends users upgrade to OpenPLC v4 as OpenPLC v3 is \nend-of-life and is no longer receiving patches, bug fixes, or security \nupdates."
            }
          ],
          "value": "OpenPLC recommends users upgrade to OpenPLC v4 as OpenPLC v3 is \nend-of-life and is no longer receiving patches, bug fixes, or security \nupdates."
        }
      ],
      "source": {
        "advisory": "ICSA-26-190-01",
        "discovery": "EXTERNAL"
      },
      "title": "OpenPLC v3 External Control of File Name or Path",
      "x_generator": {
        "engine": "Vulnogram 1.0.2"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "7d14cffa-0d7d-4270-9dc0-52cabd5a23a6",
    "assignerShortName": "icscert",
    "cveId": "CVE-2026-14480",
    "datePublished": "2026-07-10T22:17:49.406Z",
    "dateReserved": "2026-07-02T16:00:30.030Z",
    "dateUpdated": "2026-07-13T15:41:57.195Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2",
  "vulnerability-lookup:meta": {
    "vulnrichment": {
      "containers": "{\"adp\": [{\"title\": \"CISA ADP Vulnrichment\", \"metrics\": [{\"other\": {\"type\": \"ssvc\", \"content\": {\"id\": \"CVE-2026-14480\", \"role\": \"CISA Coordinator\", \"options\": [{\"Exploitation\": \"none\"}, {\"Automatable\": \"no\"}, {\"Technical Impact\": \"total\"}], \"version\": \"2.0.3\", \"timestamp\": \"2026-07-13T15:40:59.399646Z\"}}}], \"providerMetadata\": {\"orgId\": \"134c704f-9b21-4f2e-91b3-4a467353bcc0\", \"shortName\": \"CISA-ADP\", \"dateUpdated\": \"2026-07-13T15:41:51.949Z\"}}], \"cna\": {\"title\": \"OpenPLC v3 External Control of File Name or Path\", \"source\": {\"advisory\": \"ICSA-26-190-01\", \"discovery\": \"EXTERNAL\"}, \"credits\": [{\"lang\": \"en\", \"type\": \"finder\", \"value\": \"Grady DeRosa reported this vulnerability to CISA.\"}], \"metrics\": [{\"format\": \"CVSS\", \"cvssV3_1\": {\"scope\": \"CHANGED\", \"version\": \"3.1\", \"baseScore\": 9.9, \"attackVector\": \"NETWORK\", \"baseSeverity\": \"CRITICAL\", \"vectorString\": \"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H\", \"integrityImpact\": \"HIGH\", \"userInteraction\": \"NONE\", \"attackComplexity\": \"LOW\", \"availabilityImpact\": \"HIGH\", \"privilegesRequired\": \"LOW\", \"confidentialityImpact\": \"HIGH\"}, \"scenarios\": [{\"lang\": \"en\", \"value\": \"GENERAL\"}]}, {\"format\": \"CVSS\", \"cvssV4_0\": {\"Safety\": \"NOT_DEFINED\", \"version\": \"4.0\", \"Recovery\": \"NOT_DEFINED\", \"baseScore\": 8.7, \"Automatable\": \"NOT_DEFINED\", \"attackVector\": \"NETWORK\", \"baseSeverity\": \"HIGH\", \"valueDensity\": \"NOT_DEFINED\", \"vectorString\": \"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N\", \"exploitMaturity\": \"NOT_DEFINED\", \"providerUrgency\": \"NOT_DEFINED\", \"userInteraction\": \"NONE\", \"attackComplexity\": \"LOW\", \"attackRequirements\": \"NONE\", \"privilegesRequired\": \"LOW\", \"subIntegrityImpact\": \"NONE\", \"vulnIntegrityImpact\": \"HIGH\", \"subAvailabilityImpact\": \"NONE\", \"vulnAvailabilityImpact\": \"HIGH\", \"subConfidentialityImpact\": \"NONE\", \"vulnConfidentialityImpact\": \"HIGH\", \"vulnerabilityResponseEffort\": \"NOT_DEFINED\"}, \"scenarios\": [{\"lang\": \"en\", \"value\": \"GENERAL\"}]}], \"affected\": [{\"vendor\": \"OpenPLC\", \"product\": \"OpenPLC\", \"versions\": [{\"status\": \"affected\", \"version\": \"v3\"}, {\"status\": \"unaffected\", \"version\": \"v4\"}], \"defaultStatus\": \"unaffected\"}], \"solutions\": [{\"lang\": \"en\", \"value\": \"OpenPLC recommends users upgrade to OpenPLC v4 as OpenPLC v3 is \\nend-of-life and is no longer receiving patches, bug fixes, or security \\nupdates.\", \"supportingMedia\": [{\"type\": \"text/html\", \"value\": \"OpenPLC recommends users upgrade to OpenPLC v4 as OpenPLC v3 is \\nend-of-life and is no longer receiving patches, bug fixes, or security \\nupdates.\", \"base64\": false}]}], \"references\": [{\"url\": \"https://www.cisa.gov/news-events/ics-advisories/icsa-26-190-01\"}, {\"url\": \"https://github.com/cisagov/CSAF/blob/develop/csaf_files/OT/white/2026/icsa-26-190-01.json\"}], \"x_generator\": {\"engine\": \"Vulnogram 1.0.2\"}, \"descriptions\": [{\"lang\": \"en\", \"value\": \"OpenPLC Runtime v3 contains an authenticated arbitrary file write \\nvulnerability in the legacy web UI program\\u2011upload workflow. The \\napplication stores an attacker\\u2011supplied filename (prog_file) directly \\ninto the Programs.File database field and later uses this value as the \\ndestination path for an uploaded file without validating or restricting \\nthe path. Because Python os.path.join() honors attacker\\u2011controlled \\nabsolute paths, an authenticated user can write arbitrary files anywhere\\n writable by the OpenPLC webserver process. In the default build \\npipeline, all C++ source files within the OpenPLC runtime core directory\\n are automatically compiled into the executable runtime binary. By \\nwriting a malicious .cpp file into this directory, an authenticated \\nattacker can escalate the arbitrary file write into arbitrary native \\ncode execution when the operator triggers a normal program compilation \\nand runtime start.\", \"supportingMedia\": [{\"type\": \"text/html\", \"value\": \"OpenPLC Runtime v3 contains an authenticated arbitrary file write \\nvulnerability in the legacy web UI program\\u2011upload workflow. The \\napplication stores an attacker\\u2011supplied filename (prog_file) directly \\ninto the Programs.File database field and later uses this value as the \\ndestination path for an uploaded file without validating or restricting \\nthe path. Because Python os.path.join() honors attacker\\u2011controlled \\nabsolute paths, an authenticated user can write arbitrary files anywhere\\n writable by the OpenPLC webserver process. In the default build \\npipeline, all C++ source files within the OpenPLC runtime core directory\\n are automatically compiled into the executable runtime binary. By \\nwriting a malicious .cpp file into this directory, an authenticated \\nattacker can escalate the arbitrary file write into arbitrary native \\ncode execution when the operator triggers a normal program compilation \\nand runtime start.\", \"base64\": false}]}], \"problemTypes\": [{\"descriptions\": [{\"lang\": \"en\", \"type\": \"CWE\", \"cweId\": \"CWE-73\", \"description\": \"CWE-73\"}]}], \"providerMetadata\": {\"orgId\": \"7d14cffa-0d7d-4270-9dc0-52cabd5a23a6\", \"shortName\": \"icscert\", \"dateUpdated\": \"2026-07-10T22:17:49.406Z\"}}}",
      "cveMetadata": "{\"cveId\": \"CVE-2026-14480\", \"state\": \"PUBLISHED\", \"dateUpdated\": \"2026-07-13T15:41:57.195Z\", \"dateReserved\": \"2026-07-02T16:00:30.030Z\", \"assignerOrgId\": \"7d14cffa-0d7d-4270-9dc0-52cabd5a23a6\", \"datePublished\": \"2026-07-10T22:17:49.406Z\", \"assignerShortName\": \"icscert\"}",
      "dataType": "CVE_RECORD",
      "dataVersion": "5.2"
    }
  }
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
  • Confirmed: The vulnerability is confirmed from an analyst perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
  • Patched: This vulnerability was successfully patched by the user reporting the sighting.
  • Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
  • Not confirmed: The user expresses doubt about the veracity of the vulnerability.
  • Not patched: This vulnerability was not successfully patched by the user reporting the sighting.


Loading…

Loading…