mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-12 19:55:14 +02:00
Dynamic (#77)
This commit is contained in:
parent
55247b7fcd
commit
991c84a1eb
1464 changed files with 225448 additions and 1985 deletions
|
|
@ -4,11 +4,26 @@ import type { ScanView } from '../types';
|
|||
|
||||
export type ScanMode = 'full' | 'ast' | 'cfg' | 'taint';
|
||||
export type EngineProfile = 'fast' | 'balanced' | 'deep';
|
||||
export type VerifyBackend = 'auto' | 'docker' | 'process' | 'firecracker';
|
||||
export type HardenProfile = 'standard' | 'strict';
|
||||
|
||||
export interface StartScanBody {
|
||||
scan_root?: string;
|
||||
mode?: ScanMode;
|
||||
engine_profile?: EngineProfile;
|
||||
/**
|
||||
* Override dynamic verification for this scan.
|
||||
* true - force on.
|
||||
* false - force off.
|
||||
* absent - use server config default.
|
||||
*/
|
||||
verify?: boolean;
|
||||
/** Also verify Confidence < Medium findings. Default false. */
|
||||
verify_all_confidence?: boolean;
|
||||
/** Sandbox backend for dynamic verification. */
|
||||
verify_backend?: VerifyBackend;
|
||||
/** Process-backend hardening profile. */
|
||||
harden_profile?: HardenProfile;
|
||||
}
|
||||
|
||||
export function useStartScan() {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export interface FindingsParams {
|
|||
language?: string;
|
||||
rule_id?: string;
|
||||
status?: string;
|
||||
verification?: string;
|
||||
search?: string;
|
||||
sort_by?: string;
|
||||
sort_dir?: string;
|
||||
|
|
|
|||
11
frontend/src/api/queries/surface.ts
Normal file
11
frontend/src/api/queries/surface.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { useQuery } from '@tanstack/react-query';
|
||||
import { apiGet } from '../client';
|
||||
import type { SurfaceMap } from '../types';
|
||||
|
||||
export function useSurfaceMap() {
|
||||
return useQuery({
|
||||
queryKey: ['surface'],
|
||||
queryFn: ({ signal }) => apiGet<SurfaceMap>('/surface', signal),
|
||||
staleTime: 30_000,
|
||||
});
|
||||
}
|
||||
43
frontend/src/api/queries/targets.ts
Normal file
43
frontend/src/api/queries/targets.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { apiDelete, apiGet, apiPost } from '../client';
|
||||
import type { TargetView } from '../types';
|
||||
|
||||
export function useTargets() {
|
||||
return useQuery({
|
||||
queryKey: ['targets'],
|
||||
queryFn: ({ signal }) => apiGet<TargetView[]>('/targets', signal),
|
||||
});
|
||||
}
|
||||
|
||||
export function useAddTarget() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (body: { path: string }) =>
|
||||
apiPost<TargetView>('/targets', body),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['targets'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useSelectTarget() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (body: { id?: string; path?: string }) =>
|
||||
apiPost<TargetView>('/targets/select', body),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useDeleteTarget() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (id: string) =>
|
||||
apiDelete<void>(`/targets/${encodeURIComponent(id)}`),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['targets'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -2,6 +2,44 @@
|
|||
export type Confidence = 'Low' | 'Medium' | 'High';
|
||||
export type FlowStepKind = 'source' | 'assignment' | 'call' | 'phi' | 'sink';
|
||||
|
||||
// Dynamic verification types (from src/evidence.rs VerifyStatus / VerifyResult)
|
||||
export type VerifyStatus =
|
||||
| 'Confirmed'
|
||||
| 'PartiallyConfirmed'
|
||||
| 'NotConfirmed'
|
||||
| 'Inconclusive'
|
||||
| 'Unsupported';
|
||||
|
||||
export interface AttemptSummary {
|
||||
payload_label: string;
|
||||
exit_code?: number;
|
||||
timed_out: boolean;
|
||||
triggered: boolean;
|
||||
sink_hit?: boolean;
|
||||
}
|
||||
|
||||
export interface VerifyResult {
|
||||
finding_id: string;
|
||||
status: VerifyStatus;
|
||||
triggered_payload?: string;
|
||||
/** Typed UnsupportedReason (PascalCase string) */
|
||||
reason?: string;
|
||||
/** Typed InconclusiveReason (PascalCase string) */
|
||||
inconclusive_reason?: string;
|
||||
detail?: string;
|
||||
attempts?: AttemptSummary[];
|
||||
toolchain_match?: string;
|
||||
}
|
||||
|
||||
export interface DynamicVerificationSummary {
|
||||
total: number;
|
||||
confirmed: number;
|
||||
partially_confirmed: number;
|
||||
not_confirmed: number;
|
||||
inconclusive: number;
|
||||
unsupported: number;
|
||||
}
|
||||
|
||||
export interface FlowStep {
|
||||
step: number;
|
||||
kind: FlowStepKind;
|
||||
|
|
@ -40,6 +78,8 @@ export interface Evidence {
|
|||
flow_steps: FlowStep[];
|
||||
explanation?: string;
|
||||
confidence_limiters: string[];
|
||||
/** Dynamic verification result; present only when --verify was active. */
|
||||
dynamic_verdict?: VerifyResult;
|
||||
}
|
||||
|
||||
// Finding types
|
||||
|
|
@ -57,10 +97,31 @@ export interface RelatedFindingView {
|
|||
severity: string;
|
||||
}
|
||||
|
||||
// Baseline / patch-validation types (M6.5)
|
||||
export type VerdictTransition =
|
||||
| 'New'
|
||||
| 'Unchanged'
|
||||
| 'Resolved'
|
||||
| 'Regressed'
|
||||
| 'FlippedConfirmed'
|
||||
| 'FlippedNotConfirmed';
|
||||
|
||||
export interface VerdictDiffEntry {
|
||||
stable_hash: number;
|
||||
path: string;
|
||||
line: number;
|
||||
rule_id: string;
|
||||
baseline_status?: VerifyStatus;
|
||||
current_status?: VerifyStatus;
|
||||
transition: VerdictTransition;
|
||||
}
|
||||
|
||||
export interface FindingView {
|
||||
index: number;
|
||||
fingerprint: string;
|
||||
portable_fingerprint?: string;
|
||||
/** Blake3-derived stable cross-commit identity (M6.5). */
|
||||
stable_hash?: number;
|
||||
path: string;
|
||||
line: number;
|
||||
col: number;
|
||||
|
|
@ -79,6 +140,7 @@ export interface FindingView {
|
|||
triage_note?: string;
|
||||
code_context?: CodeContextView;
|
||||
evidence?: Evidence;
|
||||
dynamic_verdict?: VerifyResult;
|
||||
guard_kind?: string;
|
||||
rank_reason?: [string, string][];
|
||||
sanitizer_status?: string;
|
||||
|
|
@ -100,6 +162,7 @@ export interface FilterValues {
|
|||
languages: string[];
|
||||
rules: string[];
|
||||
statuses: string[];
|
||||
verification_statuses: string[];
|
||||
}
|
||||
|
||||
// Scan types
|
||||
|
|
@ -135,6 +198,17 @@ export interface ScanView {
|
|||
metrics?: ScanMetricsSnapshot;
|
||||
}
|
||||
|
||||
export interface TargetView {
|
||||
id: string;
|
||||
name: string;
|
||||
path: string;
|
||||
db_path: string;
|
||||
last_seen_at: string;
|
||||
last_scan_at?: string;
|
||||
active: boolean;
|
||||
exists: boolean;
|
||||
}
|
||||
|
||||
// Scan Comparison types
|
||||
export interface CompareScanInfo {
|
||||
id: string;
|
||||
|
|
@ -173,6 +247,8 @@ export interface CompareResponse {
|
|||
fixed_findings: ComparedFinding[];
|
||||
changed_findings: ChangedFinding[];
|
||||
unchanged_findings: ComparedFinding[];
|
||||
/** Verdict-level diff (M6.5). Present when findings carry stable_hash values. */
|
||||
verdict_diff?: VerdictDiffEntry[];
|
||||
}
|
||||
|
||||
// Overview types
|
||||
|
|
@ -302,6 +378,7 @@ export interface ScannerQuality {
|
|||
call_resolution_rate: number;
|
||||
symex_verified_rate: number;
|
||||
symex_breakdown: Record<string, number>;
|
||||
dynamic_verification: DynamicVerificationSummary;
|
||||
}
|
||||
|
||||
export interface IssueCategoryBucket {
|
||||
|
|
@ -843,3 +920,106 @@ export interface AuthAnalysisView {
|
|||
units: AuthUnitView[];
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
// ── Surface map (Phase 21–23) ───────────────────────────────────────
|
||||
|
||||
export interface SurfaceSourceLocation {
|
||||
file: string;
|
||||
line: number;
|
||||
col: number;
|
||||
}
|
||||
|
||||
export type SurfaceFramework =
|
||||
| 'flask'
|
||||
| 'fast_api'
|
||||
| 'django'
|
||||
| 'express'
|
||||
| 'koa'
|
||||
| 'spring'
|
||||
| 'jax_rs'
|
||||
| 'quarkus'
|
||||
| 'rails'
|
||||
| 'sinatra'
|
||||
| 'laravel'
|
||||
| 'slim'
|
||||
| 'axum'
|
||||
| 'actix'
|
||||
| 'rocket'
|
||||
| 'net_http'
|
||||
| 'gin'
|
||||
| 'next_app_router'
|
||||
| 'next_server_action';
|
||||
|
||||
export type SurfaceHttpMethod =
|
||||
| 'GET'
|
||||
| 'HEAD'
|
||||
| 'POST'
|
||||
| 'PUT'
|
||||
| 'PATCH'
|
||||
| 'DELETE'
|
||||
| 'OPTIONS';
|
||||
|
||||
export type SurfaceDataStoreKind =
|
||||
| 'sql'
|
||||
| 'key_value'
|
||||
| 'document'
|
||||
| 'blob_store'
|
||||
| 'filesystem'
|
||||
| 'unknown';
|
||||
|
||||
export type SurfaceExternalKind =
|
||||
| 'http_api'
|
||||
| 'message_broker'
|
||||
| 'search_index'
|
||||
| 'auth_provider'
|
||||
| 'unknown';
|
||||
|
||||
export type SurfaceEdgeKind =
|
||||
| 'calls'
|
||||
| 'reads_from'
|
||||
| 'writes_to'
|
||||
| 'talks_to'
|
||||
| 'reaches'
|
||||
| 'triggers'
|
||||
| 'auth_required_on';
|
||||
|
||||
export type SurfaceNode =
|
||||
| {
|
||||
node: 'entry_point';
|
||||
location: SurfaceSourceLocation;
|
||||
framework: SurfaceFramework;
|
||||
method: SurfaceHttpMethod;
|
||||
route: string;
|
||||
handler_name: string;
|
||||
handler_location: SurfaceSourceLocation;
|
||||
auth_required: boolean;
|
||||
}
|
||||
| {
|
||||
node: 'data_store';
|
||||
location: SurfaceSourceLocation;
|
||||
kind: SurfaceDataStoreKind;
|
||||
label: string;
|
||||
}
|
||||
| {
|
||||
node: 'external_service';
|
||||
location: SurfaceSourceLocation;
|
||||
kind: SurfaceExternalKind;
|
||||
label: string;
|
||||
}
|
||||
| {
|
||||
node: 'dangerous_local';
|
||||
location: SurfaceSourceLocation;
|
||||
function_name: string;
|
||||
cap_bits: number;
|
||||
};
|
||||
|
||||
export interface SurfaceEdge {
|
||||
from: number;
|
||||
to: number;
|
||||
kind: SurfaceEdgeKind;
|
||||
}
|
||||
|
||||
export interface SurfaceMap {
|
||||
nodes: SurfaceNode[];
|
||||
edges: SurfaceEdge[];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue