JordanDalton/composer-mcp-server
criticalUsing AI, install Composer PHP packages with ease.
This MCP server provides an AI-powered interface for installing Composer PHP packages. It generates the appropriate composer require command, fetches ...
144async function fetchPackageInfo(packageName: string): Promise<any> {
145 try {
146 const response = await axios.get(`https://packagist.org/packages/${packageName}.json`);
147 if (response.data && response.data.package) {
148 return response.data.package;
149 }
150 return null;
151 } catch (error) {
152 console.error(`Error fetching package info from Packagist: ${error}`);
153 return null;
154 }
155 }// Exploitable if MCP is exposed to untrusted prompts (network_exposed).
The package name from user input is directly interpolated into the URL for the Packagist API request without validation. An attacker could inject path traversal or special characters to make requests to arbitrary endpoints on packagist.org or potentially other hosts if the base URL is manipulated.
ImpactAn attacker could potentially access internal services or perform SSRF attacks by crafting a malicious package name that alters the URL path, though the domain is fixed to packagist.org. The risk is limited but present.
FixValidate the package name against a strict pattern (e.g., vendor/package format) before constructing the URL. Use URL encoding or a parameterized approach.
158async function fetchGitHubReadme(repoUrl: string): Promise<string | null> {
159 try {
160 const match = repoUrl.match(/github\.com\/([^\/]+\/[^\/]+)/);
161 if (!match) return null;
162
163 const repo = match[1];
164 const apiUrl = `https://api.github.com/repos/${repo}/readme`;
165
166 const response = await axios.get(apiUrl, {
167 headers: {
168 'Accept': 'application/vnd.github.v3.raw'
169 }
170 });
171
172 return response.data;
173 } catch (error) {
174 console.error(`Error fetching README from GitHub: ${error}`);
175 return null;
176 }
177 }// Exploitable if MCP is exposed to untrusted prompts (network_exposed).
The repository URL is extracted from Packagist data, which is indirectly user-controlled via the package name. The regex extraction is relatively safe, but if the repository URL from Packagist is manipulated (e.g., via a malicious package), it could lead to SSRF against GitHub API or other hosts.
ImpactAn attacker could potentially cause the server to make requests to arbitrary URLs if they can influence the repository URL returned by Packagist, though this requires control over a Packagist package.
FixValidate that the repository URL matches expected patterns and restrict to known domains. Consider caching or using a whitelist.
182async function fetchGitLabReadme(repoUrl: string): Promise<string | null> {
183 try {
184 const match = repoUrl.match(/gitlab\.com\/([^\/]+\/[^\/]+)/);
185 if (!match) return null;
186
187 const projectId = encodeURIComponent(match[1]);
188 const apiUrl = `https://gitlab.com/api/v4/projects/${projectId}/repository/files/README.md/raw`;
189
190 const response = await axios.get(apiUrl);
191 return response.data;
192 } catch (error) {
193 console.error(`Error fetching README from GitLab: ${error}`);
194 return null;
195 }
196 }// Exploitable if MCP is exposed to untrusted prompts (network_exposed).
Similar to GitHub, the repository URL from Packagist is used to construct a GitLab API request. Although encodeURIComponent is used, the URL is still derived from user-controlled data, potentially allowing SSRF if the repository URL is malicious.
ImpactAn attacker could cause requests to arbitrary GitLab projects or potentially other hosts if the regex is bypassed.
FixValidate the repository URL against a strict pattern and restrict to known domains.
17server.tool("install_package",
18 {
19 package: z.string().describe("The package name to install"),
20 version: z.string().optional().describe("The version of the package to install")
21 },// Exploitable if MCP is exposed to untrusted prompts (network_exposed).
The package name is accepted as a free-form string without any validation (e.g., regex for vendor/package format). This allows injection of special characters that could affect URL construction or command generation.
ImpactAn attacker could provide a package name with path traversal characters or other payloads, potentially leading to SSRF or other injection attacks.
FixAdd Zod validation to enforce a pattern like /^[a-z0-9_-]+/[a-z0-9_-]+$/ for the package name.