Four npm packages posed as MCP documentation helpers while their code moved from cloud reconnaissance to temporary-credential retrieval and an unpinned install path.
Four npm packages advertised Markdown help and exposed a very different purpose once they ran. GitHub published malware advisories for the four @ifasn packages at 21:31 UTC on November 2. Across them, the advisory database lists 25 affected versions and no patched release.
The packages were named md-doc-mcp, mdd-doc-mcp, mmd-doc-mcp and mmdd-doc-mcp. That slight spelling drift matters: a reviewer scanning a dependency list could read them as iterations of the same harmless documentation utility. The code described by GitHub instead probed cloud instance metadata, reported environmental signals outside the host and retrieved temporary Alibaba Cloud RAM credentials in two variants, one of which also probed high-value local secret paths.
An MCP integration is executable software placed beside the files, tokens and cloud roles that make an agent useful. Its permission boundary is the process that launches it.
GitHub’s November 2 advisories say the four packages presented themselves as Markdown MCP tools while their runtime behavior reached into cloud metadata and, in two variants, the temporary-credential path for an attached Alibaba Cloud role.
Four spellings, one trust decision
The family did not repeat one behavior across four names. The variants formed a progression.
GitHub says md-doc-mcp ran on import or startup, checked metadata services associated with AWS, Google Cloud, Azure and Alibaba Cloud, then sent the returned signals to a hard-coded external destination. The returned pattern could identify the cloud environment.
The mmd-doc-mcp variant also probed multiple cloud metadata services and reported per-endpoint status codes externally. Its advisory says the pattern could reveal both the cloud provider and whether an attached IAM or RAM role was present. The package framed the activity as health checking and configuration synchronization, but the advisory notes that the queried locations were cloud metadata and credential services, unrelated to Markdown processing.
The other two variants went further. GitHub says mdd-doc-mcp requested an Alibaba metadata token, reached the RAM temporary-credential location and wrote the response locally. Its package manifest also pulled a dependency from an unencrypted, unpinned remote archive with no integrity check, creating an install-time path for whatever code that remote host returned.
The mmdd-doc-mcp advisory describes the same temporary-credential retrieval plus scripts that enumerated familiar locations for an SSH private key, an environment file and a Kubernetes service-account token. Those are categories of identity material that can move an intrusion from one developer tool into cloud, source-control or cluster access.
The four package names varied only by repeated m and d characters, while GitHub documented materially different behaviors across the family: environment discovery, external reporting, credential retrieval and an unpinned installation dependency.
Three gates failed before the helper reached a role
The first gate is installation provenance. The mdd variant did not bind every installed byte to the registry package and its lockfile. Its remote archive could change independently of the named release.
The second gate is startup behavior. GitHub says code in this family ran on import, startup or installation. A user did not have to invoke a suspicious feature after the helper was loaded.
The third gate is runtime reach. An IDE, local agent client, build runner or cloud development machine determines which metadata services, files and outbound destinations the process can reach. On a laptop that can include source repositories and environment variables. In CI it can include deployment tokens. On a cloud instance or cluster it can include a workload role or mounted service account.
Reviewing an MCP integration therefore requires three answers: Were all installed bytes integrity-bound? What executes automatically? Which metadata, filesystem and egress paths are available at runtime?
The runner’s runtime context determines the reachable identity material. The advisories describe cloud-role discovery and probing of local secret paths; they do not establish that every listed artifact existed on every installer.
Three stages the public artifacts establish
The public evidence supports several distinct stages.
First, the packages were published under four closely related names and presented as Markdown or documentation tools. Second, the advisory descriptions identify code that executed on import, startup or installation. Third, that code performed cloud reconnaissance, contacted an external destination, accessed temporary credentials or probed local secret paths, depending on the variant.
GitHub and OpenSSF do not publish installation totals, a victim count or a confirmed downstream account compromise. The four advisories also belong to one linked evidence chain: GitHub credits OpenSSF, whose records carry analysis attributed to Amazon Inspector. Four records should not be counted as four independent observations.
That boundary still leaves a serious incident-response problem. Temporary credentials can expire while the authority that issued them remains usable. A package that read a local response may also have run beside longer-lived secrets. An unpinned remote dependency creates a wider uncertainty because the installed bytes could change independently of the named package version.
The response should reconstruct the three gates, not rely on the package description.
Close each gate before the runner returns
Start with provenance: establish where any of the four names appeared, then search lockfiles, package manifests, dependency inventories, build logs and cached artifacts. Preserve the relevant package and logs without executing it again.
Next, reconstruct startup and runtime reach:
Isolate the developer machine, runner or workload that loaded the package and preserve its process and network evidence.
Review cloud audit records for metadata-backed role use and unexpected API activity from the affected time window.
Revoke active sessions and replace reachable SSH, environment, service-account and deployment secrets from a trusted system.
For the variant with the remote unpinned archive, rebuild the execution environment from a known-good image rather than trusting an in-place cleanup.
Check outbound telemetry for the destination and behavior published in the advisories, while keeping raw credentials and sensitive logs out of tickets and chat.
Rotation order should follow privilege and reach. A production role or cluster identity deserves attention before a low-impact development token, but the inventory must decide that priority. Rotating every credential without preserving evidence can destroy the timeline while leaving the original execution path intact.
The response isolates the runner, preserves evidence, replaces reachable identity material and rebuilds any environment that installed the unpinned remote dependency.
Agent tools need an execution contract
The durable control is an explicit contract across provenance, startup behavior and runtime reach.
Run agent tools and MCP servers in disposable, least-privileged environments. Keep production credentials out of interactive agent sessions. Restrict access to cloud metadata unless the workload explicitly needs it. Limit outbound traffic from build and agent runners. Pin dependencies with integrity metadata, review package provenance and approve MCP servers as executable integrations rather than treating them as content plugins.
Logging should preserve the join between package version, execution host, workload identity and outbound connection. Without that join, responders can find the dependency but cannot determine what authority surrounded it.
The four @ifasn advisories are useful because they expose all three gates in concrete code behavior. A tool that promised tables of contents reached for cloud identity. The next control is to require pinned bytes, bounded startup behavior and a runtime with no unnecessary metadata, files or egress.






