Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@
res.sendFile(logoPath);
});

app.get("/styles.css", (req, res) => {
const cssPath = path.join(__dirname, "static", "styles.css");
res.setHeader('Content-Type', 'text/css');
res.sendFile(cssPath);
});
Comment on lines +170 to +174

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
a file system access
, but is not rate-limited.

Copilot Autofix

AI about 1 month ago

To address the missing rate limiting in the /styles.css route handler at line 170, we should apply a rate-limiting middleware to restrict how frequently a client can request this resource. The simplest way is to use the popular express-rate-limit package, which is well maintained and purpose-built for this scenario. We'll need to:

  • Import express-rate-limit
  • Create a rate limiter instance, e.g., 100 requests per 15 minutes per IP (similar to the background example).
  • Apply the rate limiter as middleware for the /styles.css route (at line 170) before the handler.

Changes to make:

  • Add a new import for express-rate-limit at the top.
  • Define a rate limiting middleware before route handlers.
  • Apply it directly to the /styles.css route.
    No other changes are needed, and we should not interfere with any existing functionality for other routes.
Suggested changeset 2
src/index.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/index.ts b/src/index.ts
--- a/src/index.ts
+++ b/src/index.ts
@@ -3,6 +3,7 @@
 import cors from "cors";
 import express from "express";
 import path from "path";
+import rateLimit from "express-rate-limit";
 import { fileURLToPath } from "url";
 import { EverythingAuthProvider } from "./auth/provider.js";
 import { BASE_URI, PORT } from "./config.js";
@@ -15,6 +16,11 @@
 
 const app = express();
 
+// Set up rate limiter for static assets: max 100 requests per 15 minutes per IP
+const staticAssetLimiter = rateLimit({
+  windowMs: 15 * 60 * 1000, // 15 minutes
+  max: 100, // limit each IP to 100 requests per windowMs
+});
 // Get the directory of the current module
 const __filename = fileURLToPath(import.meta.url);
 const __dirname = path.dirname(__filename);
@@ -167,7 +173,7 @@
   res.sendFile(logoPath);
 });
 
-app.get("/styles.css", (req, res) => {
+app.get("/styles.css", staticAssetLimiter, (req, res) => {
   const cssPath = path.join(__dirname, "static", "styles.css");
   res.setHeader('Content-Type', 'text/css');
   res.sendFile(cssPath);
EOF
@@ -3,6 +3,7 @@
import cors from "cors";
import express from "express";
import path from "path";
import rateLimit from "express-rate-limit";
import { fileURLToPath } from "url";
import { EverythingAuthProvider } from "./auth/provider.js";
import { BASE_URI, PORT } from "./config.js";
@@ -15,6 +16,11 @@

const app = express();

// Set up rate limiter for static assets: max 100 requests per 15 minutes per IP
const staticAssetLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
});
// Get the directory of the current module
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@@ -167,7 +173,7 @@
res.sendFile(logoPath);
});

app.get("/styles.css", (req, res) => {
app.get("/styles.css", staticAssetLimiter, (req, res) => {
const cssPath = path.join(__dirname, "static", "styles.css");
res.setHeader('Content-Type', 'text/css');
res.sendFile(cssPath);
package.json
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -32,7 +32,8 @@
     "cors": "^2.8.5",
     "dotenv": "^16.4.7",
     "express": "^4.21.2",
-    "raw-body": "^3.0.0"
+    "raw-body": "^3.0.0",
+    "express-rate-limit": "^8.0.1"
   },
   "overrides": {
     "@types/express": "^5.0.0",
EOF
@@ -32,7 +32,8 @@
"cors": "^2.8.5",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"raw-body": "^3.0.0"
"raw-body": "^3.0.0",
"express-rate-limit": "^8.0.1"
},
"overrides": {
"@types/express": "^5.0.0",
This fix introduces these dependencies
Package Version Security advisories
express-rate-limit (npm) 8.0.1 None
Copilot is powered by AI and may make mistakes. Always verify output.

// Splash page
app.get("/", (req, res) => {
const splashPath = path.join(__dirname, "static", "index.html");
Expand Down
191 changes: 4 additions & 187 deletions src/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,197 +3,14 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MCP Everything Server</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: #ffffff;
color: #000000;
min-height: 100vh;
display: flex;
flex-direction: column;
}

.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
flex: 1;
}

header {
display: flex;
align-items: center;
gap: 2rem;
margin-bottom: 3rem;
padding-bottom: 2rem;
border-bottom: 2px solid #000000;
}

.logo {
width: 80px;
height: 80px;
}

h1 {
font-size: 2.5rem;
font-weight: 700;
letter-spacing: -0.02em;
}

.tagline {
font-size: 1.25rem;
color: #666666;
margin-bottom: 3rem;
line-height: 1.6;
}

.features {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-bottom: 3rem;
}

.feature-card {
border: 2px solid #000000;
padding: 1.5rem;
background: #ffffff;
transition: all 0.2s ease;
}

.feature-card:hover {
background: #000000;
color: #ffffff;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.feature-card h3 {
font-size: 1.25rem;
margin-bottom: 0.75rem;
font-weight: 600;
}

.feature-card p {
line-height: 1.6;
opacity: 0.9;
}

.endpoints {
background: #f5f5f5;
border: 2px solid #000000;
padding: 2rem;
margin-bottom: 3rem;
}

.endpoints h2 {
font-size: 1.75rem;
margin-bottom: 1.5rem;
font-weight: 600;
}

.endpoint-list {
display: flex;
flex-direction: column;
gap: 1rem;
}

.endpoint {
font-family: 'Courier New', monospace;
background: #ffffff;
padding: 0.75rem 1rem;
border: 1px solid #000000;
display: flex;
align-items: center;
gap: 1rem;
}

.method {
font-weight: bold;
min-width: 80px;
}

.method.get { color: #0066cc; }
.method.post { color: #009900; }
.method.delete { color: #cc0000; }

.links {
display: flex;
gap: 2rem;
flex-wrap: wrap;
margin-bottom: 3rem;
}

.link-button {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 1rem 2rem;
background: #000000;
color: #ffffff;
text-decoration: none;
font-weight: 600;
transition: all 0.2s ease;
border: 2px solid #000000;
}

.link-button:hover {
background: #ffffff;
color: #000000;
}

.link-button.secondary {
background: #ffffff;
color: #000000;
}

.link-button.secondary:hover {
background: #000000;
color: #ffffff;
}

footer {
background: #000000;
color: #ffffff;
padding: 2rem;
text-align: center;
}

footer a {
color: #ffffff;
text-decoration: underline;
}

@media (max-width: 768px) {
h1 {
font-size: 2rem;
}

header {
flex-direction: column;
align-items: flex-start;
gap: 1rem;
}

.logo {
width: 60px;
height: 60px;
}
}
</style>
<title>MCP Example Server</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<div class="container">
<header>
<img src="/mcp-logo.png" alt="MCP Logo" class="logo">
<h1>MCP Everything Server</h1>
<h1>MCP Example Server</h1>
</header>

<p class="tagline">
Expand Down Expand Up @@ -264,7 +81,7 @@ <h2>API Endpoints</h2>
<a href="https://modelcontextprotocol.io" class="link-button secondary">
MCP Documentation
</a>
<a href="https://modelcontextprotocol.io/specification" class="link-button secondary">
<a href="https://modelcontextprotocol.io/specification/2025-06-18" class="link-button secondary">
Protocol Specification
</a>
</div>
Expand Down
Loading