Skip to main content
Glama

security_headers_check

Test API endpoints for missing or misconfigured security headers using specified HTTP methods to ensure compliance and prevent vulnerabilities.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
endpointYesAPI endpoint to test
http_methodNoHTTP method to useGET
use_authNoWhether to use current authentication if available

Implementation Reference

  • The handler function for the security_headers_check tool. Makes an HTTP request to the endpoint, extracts response headers, analyzes them using helper functions, generates a formatted report, and handles authentication.
    async ({ endpoint, http_method, use_auth }) => {
      try {
        // Get auth headers if available and requested
        let headers = {};
        if (use_auth) {
          const authManager = AuthManager.getInstance();
          const authState = authManager.getAuthState();
          
          if (authState.type !== 'none' && authState.headers) {
            headers = { ...headers, ...authState.headers };
          }
        }
        
        // Make the request
        const response = await axios({
          method: http_method.toLowerCase(),
          url: endpoint,
          headers,
          validateStatus: () => true, // Accept any status code
        });
        
        // Get headers (case insensitive)
        const responseHeaders = response.headers;
        const headerMap = new Map<string, string>();
        
        for (const key in responseHeaders) {
          headerMap.set(key.toLowerCase(), responseHeaders[key]);
        }
        
        // Check for security headers
        const securityHeaders = checkSecurityHeaders(headerMap);
        
        // Generate recommendations
        const recommendations = generateRecommendations(securityHeaders);
        
        // Add authentication info to the report
        const authManager = AuthManager.getInstance();
        const authState = authManager.getAuthState();
        const authInfo = use_auth && authState.type !== 'none'
          ? `\nTest performed with authentication: ${authState.type}`
          : '\nTest performed without authentication';
        
        return {
          content: [
            {
              type: "text",
              text: formatSecurityHeadersReport(securityHeaders, recommendations, endpoint, authInfo),
            },
          ],
        };
      } catch (error) {
        return {
          content: [
            {
              type: "text",
              text: `Error checking security headers: ${(error as Error).message}`,
            },
          ],
        };
      }
  • Input schema for the tool using Zod: endpoint (URL), http_method (GET/HEAD/OPTIONS), use_auth (boolean).
    {
      endpoint: z.string().url().describe("API endpoint to test"),
      http_method: z.enum(["GET", "HEAD", "OPTIONS"]).default("GET").describe("HTTP method to use"),
      use_auth: z.boolean().default(true).describe("Whether to use current authentication if available"),
    },
  • Registers the security_headers_check tool with the MCP server, including schema and handler.
    export function registerSecurityHeadersTools(server: McpServer) {
      // Security headers check
      server.tool(
        "security_headers_check",
        {
          endpoint: z.string().url().describe("API endpoint to test"),
          http_method: z.enum(["GET", "HEAD", "OPTIONS"]).default("GET").describe("HTTP method to use"),
          use_auth: z.boolean().default(true).describe("Whether to use current authentication if available"),
        },
        async ({ endpoint, http_method, use_auth }) => {
          try {
            // Get auth headers if available and requested
            let headers = {};
            if (use_auth) {
              const authManager = AuthManager.getInstance();
              const authState = authManager.getAuthState();
              
              if (authState.type !== 'none' && authState.headers) {
                headers = { ...headers, ...authState.headers };
              }
            }
            
            // Make the request
            const response = await axios({
              method: http_method.toLowerCase(),
              url: endpoint,
              headers,
              validateStatus: () => true, // Accept any status code
            });
            
            // Get headers (case insensitive)
            const responseHeaders = response.headers;
            const headerMap = new Map<string, string>();
            
            for (const key in responseHeaders) {
              headerMap.set(key.toLowerCase(), responseHeaders[key]);
            }
            
            // Check for security headers
            const securityHeaders = checkSecurityHeaders(headerMap);
            
            // Generate recommendations
            const recommendations = generateRecommendations(securityHeaders);
            
            // Add authentication info to the report
            const authManager = AuthManager.getInstance();
            const authState = authManager.getAuthState();
            const authInfo = use_auth && authState.type !== 'none'
              ? `\nTest performed with authentication: ${authState.type}`
              : '\nTest performed without authentication';
            
            return {
              content: [
                {
                  type: "text",
                  text: formatSecurityHeadersReport(securityHeaders, recommendations, endpoint, authInfo),
                },
              ],
            };
          } catch (error) {
            return {
              content: [
                {
                  type: "text",
                  text: `Error checking security headers: ${(error as Error).message}`,
                },
              ],
            };
          }
        }
      );
    }
  • Helper function that checks the response headers Map for presence and configuration of key security headers like HSTS, CSP, X-Frame-Options, etc., returning an array with analysis.
    function checkSecurityHeaders(headers: Map<string, string>): Array<{
      name: string;
      present: boolean;
      value: string;
      description: string;
      severity: "High" | "Medium" | "Low";
      recommendation: string;
    }> {
      return [
        {
          name: "Strict-Transport-Security",
          present: headers.has("strict-transport-security"),
          value: headers.get("strict-transport-security") || "",
          description: "Ensures the browser only uses HTTPS for the domain",
          severity: "High",
          recommendation: headers.has("strict-transport-security") 
            ? (headers.get("strict-transport-security")?.includes("max-age=31536000") 
                ? "Good: HSTS is properly configured"
                : "Improve: Set max-age to at least one year (31536000)")
            : "Add: Strict-Transport-Security: max-age=31536000; includeSubDomains",
        },
        {
          name: "Content-Security-Policy",
          present: headers.has("content-security-policy"),
          value: headers.get("content-security-policy") || "",
          description: "Controls which resources the browser is allowed to load",
          severity: "High",
          recommendation: headers.has("content-security-policy")
            ? "Verify that the CSP policy is restrictive enough for your application"
            : "Add a Content-Security-Policy header appropriate for your application",
        },
        {
          name: "X-Content-Type-Options",
          present: headers.has("x-content-type-options"),
          value: headers.get("x-content-type-options") || "",
          description: "Prevents the browser from MIME-sniffing content types",
          severity: "Medium",
          recommendation: headers.has("x-content-type-options") 
            ? (headers.get("x-content-type-options") === "nosniff" 
                ? "Good: X-Content-Type-Options is properly configured" 
                : "Fix: Set X-Content-Type-Options to 'nosniff'")
            : "Add: X-Content-Type-Options: nosniff",
        },
        {
          name: "X-Frame-Options",
          present: headers.has("x-frame-options"),
          value: headers.get("x-frame-options") || "",
          description: "Prevents your site from being embedded in iframes on other sites",
          severity: "Medium",
          recommendation: headers.has("x-frame-options")
            ? (["DENY", "SAMEORIGIN"].includes(headers.get("x-frame-options")?.toUpperCase() || "") 
                ? "Good: X-Frame-Options is properly configured" 
                : "Fix: Set X-Frame-Options to 'DENY' or 'SAMEORIGIN'")
            : "Add: X-Frame-Options: DENY",
        },
        {
          name: "X-XSS-Protection",
          present: headers.has("x-xss-protection"),
          value: headers.get("x-xss-protection") || "",
          description: "Enables browser's built-in XSS filtering",
          severity: "Low",
          recommendation: headers.has("x-xss-protection")
            ? (headers.get("x-xss-protection") === "1; mode=block" 
                ? "Good: X-XSS-Protection is properly configured" 
                : "Improve: Set X-XSS-Protection to '1; mode=block'")
            : "Add: X-XSS-Protection: 1; mode=block",
        },
        {
          name: "Referrer-Policy",
          present: headers.has("referrer-policy"),
          value: headers.get("referrer-policy") || "",
          description: "Controls how much referrer information is included with requests",
          severity: "Medium",
          recommendation: headers.has("referrer-policy")
            ? "Verify that the referrer policy is appropriate for your application"
            : "Add a Referrer-Policy header (e.g., 'strict-origin-when-cross-origin')",
        },
        {
          name: "Permissions-Policy",
          present: headers.has("permissions-policy") || headers.has("feature-policy"),
          value: headers.get("permissions-policy") || headers.get("feature-policy") || "",
          description: "Controls which browser features can be used by the page",
          severity: "Medium",
          recommendation: headers.has("permissions-policy") || headers.has("feature-policy")
            ? "Verify that the permissions policy is appropriate for your application"
            : "Add a Permissions-Policy header to restrict access to browser features",
        },
        {
          name: "Cache-Control",
          present: headers.has("cache-control"),
          value: headers.get("cache-control") || "",
          description: "Controls how responses are cached",
          severity: "Medium",
          recommendation: headers.has("cache-control")
            ? (headers.get("cache-control")?.includes("no-store") 
                ? "Good: Cache-Control prevents storage of sensitive data" 
                : "Consider: For sensitive data, use 'Cache-Control: no-store'")
            : "Add appropriate Cache-Control header based on content sensitivity",
        },
        {
          name: "X-Permitted-Cross-Domain-Policies",
          present: headers.has("x-permitted-cross-domain-policies"),
          value: headers.get("x-permitted-cross-domain-policies") || "",
          description: "Controls Adobe Flash and PDF client resource sharing",
          severity: "Low",
          recommendation: headers.has("x-permitted-cross-domain-policies")
            ? "Verify that the policy is appropriate for your application"
            : "Consider adding: X-Permitted-Cross-Domain-Policies: none",
        },
        {
          name: "Access-Control-Allow-Origin",
          present: headers.has("access-control-allow-origin"),
          value: headers.get("access-control-allow-origin") || "",
          description: "Controls which domains can access the API via CORS",
          severity: "High",
          recommendation: headers.has("access-control-allow-origin")
            ? (headers.get("access-control-allow-origin") === "*" 
                ? "Warning: CORS is enabled for all origins" 
                : "Verify that CORS is correctly configured for your use case")
            : "CORS not enabled - appropriate if this API should not be accessed cross-origin",
        },
      ];
    }
  • src/index.ts:20-20 (registration)
    Top-level registration call in the main server setup that triggers registration of all tools, including security_headers_check via the tools chain.
    registerSecurityTools(server);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ricauts/CyberMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server