changemaker.lite/api/dist/utils/promql-validator.js

66 lines
2.5 KiB
JavaScript

"use strict";
/**
* PromQL query validation utilities
* Prevents injection vulnerabilities in Prometheus queries
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.validatePromQLQuery = validatePromQLQuery;
exports.validatePromQLQueries = validatePromQLQueries;
/**
* Validates PromQL query string to prevent injection attacks
* Allows only safe metric names, labels, operators, and functions
*
* @param query - The PromQL query to validate
* @throws Error if query contains unsafe characters or functions
*/
function validatePromQLQuery(query) {
if (!query || typeof query !== 'string') {
throw new Error('Invalid PromQL query: query must be a non-empty string');
}
// Block dangerous characters that could enable injection
const dangerousChars = [';', '&', '|', '`', '$', '\\'];
for (const char of dangerousChars) {
if (query.includes(char)) {
throw new Error(`Invalid PromQL query: unsafe character '${char}' detected`);
}
}
// Block dangerous PromQL functions that could enable resource exhaustion
const dangerousFunctions = [
'absent_over_time', // Can cause expensive queries
'predict_linear', // Computationally expensive
'deriv', // Can be expensive on large datasets
'holt_winters', // Computationally expensive
];
const lowerQuery = query.toLowerCase();
for (const fn of dangerousFunctions) {
if (lowerQuery.includes(fn)) {
throw new Error(`Invalid PromQL query: dangerous function '${fn}' detected`);
}
}
// Basic structure validation: queries should contain alphanumeric, underscores, colons, and safe operators
// This is a permissive check to catch obvious malicious input
const safePattern = /^[a-zA-Z0-9_:(){}\[\],.+\-*/<>=!~\s"'%]+$/;
if (!safePattern.test(query)) {
throw new Error('Invalid PromQL query: contains unsafe characters');
}
}
/**
* Validates an array of PromQL queries
*
* @param queries - Array of PromQL queries to validate
* @throws Error if any query is invalid
*/
function validatePromQLQueries(queries) {
if (!Array.isArray(queries)) {
throw new Error('Invalid input: queries must be an array');
}
for (let i = 0; i < queries.length; i++) {
try {
validatePromQLQuery(queries[i]);
}
catch (error) {
throw new Error(`Query #${i + 1} validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
}
//# sourceMappingURL=promql-validator.js.map