registry  /  @lystech/core  /  3.0.87

@lystech/core@3.0.87

Lystech Core contains essentials for lystech apps

AI Security Review

scanned 1h ago · by lpm-firewall-ai

Installation mutates a consuming project's GitHub Actions configuration without an affirmative user command. The persisted workflow runs on future pushes and reports repository metadata to a third-party registry endpoint.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
`npm install @lystech/core` executes the declared `postinstall` hook in a consumer project.
Impact
Unauthorised CI persistence and third-party collection of consumer repository identity.
Mechanism
postinstall GitHub Actions workflow injection with repository metadata reporting
Attack narrative
On installation, the postinstall hook inspects the consumer project's manifest and writes `.github/workflows/sync-package-registry.yml` without prompting. That workflow runs on pushes, uses the repository-scoped GitHub token to query GitHub for the repository ID, and sends the package name plus owner, repository name, and repository ID to a DigitalOcean-hosted registry. The installation-created workflow remains in the project and executes independently of future package imports.
Rationale
This is concrete unconsented install-time mutation of a consumer CI control surface combined with external reporting and persistence. The frontend bundle's normal Firebase/API traffic does not mitigate the lifecycle behavior.
Evidence
package.jsonbin/postinstall.cjsbin/setup-registry.cjsbin/setup-github-action.cjsdist/lystech-core-provider.es.js.github/workflows/sync-package-registry.yml
Network endpoints2
api.github.com/repos/$OWNER/$REPO_NAMElysbunback-usgg4.ondigitalocean.app/api/package-registry

Decision evidence

public snapshot
AI called this Malicious at 96.0% confidence as Malware with low false-positive risk.
Evidence for block
  • `package.json` runs `bin/postinstall.cjs` on installation.
  • `bin/postinstall.cjs` unconditionally creates `.github/workflows/sync-package-registry.yml` in the consumer project unless already present or opt-out env is set.
  • The injected push-triggered workflow reads GitHub repository identity using `secrets.GITHUB_TOKEN`.
  • The workflow POSTs package name, owner, repository name, and repository ID to `lysbunback-usgg4.ondigitalocean.app`.
  • The generated workflow persists after installation and runs on subsequent pushes.
Evidence against
  • The injected workflow does not transmit the GitHub token itself.
  • Bundle review found no package-owned `child_process`, shell, `eval`, or dynamic-code execution.
Behavioral surface
Source
ChildProcessEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsMinifiedTelemetryUrlStrings
ManifestNo manifest risk signals triggered.
scanned 6 file(s), 2.17 MB of source, external domains: accounts.google.com, ant.design, api.github.com, api.lystech.ca, apis.google.com, github.com, jedwatson.github.io, lysbunback-usgg4.ondigitalocean.app, lystech.firebaseio.com, momentjs.com, placehold.co, react-query.tanstack.com, reactjs.org, reactrouter.com, u.ant.design, www.google.com, www.paypal.com, www.sandbox.paypal.com, www.w3.org
Oversized source lightweight scan
dist/lystech-core-provider.es.js2.39 MB file, sampled 256 KB
NetworkChildProcessEnvironmentVarsHighEntropyStringsUrlStringsmomentjs.comreactjs.orgwww.google.comwww.paypal.comwww.sandbox.paypal.com

Source & flagged code

7 flagged · loading source
package.jsonView file
scripts.postinstall = node bin/postinstall.cjs
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

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

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

package.jsonView on unpkg
dist/lystech-core-provider.umd.jsView file
16* LICENSE file in the root directory of this source tree. L17: */var Pp;function T4(){return Pp||(Pp=1,process.env.NODE_ENV!=="production"&&function(){var e=O,t=Symbol.for("react.element"),n=Symbol.for("react.portal"),r=Symbol.for("react.fragm... L18: `+ae+K}}var ie=!1,le;{var G=typeof WeakMap=="function"?WeakMap:Map;le=new G}function te(K,Pe){if(!K||ie)return"";{var Fe=le.get(K);if(Fe!==void 0)return Fe}var Be;ie=!0;var at=Erro... ... L20: `),xt=ut.length-1,At=Bt.length-1;xt>=1&&At>=0&&ut[xt]!==Bt[At];)At--;for(;xt>=1&&At>=0;xt--,At--)if(ut[xt]!==Bt[At]){if(xt!==1||At!==1)do if(xt--,At--,At<0||ut[xt]!==Bt[At]){var We... L21: `+ut[xt].replace(" at new "," at ");return K.displayName&&We.includes("<anonymous>")&&(We=We.replace("<anonymous>",K.displayName)),typeof K=="function"&&le.set(K,We),We}while(xt>=1... L22: ... L59: * limitations under the License. L60: */const Np=function(e){const t=[];let n=0;for(let r=0;r<e.length;r++){let a=e.charCodeAt(r);a<128?t[n++]=a:a<2048?(t[n++]=a>>6|192,t[n++]=a&63|128):(a&64512)===55296&&r+1<e.length&... L61: * @license ... L374: * limitations under the License. L375: */function s6(e){bs(new oo("platform-logger",t=>new SO(t),"PRIVATE")),bs(ne
Critical
Credential Exfiltration

Source appears to send environment or credential material to an external endpoint.

dist/lystech-core-provider.umd.jsView on unpkg · L16
16Trigger-reachable chain: manifest.main -> dist/lystech-core-provider.umd.js L16: * LICENSE file in the root directory of this source tree. L17: */var Pp;function T4(){return Pp||(Pp=1,process.env.NODE_ENV!=="production"&&function(){var e=O,t=Symbol.for("react.element"),n=Symbol.for("react.portal"),r=Symbol.for("react.fragm... L18: `+ae+K}}var ie=!1,le;{var G=typeof WeakMap=="function"?WeakMap:Map;le=new G}function te(K,Pe){if(!K||ie)return"";{var Fe=le.get(K);if(Fe!==void 0)return Fe}var Be;ie=!0;var at=Erro... ... L20: `),xt=ut.length-1,At=Bt.length-1;xt>=1&&At>=0&&ut[xt]!==Bt[At];)At--;for(;xt>=1&&At>=0;xt--,At--)if(ut[xt]!==Bt[At]){if(xt!==1||At!==1)do if(xt--,At--,At<0||ut[xt]!==Bt[At]){var We... L21: `+ut[xt].replace(" at new "," at ");return K.displayName&&We.includes("<anonymous>")&&(We=We.replace("<anonymous>",K.displayName)),typeof K=="function"&&le.set(K,We),We}while(xt>=1... L22: ... L59: * limitations under the License. L60: */const Np=function(e){const t=[];let n=0;for(let r=0;r<e.length;r++){let a=e.charCodeAt(r);a<128?t[n++]=a:a<2048?(t[n++]=a>>6|192,t[n++]=a&63|128):(a&64512)===55296&&r+1<e.length&... L61: * @license ... L374: * limitations under the License. L375…
Critical
Trigger Reachable Dangerous Capability

A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.

dist/lystech-core-provider.umd.jsView on unpkg · L16
1727patternName = google_api_key severity = high line = 1727 matchedText = }`;funct...nce.
High
High Secret

Package contains a high-severity secret pattern.

dist/lystech-core-provider.umd.jsView on unpkg · L1727
1727patternName = google_api_key severity = high line = 1727 matchedText = }`;funct...nce.
High
Secret Pattern

Google API key in dist/lystech-core-provider.umd.js

dist/lystech-core-provider.umd.jsView on unpkg · L1727
dist/lystech-core-provider.es.jsView file
path = dist/lystech-core-provider.es.js kind = oversized_source_file sizeBytes = 2505301 magicHex = [redacted]
High
Oversized Source File

Package contains source files above the static scanner size ceiling.

dist/lystech-core-provider.es.jsView on unpkg

Findings

2 Critical4 High4 Medium5 Low
CriticalCredential Exfiltrationdist/lystech-core-provider.umd.js
CriticalTrigger Reachable Dangerous Capabilitydist/lystech-core-provider.umd.js
HighInstall Time Lifecycle Scriptspackage.json
HighHigh Secretdist/lystech-core-provider.umd.js
HighOversized Source Filedist/lystech-core-provider.es.js
HighSecret Patterndist/lystech-core-provider.umd.js
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowTelemetry
LowUrl Strings