registry  /  php-app  /  0.1.3

php-app@0.1.3

PHP loyihasini desktop ilovaga aylantiruvchi CLI (PHP, HTML, CSS, JS)

AI Security Review

scanned 5h ago · by lpm-firewall-ai

Automatic installation downloads and extracts a remote platform-specific PHP executable without verifying its integrity. Later runtime execution trusts the extracted binary.

Static reason
One or more suspicious static signals were detected.
Trigger
`npm install php-app@0.1.3` downloads the payload; explicit `php-app run` executes it.
Impact
A compromised or substituted download can yield arbitrary code execution when the package is run.
Mechanism
Unverified install-time remote binary staging followed by runtime execution.
Rationale
This package has a concrete unverified remote-binary supply-chain risk activated by `postinstall`, but the inspected source does not prove deliberately malicious behavior. Warn rather than block under the stated lifecycle policy.
Evidence
package.jsonscripts/postinstall.jsruntime/main.jsbin/php-app.jslib/phpapp.phplib/router.phpruntime/php-bin/<platform>/php/tmp/php-app-php-<version>-cli-<platform>.<archive>
Network endpoints3
dl.static-php.dev/static-php-cli/common/registry.npmjs.org/php-app/latest127.0.0.1:<dynamic-port>

Decision evidence

public snapshot
AI called this Suspicious at 91.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
  • `scripts/postinstall.js` runs automatically after install and downloads a platform PHP archive from `https://dl.static-php.dev/static-php-cli/common/...`.
  • The lifecycle script writes the remote archive under the OS temp directory, extracts it into `runtime/php-bin/<platform>/`, and marks the resulting PHP executable runnable.
  • No checksum, signature, pinned digest, or other integrity verification is applied before the downloaded executable is trusted.
  • `runtime/main.js` later selects `runtime/php-bin/.../php` and executes it for `php-app run`.
Evidence against
  • `package.json` contains no preinstall hook; its only lifecycle hook is the visible `postinstall` downloader.
  • Observed network endpoints are the static PHP host, npm registry update lookup, and loopback control/runtime servers; no credential collection or third-party exfiltration appears in inspected source.
  • `runtime/main.js` binds control and PHP servers to `127.0.0.1` and protects bridge requests with random tokens.
  • `bin/php-app.js` child-process calls implement explicit CLI `run`, `build`, `doctor`, and `update` functions.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetwork
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 4 file(s), 32.8 KB of source, external domains: 127.0.0.1, dl.static-php.dev, nodejs.org, registry.npmjs.org

Source & flagged code

9 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/postinstall.js
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node scripts/postinstall.js
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
bin/php-app.jsView file
4const fs = require('fs'); L5: const { spawn, spawnSync } = require('child_process'); L6: const os = require('os');
High
Child Process

Package source references child process execution.

bin/php-app.jsView on unpkg · L4
2'use strict'; L3: const path = require('path'); L4: const fs = require('fs');
Medium
Dynamic Require

Package source references dynamic require/import behavior.

bin/php-app.jsView on unpkg · L2
runtime/main.jsView file
130const env = { L131: ...process.env, L132: PHPAPP_CONTROL_URL: `http://127.0.0.1:${controlPort}`, L133: PHPAPP_TOKEN: CONTROL_TOKEN, ... L137: const router = path.join(libDir, 'router.php'); L138: phpProc = spawn(phpBin, ['-d', 'include_path=' + libDir + path.delimiter + '.', '-S', `127.0.0.1:${phpPort}`, '-t', docroot, router], { env, cwd: docroot }); L139: phpProc.stdout.on('data', (d) => process.stdout.write('[php] ' + d));
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

runtime/main.jsView on unpkg · L130
131...process.env, L132: PHPAPP_CONTROL_URL: `http://127.0.0.1:${controlPort}`, L133: PHPAPP_TOKEN: CONTROL_TOKEN, ... L137: const router = path.join(libDir, 'router.php'); L138: phpProc = spawn(phpBin, ['-d', 'include_path=' + libDir + path.delimiter + '.', '-S', `127.0.0.1:${phpPort}`, '-t', docroot, router], { env, cwd: docroot }); L139: phpProc.stdout.on('data', (d) => process.stdout.write('[php] ' + d)); L140: phpProc.stderr.on('data', (d) => process.stdout.write('[php] ' + d));
High
Command Output Exfiltration

Source combines command execution, command-output handling, and outbound requests; review data flow before blocking.

runtime/main.jsView on unpkg · L131
scripts/postinstall.jsView file
4const os = require('os'); L5: const { spawnSync } = require('child_process'); L6: L7: const PHP_VERSION = process.env.PHPAPP_PHP_VERSION || '8.4.23'; L8: const VERSION = (() => { try { return require(path.join(__dirname, '..', 'package.json')).version; } catch (_) { return ''; } })(); L9: ... L19: try { L20: if (process.platform !== 'win32') { L21: const fd = fs.openSync('/dev/tty', 'w'); ... L26: } catch (_) {} L27: process.stdout.write(msg); L28: }
High
Sandbox Evasion Gated Capability

Source gates dangerous network, credential, or execution behavior behind CI, host, platform, time, or geo fingerprint checks.

scripts/postinstall.jsView on unpkg · L4
4const os = require('os'); L5: const { spawnSync } = require('child_process'); L6: L7: const PHP_VERSION = process.env.PHPAPP_PHP_VERSION || '8.4.23'; L8: const VERSION = (() => { try { return require(path.join(__dirname, '..', 'package.json')).version; } catch (_) { return ''; } })(); L9: ... L19: try { L20: if (process.platform !== 'win32') { L21: const fd = fs.openSync('/dev/tty', 'w'); ... L26: } catch (_) {} L27: process.stdout.write(msg); L28: }
High
Install Named Payload File

Install-named source file stages remote content through filesystem writes and execution.

scripts/postinstall.jsView on unpkg · L4
bin/fetch-php.shView file
path = bin/fetch-php.sh kind = build_helper sizeBytes = 851 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

bin/fetch-php.shView on unpkg

Findings

6 High6 Medium4 Low
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processbin/php-app.js
HighSame File Env Network Executionruntime/main.js
HighCommand Output Exfiltrationruntime/main.js
HighSandbox Evasion Gated Capabilityscripts/postinstall.js
HighInstall Named Payload Filescripts/postinstall.js
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requirebin/php-app.js
MediumNetwork
MediumEnvironment Vars
MediumShips Build Helperbin/fetch-php.sh
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings