-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
working with Threat dragon 2 #123
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,8 +10,10 @@ import { | |
INTERNAL_API_PORT, | ||
isSuit, | ||
logEvent, | ||
mapModel2toOldModel, | ||
ModelType, | ||
ThreatDragonModel, | ||
ThreatDragonModel2, | ||
ThreatDragonThreat, | ||
gameName, | ||
} from '@eop/shared'; | ||
|
@@ -86,10 +88,17 @@ export const createGame = | |
switch (body.modelType) { | ||
case ModelType.THREAT_DRAGON: { | ||
// TODO: validation | ||
await gameServer.db.setModel( | ||
matchID, | ||
JSON.parse(body.model as string) as ThreatDragonModel, | ||
); | ||
logEvent(`printing body: ${body.model}`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This log statement should be removed. The model can potentially contain sensitive data that MUST NOT end up in the logs. |
||
var model = JSON.parse(body.model as string) as ThreatDragonModel; | ||
await gameServer.db.setModel(matchID,model); | ||
break; | ||
} | ||
|
||
case ModelType.THREAT_DRAGON_V2: { | ||
logEvent(`printing body: ${body.model}`); | ||
var model2 = JSON.parse(body.model as string) as ThreatDragonModel2; | ||
var model = mapModel2toOldModel(model2); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do I understand it correctly: The Input is a V2 model, but internally it gets mapped to a V1 model? This would mean that the model that can be downloaded is also V1? For the users this might be every unintuitive... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tend to agree. I know it's probably a decent amount of work, but I would prefer to actually support V2 properly, which likely means completely switching out the rendering logic of the diagrams. We might also have to deal with the fact that a threat dragon model can contain multiple diagrams. I'm not sure how this is handled right now (if it is at all). But maybe this could be an interim solution, to unblock users who want to load a v2 model into EoP, until we have a proper solution? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok. But if we use this as an interim solution, we should be transparent and rename the download button. Maybe add "(Threat Dragon V1)" tiny underneath the "Download Threats"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes @ChristophNiehoff i have mapped v2 model to v1 as workaround. |
||
await gameServer.db.setModel(matchID,model); | ||
break; | ||
} | ||
|
||
|
@@ -222,7 +231,8 @@ export const downloadThreatDragonModel = | |
|
||
const isJsonModel = | ||
state.G.modelType == ModelType.PRIVACY_ENHANCED || | ||
state.G.modelType == ModelType.THREAT_DRAGON; | ||
state.G.modelType == ModelType.THREAT_DRAGON || | ||
state.G.modelType == ModelType.THREAT_DRAGON_V2; | ||
|
||
const model = game.model; | ||
if (!model || 'extension' in model || !isJsonModel) { | ||
|
@@ -295,7 +305,8 @@ export const downloadThreatsMarkdownFile = | |
|
||
const isJsonModel = | ||
state.G.modelType == ModelType.PRIVACY_ENHANCED || | ||
state.G.modelType == ModelType.THREAT_DRAGON; | ||
state.G.modelType == ModelType.THREAT_DRAGON || | ||
state.G.modelType == ModelType.THREAT_DRAGON_V2; | ||
|
||
const model = game.model; | ||
const threats = getThreats( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
/** | ||
* The threat models used by OWASP Threat Dragon | ||
* | ||
* This type is based on the schema at https://owasp.org/www-project-threat-dragon/assets/schemas/owasp.threat-dragon.schema.V2.json | ||
*/ | ||
|
||
export interface ThreatDragonModel2 { | ||
summary: Summary | ||
detail: Detail | ||
version: string | ||
} | ||
|
||
export interface Summary { | ||
title: string | ||
owner: string | ||
description: string | ||
id: number | ||
} | ||
|
||
export interface Detail { | ||
contributors: Contributor[] | ||
diagrams: Diagram[] | ||
reviewer: string | ||
diagramTop: number | ||
threatTop: number | ||
} | ||
|
||
export interface Contributor { | ||
name: string | ||
} | ||
|
||
export interface Diagram { | ||
cells: Cell[] | ||
version: string | ||
title: string | ||
thumbnail: string | ||
id: number | ||
} | ||
|
||
export interface Cell { | ||
position?: { | ||
/** | ||
* The component horizontal position | ||
*/ | ||
x: number; | ||
/** | ||
* The component vertical position | ||
*/ | ||
y: number; | ||
[k: string]: unknown; | ||
}; | ||
size?: { | ||
/** | ||
* The component height | ||
*/ | ||
height: number; | ||
/** | ||
* The component width | ||
*/ | ||
width: number; | ||
}; | ||
attrs?: Attrs | ||
visible?: boolean | ||
shape: string | ||
zIndex: number | ||
id: string | ||
data: Data | ||
width?: number | ||
height?: number | ||
connector?: string | ||
labels?: Label[] | ||
source?: Source | ||
target?: Target | ||
vertices?: { | ||
/** | ||
* The horizontal value of the curve point | ||
*/ | ||
x: number; | ||
/** | ||
* The vertical value of the curve point | ||
*/ | ||
y: number; | ||
}; | ||
} | ||
|
||
export interface Position { | ||
x: number | ||
y: number | ||
} | ||
|
||
export interface Size { | ||
width: number | ||
height: number | ||
} | ||
|
||
export interface Attrs { | ||
line?: Line | ||
text?: Text | ||
topLine?: TopLine | ||
bottomLine?: BottomLine | ||
body?: Body | ||
} | ||
|
||
export interface Line { | ||
stroke: string | ||
strokeWidth?: number | ||
targetMarker: TargetMarker | ||
sourceMarker: SourceMarker | ||
strokeDasharray?: string | ||
} | ||
|
||
export interface TargetMarker { | ||
name: string | ||
} | ||
|
||
export interface SourceMarker { | ||
name: string | ||
} | ||
|
||
export interface Text { | ||
text: string | ||
} | ||
|
||
export interface TopLine { | ||
stroke: string | ||
strokeWidth: number | ||
strokeDasharray: any | ||
} | ||
|
||
export interface BottomLine { | ||
stroke: string | ||
strokeWidth: number | ||
strokeDasharray: any | ||
} | ||
|
||
export interface Body { | ||
stroke: string | ||
strokeWidth: number | ||
strokeDasharray: any | ||
} | ||
|
||
export interface Data { | ||
name: string | ||
description: string | ||
type: CellType | ||
isTrustBoundary: boolean | ||
outOfScope?: boolean | ||
reasonOutOfScope?: string | ||
threats?: Threat[] | ||
hasOpenThreats: boolean | ||
isALog?: boolean | ||
storesCredentials?: boolean | ||
isEncrypted?: boolean | ||
isSigned?: boolean | ||
providesAuthentication?: boolean | ||
isBidirectional?: boolean | ||
isPublicNetwork?: boolean | ||
protocol?: string | ||
} | ||
|
||
export interface Threat { | ||
status: Status | ||
severity: string | ||
title: string | ||
type: string | ||
description: string | ||
mitigation: string | ||
modelType: string | ||
id: string | ||
} | ||
|
||
export interface Label { | ||
/** | ||
* The label position | ||
*/ | ||
position: number; | ||
/** | ||
* The label text attributes | ||
*/ | ||
attrs: { | ||
/** | ||
* The text attributes | ||
*/ | ||
label: { | ||
/** | ||
* The text size | ||
*/ | ||
// 'font-size': string; | ||
/** | ||
* The text weight | ||
*/ | ||
// 'font-weight': string; | ||
/** | ||
* The text content | ||
*/ | ||
text: string; | ||
}; | ||
}; | ||
} | ||
|
||
export interface Attrs2 { | ||
label: Label2 | ||
} | ||
|
||
export interface Label2 { | ||
text: string | ||
} | ||
|
||
export interface Source { | ||
x?: number | ||
y?: number | ||
cell?: string | ||
} | ||
|
||
export interface Target { | ||
x?: number | ||
y?: number | ||
cell?: string | ||
} | ||
|
||
export interface Vertex { | ||
x: number | ||
y: number | ||
} | ||
export type CellType = | ||
| 'tm.Process' | ||
| 'tm.Store' | ||
| 'tm.Actor' | ||
| 'tm.Flow' | ||
| 'tm.Boundary' | ||
| 'tm.BoundaryBox'; | ||
|
||
type Status = 'NA' | 'Open' | 'Mitigated'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does one need a dedicated form group for V2? Or could one validate the uploaded model and set a
ModelType
according to that?