add os and category labels to details and conversion slack blocks

This commit is contained in:
Charlotte Croce 2025-04-19 14:02:30 -04:00
parent b329988c38
commit ad6b108d3f
5 changed files with 84 additions and 27 deletions

View file

@ -40,6 +40,13 @@ function getConversionResultBlocks(conversionResult) {
format: 'siem_rule_ndjson'
};
// Extract logsource information or use defaults
const logsource = rule.logsource || {};
const product = logsource.product || 'N/A';
const category = logsource.category || 'N/A';
logger.debug(`${FILE_NAME}: Logsource info - Product: ${product}, Category: ${category}`);
// Truncate output if it's too long for Slack
let output = conversionResult.output || '';
const maxOutputLength = 2900; // Slack has a limit of ~3000 chars in a code block
@ -66,6 +73,19 @@ function getConversionResultBlocks(conversionResult) {
text: `*Rule ID:* ${rule.id}\n*Description:* ${rule.description}`
}
},
{
type: 'section',
fields: [
{
type: 'mrkdwn',
text: `*OS/Product:* ${product}`
},
{
type: 'mrkdwn',
text: `*Category:* ${category}`
}
]
},
{
type: 'section',
text: {

View file

@ -193,6 +193,28 @@ function getSigmaRuleDetailsBlocks(details) {
}
];
// Get logsource information from the details
const logsource = details.logsource || {};
const product = logsource.product || 'N/A';
const category = logsource.category || 'N/A';
logger.debug(`${FILE_NAME}: Logsource info - Product: ${product}, Category: ${category}`);
// Add logsource information section after severity/author
blocks.push({
type: 'section',
fields: [
{
type: 'mrkdwn',
text: `*OS/Product:* ${product}`
},
{
type: 'mrkdwn',
text: `*Category:* ${category}`
}
]
});
// Add divider for visual separation
blocks.push({ type: 'divider' });

View file

@ -78,12 +78,25 @@ const getSearchResultBlocks = (keyword, results, pagination = {}) => {
const ruleId = safeRule.id || 'unknown';
logger.debug(`${FILE_NAME}: Adding result #${index + 1}: ${ruleId} - ${safeRule.title || 'Untitled'}`);
// Combine rule information and action button into a single line
// Get OS emoji based on product
const getOsEmoji = (product) => {
if (!product) return '';
const productLower = product.toLowerCase();
if (productLower.includes('windows')) return ':window: ';
if (productLower.includes('mac') || productLower.includes('apple')) return ':apple: ';
if (productLower.includes('linux')) return ':penguin: ';
return '';
};
const osEmoji = getOsEmoji(safeRule.logsource && safeRule.logsource.product);
// Rule information and action button - with OS emoji before title and no ID field
blocks.push({
"type": "section",
"text": {
"type": "mrkdwn",
"text": `*${safeRule.title || 'Untitled Rule'}*\nID: \`${ruleId}\``
"text": `*${osEmoji}${safeRule.title || 'Untitled Rule'}*`
},
"accessory": {
"type": "button",

View file

@ -4,7 +4,7 @@
* Handles Sigma rule search requests from Slack commands
*/
const { searchSigmaRules, searchSigmaRulesComplex } = require('../../services/sigma/sigma_search_service');
const { searchSigmaRules, searchSigmaRulesComplex, searchAndConvertRules } = require('../../services/sigma/sigma_search_service');
const logger = require('../../utils/logger');
const { handleError } = require('../../utils/error_handler');
const { getSearchResultBlocks } = require('../../blocks/sigma/sigma_search_results_block');
@ -69,7 +69,7 @@ const handleCommand = async (command, respond) => {
});
// Search for rules using the service function with pagination
const searchResult = await searchSigmaRules(keyword, page, pageSize);
const searchResult = await searchAndConvertRules(keyword, page, pageSize);
logger.debug(`${FILE_NAME}: Search result status: ${searchResult.success}`);
logger.debug(`${FILE_NAME}: Found ${searchResult.results?.length || 0} results out of ${searchResult.pagination?.totalResults || 0} total matches`);
logger.debug(`${FILE_NAME}: About to generate blocks for search results`);
@ -240,6 +240,7 @@ const handleComplexSearch = async (command, respond) => {
);
// Replace the header to indicate it's a complex search
// TODO: should be moved to dedicated block file
if (blocks && blocks.length > 0) {
blocks[0] = {
type: "header",

View file

@ -62,6 +62,7 @@ async function getSigmaRuleDetails(ruleId) {
description: rule.description || 'No description provided',
author: rule.author || 'Unknown author',
severity: rule.level || 'Unknown',
logsource: rule.logsource || {}, // Add this line to include logsource info
detectionExplanation: extractDetectionCondition(rule),
falsePositives: Array.isArray(rule.falsepositives) ? rule.falsepositives :
typeof rule.falsepositives === 'string' ? [rule.falsepositives] :