dnssweeper-cli
Version:
CLI tool for detecting and analyzing unused DNS records
153 lines • 5.84 kB
JavaScript
;
/**
* パターンマッチング機能
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.analyzeRecord = analyzeRecord;
exports.analyzeRecords = analyzeRecords;
exports.filterByRiskLevel = filterByRiskLevel;
exports.sortByRiskScore = sortByRiskScore;
const messages_1 = require("../utils/messages");
/**
* DNSレコードをパターンマッチングして分析する
* @param record - 分析対象のDNSレコード
* @param config - パターン設定
* @param language - 言語設定
* @returns 分析結果
*/
function analyzeRecord(record, config, language = 'ja') {
const matchedPatterns = [];
const reasons = [];
let riskScore = config.scoring.base;
const messages = (0, messages_1.getMessages)(language);
const recordName = record.name.toLowerCase();
// プレフィックスのチェック
for (const [riskLevel, patterns] of Object.entries(config.patterns.prefixes)) {
for (const pattern of patterns) {
if (recordName.startsWith(pattern)) {
matchedPatterns.push(`prefix:${pattern}`);
reasons.push((0, messages_1.formatMessage)(messages.reasons.dangerousPrefix, { pattern }));
riskScore += config.scoring[riskLevel];
break; // 同じリスクレベルでは1つのマッチで十分
}
}
}
// サフィックスのチェック(サブドメイン部分で判定)
const subdomain = recordName.split('.')[0];
for (const [riskLevel, patterns] of Object.entries(config.patterns.suffixes)) {
for (const pattern of patterns) {
// パターンが '-' で始まる場合は、サブドメインがそのサフィックスで終わるかチェック
const suffix = pattern.startsWith('-') ? pattern.substring(1) : pattern;
if (subdomain.endsWith(suffix)) {
matchedPatterns.push(`suffix:${pattern}`);
reasons.push((0, messages_1.formatMessage)(messages.reasons.dangerousSuffix, { pattern }));
riskScore += config.scoring[riskLevel];
break; // 同じリスクレベルでは1つのマッチで十分
}
}
}
// キーワードのチェック
for (const [riskLevel, patterns] of Object.entries(config.patterns.keywords)) {
for (const pattern of patterns) {
if (recordName.includes(pattern)) {
matchedPatterns.push(`keyword:${pattern}`);
reasons.push((0, messages_1.formatMessage)(messages.reasons.dangerousKeyword, { pattern }));
riskScore += config.scoring[riskLevel];
break; // 同じリスクレベルでは1つのマッチで十分
}
}
}
// 最終更新日時による追加スコア計算
const lastModified = new Date(record.modified);
const now = new Date();
const daysSinceModified = (now.getTime() - lastModified.getTime()) / (1000 * 60 * 60 * 24);
if (daysSinceModified > 365) {
riskScore += 20;
reasons.push((0, messages_1.formatMessage)(messages.reasons.lastModified, {
days: Math.floor(daysSinceModified),
}));
}
else if (daysSinceModified > 180) {
riskScore += 10;
reasons.push((0, messages_1.formatMessage)(messages.reasons.lastModified, {
days: Math.floor(daysSinceModified),
}));
}
// レコードタイプによる調整
if (record.type === 'CNAME') {
riskScore += 5;
reasons.push(messages.reasons.cnameWarning);
}
// リスクレベルの決定
const riskLevel = determineRiskLevel(riskScore, config.thresholds);
// 基本的な理由がない場合
if (reasons.length === 0) {
reasons.push(messages.reasons.noSpecialIssues);
}
return {
record,
riskScore,
riskLevel,
matchedPatterns,
reasons,
};
}
/**
* スコアからリスクレベルを決定
* @param score - リスクスコア
* @param thresholds - 閾値設定
* @returns リスクレベル
*/
function determineRiskLevel(score, thresholds) {
if (score >= thresholds.critical)
return 'critical';
if (score >= thresholds.high)
return 'high';
if (score >= thresholds.medium)
return 'medium';
if (score >= thresholds.low)
return 'low';
return 'safe';
}
/**
* 複数のDNSレコードをバッチ分析
* @param records - 分析対象のDNSレコード配列
* @param config - パターン設定
* @param language - 言語設定
* @returns 分析結果の配列
*/
function analyzeRecords(records, config, language = 'ja') {
return records.map(record => analyzeRecord(record, config, language));
}
/**
* 分析結果をリスクレベルでフィルタリング
* @param results - 分析結果の配列
* @param minRiskLevel - 最小リスクレベル
* @returns フィルタリングされた分析結果
*/
function filterByRiskLevel(results, minRiskLevel) {
const riskLevelOrder = [
'safe',
'low',
'medium',
'high',
'critical',
];
const minIndex = riskLevelOrder.indexOf(minRiskLevel);
return results.filter(result => {
const resultIndex = riskLevelOrder.indexOf(result.riskLevel);
return resultIndex >= minIndex;
});
}
/**
* 分析結果をリスクスコアでソート
* @param results - 分析結果の配列
* @param descending - 降順でソートするか(デフォルト: true)
* @returns ソートされた分析結果
*/
function sortByRiskScore(results, descending = true) {
return [...results].sort((a, b) => {
return descending ? b.riskScore - a.riskScore : a.riskScore - b.riskScore;
});
}
//# sourceMappingURL=patternMatcher.js.map