Using GitHub Actions with branch references instead of SHA pins enables supply chain attacks.
uses: actions/checkout@v4
Pin GitHub Actions to full commit SHAs: uses: actions/checkout@abc123...
Direct usage of child_process module methods with variable arguments may allow command injection.
const { execSync } = require('child_process');Use execFile with explicit argument arrays instead of child_process with string commands.
Detected console.log() usage in non-test source code. Console.log is not appropriate for production logging as it lacks log levels, structured output, and proper log management.
console.log('Running tests...');Replace console.log with a structured logging library (e.g., winston, pino) that supports log levels and proper log management.
Backslash-based directory traversal patterns targeting Windows file systems.
process.stdout.write('\n🚀 Starting Playwright MCP Server (HTTP Mode)...\n');Normalize path separators and apply traversal checks for both forward and backslashes.
Requests targeting 127.0.0.1, localhost, or [::1] may access internal services not intended to be exposed.
sse: `http://localhost:${port}/sse`,Block requests to localhost and loopback addresses. Implement URL validation that rejects 127.x.x.x and ::1.
HTTP endpoints defined without authentication middleware may be accessible to unauthorized users.
app.get('/sse', (req, res) => handleSseConnection('/sse', '/messages', req, res));Add authentication middleware to all routes that access or modify data.
An HTTP server is created without configuring Strict-Transport-Security (HSTS) headers. Without HSTS, browsers may allow downgrade attacks from HTTPS to HTTP.
const httpServer = app.listen(port, host, () => {Add Strict-Transport-Security headers to your server responses. Use a middleware such as helmet to set HSTS automatically.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
SCREENSHOT = 'screenshot',
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
HTML comments in tool descriptions may contain hidden instructions intended to influence LLM reasoning.
output = output.slice(0, maxLength) + '\n<!-- Output truncated due to size limits -->';
Remove HTML comments from description strings. Use source code comments instead.
Using GitHub Actions with branch references instead of SHA pins enables supply chain attacks.
uses: actions/upload-pages-artifact@v3
Pin GitHub Actions to full commit SHAs: uses: actions/checkout@abc123...
Using GitHub Actions with branch references instead of SHA pins enables supply chain attacks.
uses: actions/deploy-pages@v4
Pin GitHub Actions to full commit SHAs: uses: actions/checkout@abc123...
Using GitHub Actions with branch references instead of SHA pins enables supply chain attacks.
- uses: actions/checkout@v4
Pin GitHub Actions to full commit SHAs: uses: actions/checkout@abc123...
Using GitHub Actions with branch references instead of SHA pins enables supply chain attacks.
uses: actions/setup-node@v4
Pin GitHub Actions to full commit SHAs: uses: actions/checkout@abc123...
Using GitHub Actions with branch references instead of SHA pins enables supply chain attacks.
- uses: actions/checkout@v3
Pin GitHub Actions to full commit SHAs: uses: actions/checkout@abc123...
Using GitHub Actions with branch references instead of SHA pins enables supply chain attacks.
uses: actions/setup-node@v3
Pin GitHub Actions to full commit SHAs: uses: actions/checkout@abc123...
Using GitHub Actions with branch references instead of SHA pins enables supply chain attacks.
uses: actions/upload-artifact@v4
Pin GitHub Actions to full commit SHAs: uses: actions/checkout@abc123...
Direct usage of child_process module methods with variable arguments may allow command injection.
import { spawn } from 'child_process';Use execFile with explicit argument arrays instead of child_process with string commands.
Detected console.log() usage in non-test source code. Console.log is not appropriate for production logging as it lacks log levels, structured output, and proper log management.
console.log(output);
Replace console.log with a structured logging library (e.g., winston, pino) that supports log levels and proper log management.
Detected console.log() usage in non-test source code. Console.log is not appropriate for production logging as it lacks log levels, structured output, and proper log management.
console.log(error.stdout);
Replace console.log with a structured logging library (e.g., winston, pino) that supports log levels and proper log management.
Detected console.log() usage in non-test source code. Console.log is not appropriate for production logging as it lacks log levels, structured output, and proper log management.
console.log(`
Replace console.log with a structured logging library (e.g., winston, pino) that supports log levels and proper log management.
Detected console.log() usage in non-test source code. Console.log is not appropriate for production logging as it lacks log levels, structured output, and proper log management.
console.log(message);
Replace console.log with a structured logging library (e.g., winston, pino) that supports log levels and proper log management.
Detected console.log() usage in non-test source code. Console.log is not appropriate for production logging as it lacks log levels, structured output, and proper log management.
console.log(`Monitoring HTTP server listening on port ${this.actualPort}`);Replace console.log with a structured logging library (e.g., winston, pino) that supports log levels and proper log management.
Detected console.log() usage in non-test source code. Console.log is not appropriate for production logging as it lacks log levels, structured output, and proper log management.
console.log(`Health check: http://localhost:${this.actualPort}/health`);Replace console.log with a structured logging library (e.g., winston, pino) that supports log levels and proper log management.
Detected console.log() usage in non-test source code. Console.log is not appropriate for production logging as it lacks log levels, structured output, and proper log management.
console.log(`Metrics: http://localhost:${this.actualPort}/metrics`);Replace console.log with a structured logging library (e.g., winston, pino) that supports log levels and proper log management.
Detected console.log() usage in non-test source code. Console.log is not appropriate for production logging as it lacks log levels, structured output, and proper log management.
console.log('Monitoring HTTP server stopped');Replace console.log with a structured logging library (e.g., winston, pino) that supports log levels and proper log management.
Detected patterns that disable, silence, or suppress logging or audit trails. Disabling security logging can mask malicious activity and hinder incident investigation.
description: "Whether to clear logs after retrieval (default: false)"
Ensure security-related logging is always enabled in production. Never suppress audit trails or security event logs.
Detected console logging statements that reference sensitive fields such as password, secret, token, or API keys. Logging sensitive data can expose credentials in log files, monitoring systems, and log aggregation services.
console.warn('Both token and Authorization header provided. Custom Authorization header will override token.');Remove sensitive data from log statements. If you must reference sensitive fields, redact or mask them before logging.
Detected console.log() usage in non-test source code. Console.log is not appropriate for production logging as it lacks log levels, structured output, and proper log management.
console.log('Imports successful!');Replace console.log with a structured logging library (e.g., winston, pino) that supports log levels and proper log management.
Detected console.log() usage in non-test source code. Console.log is not appropriate for production logging as it lacks log levels, structured output, and proper log management.
console.log('setupRequestHandlers:', typeof setupRequestHandlers);Replace console.log with a structured logging library (e.g., winston, pino) that supports log levels and proper log management.
Detected console.log() usage in non-test source code. Console.log is not appropriate for production logging as it lacks log levels, structured output, and proper log management.
console.log('handleToolCall:', typeof handleToolCall);Replace console.log with a structured logging library (e.g., winston, pino) that supports log levels and proper log management.
Backslash-based directory traversal patterns targeting Windows file systems.
process.stdout.write(`\n⏳ Initializing Playwright MCP Server on port ${options.port}...\n`);Normalize path separators and apply traversal checks for both forward and backslashes.
File system operations using variables without prior path validation or sanitization may allow traversal attacks.
fs.mkdirSync(logDir, { recursive: true });Add path sanitization before all fs operations. Validate paths against an allowlist of permitted directories.
File system operations using variables without prior path validation or sanitization may allow traversal attacks.
fs.unlinkSync(oldFile); // Delete oldest file
Add path sanitization before all fs operations. Validate paths against an allowlist of permitted directories.
Using path.join or path.resolve with variables from user input without validation can lead to directory traversal.
path: path.resolve(args.outputPath || '.', filename),
Sanitize user input before passing to path.join/resolve. Use path.normalize() and check for '..' sequences.
File system operations using variables without prior path validation or sanitization may allow traversal attacks.
fs.mkdirSync(downloadsDir, { recursive: true });Add path sanitization before all fs operations. Validate paths against an allowlist of permitted directories.
Requests targeting 127.0.0.1, localhost, or [::1] may access internal services not intended to be exposed.
messages: `http://localhost:${port}/messages`,Block requests to localhost and loopback addresses. Implement URL validation that rejects 127.x.x.x and ::1.
Requests targeting 127.0.0.1, localhost, or [::1] may access internal services not intended to be exposed.
mcp: `http://localhost:${port}/mcp`,Block requests to localhost and loopback addresses. Implement URL validation that rejects 127.x.x.x and ::1.
Requests targeting 127.0.0.1, localhost, or [::1] may access internal services not intended to be exposed.
health: `http://localhost:${port}/health`,Block requests to localhost and loopback addresses. Implement URL validation that rejects 127.x.x.x and ::1.
Requests targeting 127.0.0.1, localhost, or [::1] may access internal services not intended to be exposed.
"url": "http://localhost:${port}/mcp",Block requests to localhost and loopback addresses. Implement URL validation that rejects 127.x.x.x and ::1.
Requests targeting 127.0.0.1, localhost, or [::1] may access internal services not intended to be exposed.
"url": "http://localhost:8931/mcp",
Block requests to localhost and loopback addresses. Implement URL validation that rejects 127.x.x.x and ::1.
HTTP endpoints defined without authentication middleware may be accessible to unauthorized users.
app.post('/messages', (req, res) => handlePostMessage('/messages', req, res));Add authentication middleware to all routes that access or modify data.
HTTP endpoints defined without authentication middleware may be accessible to unauthorized users.
app.get('/mcp', (req, res) => handleSseConnection('/mcp', '/mcp', req, res));Add authentication middleware to all routes that access or modify data.
HTTP endpoints defined without authentication middleware may be accessible to unauthorized users.
app.post('/mcp', (req, res) => handlePostMessage('/mcp', req, res));Add authentication middleware to all routes that access or modify data.
HTTP endpoints defined without authentication middleware may be accessible to unauthorized users.
app.get('/health', (req, res) => {Add authentication middleware to all routes that access or modify data.
API endpoints without rate limiting are vulnerable to brute force and denial of service.
app.get('/sse', (req, res) => handleSseConnection('/sse', '/messages', req, res));Add rate limiting middleware to all public API endpoints.
API endpoints without rate limiting are vulnerable to brute force and denial of service.
app.post('/messages', (req, res) => handlePostMessage('/messages', req, res));Add rate limiting middleware to all public API endpoints.
API endpoints without rate limiting are vulnerable to brute force and denial of service.
app.get('/mcp', (req, res) => handleSseConnection('/mcp', '/mcp', req, res));Add rate limiting middleware to all public API endpoints.
API endpoints without rate limiting are vulnerable to brute force and denial of service.
app.post('/mcp', (req, res) => handlePostMessage('/mcp', req, res));Add rate limiting middleware to all public API endpoints.
API endpoints without rate limiting are vulnerable to brute force and denial of service.
app.get('/health', (req, res) => {Add rate limiting middleware to all public API endpoints.
POST/PUT/DELETE endpoints without CSRF tokens are vulnerable to cross-site request forgery.
app.post('/messages', (req, res) => handlePostMessage('/messages', req, res));Implement CSRF protection using tokens or SameSite cookies.
POST/PUT/DELETE endpoints without CSRF tokens are vulnerable to cross-site request forgery.
app.post('/mcp', (req, res) => handlePostMessage('/mcp', req, res));Implement CSRF protection using tokens or SameSite cookies.
HTTP endpoints defined without authentication middleware may be accessible to unauthorized users.
this.app.get('/health', (req: Request, res: Response) => {Add authentication middleware to all routes that access or modify data.
HTTP endpoints defined without authentication middleware may be accessible to unauthorized users.
this.app.get('/metrics', (req: Request, res: Response) => {Add authentication middleware to all routes that access or modify data.
HTTP endpoints defined without authentication middleware may be accessible to unauthorized users.
this.app.get('/ready', (req: Request, res: Response) => {Add authentication middleware to all routes that access or modify data.
OAuth-protected endpoints that don't validate scopes may allow unauthorized actions.
token: { type: "string", description: "Bearer token for authorization" },Validate OAuth scopes on every endpoint. Check that the token has required permissions.
OAuth-protected endpoints that don't validate scopes may allow unauthorized actions.
token: { type: "string", description: "Bearer token for authorization" },Validate OAuth scopes on every endpoint. Check that the token has required permissions.
OAuth-protected endpoints that don't validate scopes may allow unauthorized actions.
token: { type: "string", description: "Bearer token for authorization" },Validate OAuth scopes on every endpoint. Check that the token has required permissions.
OAuth-protected endpoints that don't validate scopes may allow unauthorized actions.
token: { type: "string", description: "Bearer token for authorization" },Validate OAuth scopes on every endpoint. Check that the token has required permissions.
OAuth-protected endpoints that don't validate scopes may allow unauthorized actions.
token: { type: "string", description: "Bearer token for authorization" },Validate OAuth scopes on every endpoint. Check that the token has required permissions.
OAuth-protected endpoints that don't validate scopes may allow unauthorized actions.
* @param token Optional Bearer token for authorization
Validate OAuth scopes on every endpoint. Check that the token has required permissions.
OAuth-protected endpoints that don't validate scopes may allow unauthorized actions.
headers['Authorization'] = `Bearer ${token}`;Validate OAuth scopes on every endpoint. Check that the token has required permissions.
An HTTP server is created without configuring Strict-Transport-Security (HSTS) headers. Without HSTS, browsers may allow downgrade attacks from HTTPS to HTTP.
this.httpServer = this.app!.listen(port, () => {Add Strict-Transport-Security headers to your server responses. Use a middleware such as helmet to set HSTS automatically.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
uri: `screenshot://${name}`,Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
if (uri.startsWith("screenshot://")) {Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
const screenshot = getScreenshots().get(name);
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
if (screenshot) {Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
blob: screenshot,
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
let screenshotTool: ScreenshotTool;
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
if (!screenshotTool) screenshotTool = new ScreenshotTool(server);
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
if (!screenshotTool) screenshotTool = new ScreenshotTool(server);
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
case "playwright_screenshot":
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
return await screenshotTool.execute(args, context);
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
* Get screenshots
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
return screenshotTool?.getScreenshots() ?? new Map();
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
name: "playwright_screenshot",
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
description: "Take a screenshot of the current page or a specific element",
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
name: { type: "string", description: "Name for the screenshot" },Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
selector: { type: "string", description: "CSS selector for element to screenshot" },Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
storeBase64: { type: "boolean", description: "Store screenshot in base64 format (default: true)" },Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
fullPage: { type: "boolean", description: "Store screenshot of the entire page (default: false)" },Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
savePng: { type: "boolean", description: "Save screenshot as PNG file (default: false)" },Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
"playwright_screenshot",
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
export * from './screenshot.js';
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
* Tool for taking screenshots of pages or elements
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
private screenshots = new Map<string, string>();
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
* Execute the screenshot tool
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
const screenshotOptions: any = {Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
screenshotOptions.element = element;
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
const filename = `${args.name || 'screenshot'}-${timestamp}.png`;Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
screenshotOptions.path = outputPath;
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
const screenshot = await page.screenshot(screenshotOptions);
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
const screenshot = await page.screenshot(screenshotOptions);
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
const screenshot = await page.screenshot(screenshotOptions);
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
const base64Screenshot = screenshot.toString('base64');Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
this.screenshots.set(args.name || 'screenshot', base64Screenshot);
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
this.screenshots.set(args.name || 'screenshot', base64Screenshot);
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
messages.push(`Screenshot also stored in memory with name: '${args.name || 'screenshot'}'`);Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
* Get all stored screenshots
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
return this.screenshots;
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
case 'playwright_screenshot':
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
// Take screenshot
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
await page.screenshot({ path: '${name}.png'${optionsStr} });`;Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.
Accessing clipboard contents or taking screenshots may be used to capture and exfiltrate sensitive data.
"playwright_screenshot",
Remove clipboard/screenshot access unless explicitly required by the tool's stated purpose.