Skip to content

Commit

Permalink
Added support for safelisted heuristics signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
cccs-sgaron committed Aug 30, 2021
1 parent 03a5b68 commit e803f08
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 5 deletions.
23 changes: 22 additions & 1 deletion src/components/routes/manage/safelist_detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ export type Safelist = {
reason: string[];
type: string;
}[];
signature: {
name: string;
};
tag: {
type: string;
value: string;
Expand Down Expand Up @@ -90,6 +93,8 @@ const SafelistDetail = ({ safelist_id, close }: SafelistDetailProps) => {
query:
safelist.type === 'file'
? `result.sections.heuristic.signature.name:"SAFELIST_${safelist_id || id}"`
: safelist.type === 'signature'
? `result.sections.heuristic.signature.name:"${safelist.signature.name}"`
: `result.sections.safelisted_tags.${safelist.tag.type}:"${safelist.tag.value}"`,
mincount: 0,
start: 'now-30d/d',
Expand Down Expand Up @@ -214,6 +219,8 @@ const SafelistDetail = ({ safelist_id, close }: SafelistDetailProps) => {
? `/search/result/?query=result.sections.heuristic.signature.name:"SAFELIST_${
safelist_id || id
}"`
: safelist.type === 'signature'
? `/search/result/?query=result.sections.heuristic.signature.name:"${safelist.signature.name}"`
: `/search/result/?query=result.sections.safelisted_tags.${safelist.tag.type}:"${safelist.tag.value}"`
}
>
Expand Down Expand Up @@ -266,7 +273,7 @@ const SafelistDetail = ({ safelist_id, close }: SafelistDetailProps) => {
</Grid>
</div>
<Grid container spacing={3}>
<Grid item xs={12} style={{ display: safelist && safelist.type === 'tag' ? 'none' : 'initial' }}>
<Grid item xs={12} style={{ display: safelist && safelist.type === 'file' ? 'initial' : 'none' }}>
<Typography variant="h6">{t('hashes')}</Typography>
<Divider />
<Grid container>
Expand Down Expand Up @@ -354,6 +361,20 @@ const SafelistDetail = ({ safelist_id, close }: SafelistDetailProps) => {
</Grid>
</Grid>
)}
{safelist && safelist.signature && (
<Grid item xs={12}>
<Typography variant="h6">{t('signature.title')}</Typography>
<Divider />
<Grid container>
<Grid item xs={4} sm={3} lg={2}>
<span style={{ fontWeight: 500 }}>{t('signature.name')}</span>
</Grid>
<Grid item xs={8} sm={9} lg={10}>
{safelist.signature.name}
</Grid>
</Grid>
</Grid>
)}
{safelist && safelist.tag && (
<Grid item xs={12}>
<Typography variant="h6">{t('tag.title')}</Typography>
Expand Down
3 changes: 2 additions & 1 deletion src/components/visual/FileDetail/tags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ const WrappedTagSection: React.FC<TagSectionProps> = ({ signatures, tags }) => {
<span style={{ fontWeight: 500 }}>heuristic.signature</span>
</Grid>
<Grid item xs={12} sm={9} lg={10}>
{signatures.map(([value, lvl], idx) => (
{signatures.map(([value, lvl, safe], idx) => (
<Heuristic
key={idx}
signature
text={value}
lvl={lvl}
highlight_key={getKey('heuristic.signature', value)}
safe={safe}
/>
))}
</Grid>
Expand Down
74 changes: 72 additions & 2 deletions src/components/visual/Heuristic.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import { Menu, MenuItem } from '@material-ui/core';
import AssignmentOutlinedIcon from '@material-ui/icons/AssignmentOutlined';
import PlaylistAddCheckOutlinedIcon from '@material-ui/icons/PlaylistAddCheckOutlined';
import SearchOutlinedIcon from '@material-ui/icons/SearchOutlined';
import SelectAllOutlinedIcon from '@material-ui/icons/SelectAllOutlined';
import useClipboard from 'commons/components/hooks/useClipboard';
import useALContext from 'components/hooks/useALContext';
import useHighlighter from 'components/hooks/useHighlighter';
import useMyAPI from 'components/hooks/useMyAPI';
import useMySnackbar from 'components/hooks/useMySnackbar';
import CustomChip, { PossibleColors } from 'components/visual/CustomChip';
import { scoreToVerdict } from 'helpers/utils';
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useHistory } from 'react-router-dom';
import InputDialog from './InputDialog';

const STYLE = { height: 'auto', minHeight: '20px' };
const SEARCH_ICON = <SearchOutlinedIcon style={{ marginRight: '16px' }} />;
const CLIPBOARD_ICON = <AssignmentOutlinedIcon style={{ marginRight: '16px' }} />;
const SAFELIST_ICON = <PlaylistAddCheckOutlinedIcon style={{ marginRight: '16px' }} />;
const HIGHLIGHT_ICON = <SelectAllOutlinedIcon style={{ marginRight: '16px' }} />;
const initialMenuState = {
mouseX: null,
Expand All @@ -26,6 +33,7 @@ type HeuristicProps = {
show_type?: boolean;
highlight_key?: string;
fullWidth?: boolean;
safe?: boolean;
};

const Heuristic: React.FC<HeuristicProps> = ({
Expand All @@ -35,12 +43,19 @@ const Heuristic: React.FC<HeuristicProps> = ({
signature = false,
show_type = false,
highlight_key = null,
fullWidth = false
fullWidth = false,
safe = false
}) => {
const { t } = useTranslation();
const [state, setState] = React.useState(initialMenuState);
const [safelistDialog, setSafelistDialog] = React.useState(false);
const [safelistReason, setSafelistReason] = React.useState(null);
const history = useHistory();
const apiCall = useMyAPI();
const { showSuccessMessage } = useMySnackbar();
const { isHighlighted, triggerHighlight } = useHighlighter();
const { copy } = useClipboard();
const { user: currentUser } = useALContext();

const handleClick = useCallback(() => triggerHighlight(highlight_key), [triggerHighlight, highlight_key]);

Expand Down Expand Up @@ -77,8 +92,42 @@ const Heuristic: React.FC<HeuristicProps> = ({
handleClose();
}, [handleClick, handleClose]);

const handleMenuSafelist = useCallback(() => {
setSafelistDialog(true);
handleClose();
}, [setSafelistDialog, handleClose]);

const addToSafelist = useCallback(() => {
const data = {
signature: {
name: text
},
sources: [
{
name: currentUser.username,
reason: [safelistReason],
type: 'user'
}
],
type: 'signature'
};

apiCall({
url: `/api/v4/safelist/`,
method: 'PUT',
body: data,
onSuccess: _ => {
setSafelistDialog(false);
showSuccessMessage(t('safelist.success'));
}
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [safelistReason, t, text]);

let color: PossibleColors = 'default' as 'default';
if (lvl) {
if (safe) {
color = 'success' as 'success';
} else if (lvl) {
color = {
info: 'default' as 'default',
safe: 'success' as 'success',
Expand All @@ -97,6 +146,20 @@ const Heuristic: React.FC<HeuristicProps> = ({

return (
<>
{signature && (
<InputDialog
open={safelistDialog}
handleClose={() => setSafelistDialog(false)}
handleAccept={addToSafelist}
handleInputChange={event => setSafelistReason(event.target.value)}
inputValue={safelistReason}
title={t('safelist.title')}
cancelText={t('safelist.cancelText')}
acceptText={t('safelist.acceptText')}
inputLabel={t('safelist.input')}
text={t('safelist.text')}
/>
)}
<Menu
open={state.mouseY !== null}
onClose={handleClose}
Expand All @@ -114,9 +177,16 @@ const Heuristic: React.FC<HeuristicProps> = ({
<MenuItem dense onClick={handleMenuHighlight}>
{HIGHLIGHT_ICON}Toggle Highlight
</MenuItem>
{signature && (
<MenuItem dense onClick={handleMenuSafelist}>
{SAFELIST_ICON}
{t('safelist')}
</MenuItem>
)}
</Menu>
<CustomChip
wrap
variant={safe ? 'outlined' : 'default'}
size="tiny"
type="rounded"
color={highlight_key && isHighlighted(highlight_key) ? ('primary' as 'info') : color}
Expand Down
2 changes: 2 additions & 0 deletions src/components/visual/ResultCard/result_section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ export type Section = {
signature: {
frequency: number;
name: string;
safe: boolean;
}[];
};
tags: {
Expand Down Expand Up @@ -600,6 +601,7 @@ const ResultSection: React.FC<ResultSectionProps> = ({
signature
show_type
highlight_key={getKey('heuristic.signature', signature.name)}
safe={signature.safe}
/>
))}
{Array.isArray(section.tags) &&
Expand Down
9 changes: 8 additions & 1 deletion src/components/visual/SearchResult/safelist.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ export type Safelist = {
sources: {
name: string[];
};
signature: {
name: string;
};
tag: {
type: string;
value: string;
Expand Down Expand Up @@ -114,7 +117,11 @@ const WrappedSafelistTable: React.FC<SafelistTableProps> = ({
</DivTableCell>
<DivTableCell>{sl_item.type}</DivTableCell>
<DivTableCell breakable>
{sl_item.type === 'file' ? sl_item.id : `${sl_item.tag.type} - ${maxLenStr(sl_item.tag.value, 100)}`}
{sl_item.type === 'file'
? sl_item.id
: sl_item.type === 'signature'
? maxLenStr(sl_item.signature.name, 100)
: `${sl_item.tag.type} - ${maxLenStr(sl_item.tag.value, 100)}`}
</DivTableCell>
<DivTableCell breakable>{sl_item.sources.name.join(' | ')}</DivTableCell>
{c12nDef.enforce && (
Expand Down
3 changes: 3 additions & 0 deletions src/locales/en/manage/safelist_detail.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
"remove": "Remove this hash from the safelist",
"size": "Size",
"sources": "Sources",
"signature.title": "Signature information",
"signature.name": "Name",
"tag.title": "Tag information",
"tag.type": "Type",
"tag.value": "Value",
Expand All @@ -34,6 +36,7 @@
"timing.updated": "Last updated",
"title": "Safelisted hash details",
"title.file": "Safelisted file details",
"title.signature": "Safelisted signature details",
"title.tag": "Safelisted tag details",
"unknown": "Unavailable",
"usage": "Show hash usage",
Expand Down
3 changes: 3 additions & 0 deletions src/locales/fr/manage/safelist_detail.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"file.type": "Type",
"hashes": "Hachages associés",
"remove": "Supprimer ce hachage de la liste sûre",
"signature.title": "Informations sur la signature",
"signature.name": "Nom",
"size": "Taille",
"sources": "Sources",
"tag.title": "Informations sur les balises",
Expand All @@ -34,6 +36,7 @@
"timing.updated": "Dernière mise à jour",
"title": "Détails de hachage en liste sûre",
"title.file": "Détails de fichier en liste sûre",
"title.signature": "Détails de signature en liste sûre",
"title.tag": "Détails de balises en liste sûre",
"unknown": "Indisponible",
"usage": "Afficher l'utilisation du hachage",
Expand Down

0 comments on commit e803f08

Please sign in to comment.