Skip to content

Commit 3df9e2a

Browse files
committed
refactor(frontend): security improvements - remove inline style from HTML file, remove inline JS eval from main process, add additional security restrictions
1 parent f868cbf commit 3df9e2a

File tree

6 files changed

+86
-46
lines changed

6 files changed

+86
-46
lines changed

src/frontend/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
</div>
5858
<div id='root-container' class='container'>
5959
<div id='ROOT'>
60-
<div id="context-menu-container" style="display: none;"></div>
60+
<div id="context-menu-container"></div>
6161
<div id='fixed-search'>
6262
</div>
6363
<section id="main">

src/frontend/index/install.nim

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import
66
../[ types ],
77
../../common/[ paths, ct_logging ]
88

9+
from window import setupSecureContext
10+
911
type
1012
InstallResponseKind* {.pure.} = enum Ok, Problem, Dismissed
1113

@@ -22,31 +24,33 @@ var
2224
process {.importc.}: js
2325

2426
proc createInstallSubwindow*(): js =
25-
let win = jsnew electron.BrowserWindow(
26-
js{
27-
"width": 700,
28-
"height": 422,
29-
"resizable": false,
30-
"parent": mainWindow,
31-
"modal": true,
32-
"webPreferences": js{
33-
"nodeIntegration": true,
34-
"contextIsolation": false,
35-
"spellcheck": false
36-
},
37-
"frame": false,
38-
"transparent": false,
39-
})
40-
41-
let url = "file://" & $codetracerExeDir & "/subwindow.html"
42-
debugPrint "Attempting to load: ", url
43-
win.loadURL(cstring(url))
44-
45-
let inDevEnv = nodeProcess.env[cstring"CODETRACER_DEV_TOOLS"] == cstring"1"
46-
if inDevEnv:
47-
electronDebug.devTools(win)
48-
49-
win.toJs
27+
let win = jsnew electron.BrowserWindow(
28+
js{
29+
"width": 700,
30+
"height": 422,
31+
"resizable": false,
32+
"parent": mainWindow,
33+
"modal": true,
34+
"webPreferences": js{
35+
"nodeIntegration": true,
36+
"contextIsolation": false,
37+
"spellcheck": false
38+
},
39+
"frame": false,
40+
"transparent": false,
41+
}
42+
)
43+
setupSecureContext(win)
44+
45+
let url = $codetracerExeDir & "/subwindow.html"
46+
debugPrint "Attempting to load: ", url
47+
win.loadFile(url)
48+
49+
let inDevEnv = nodeProcess.env[cstring"CODETRACER_DEV_TOOLS"] == cstring"1"
50+
if inDevEnv:
51+
electronDebug.devTools(win)
52+
53+
win.toJs
5054

5155

5256
proc onInstallCt*(sender: js, response: js) {.async.} =

src/frontend/index/window.nim

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,32 @@ proc onClose*(e: js) =
3636
mainWindow.webContents.send "CODETRACER::close", js{}
3737
close = true
3838

39+
proc setupSecureContext*(win: JsObject) =
40+
# Prevent opening new windows or popups
41+
win.webContents.setWindowOpenHandler(proc: js =
42+
return js{
43+
"action": "deny"
44+
}
45+
)
46+
47+
# Disable webview tags
48+
electron_vars.app.on(
49+
"web-contents-created",
50+
proc(evt: js, contents: js) =
51+
contents.on("will-attach-webview", proc(event: js) =
52+
event.preventDefault()
53+
)
54+
)
55+
56+
# Disable window navigation
57+
win.on(
58+
"will-navigate",
59+
proc(e: js, url: js) =
60+
let current = win.getURL()
61+
if url != current:
62+
e.preventDefault()
63+
)
64+
3965
proc createMainWindow*: js =
4066
when not defined(server):
4167
# TODO load from config
@@ -72,13 +98,16 @@ proc createMainWindow*: js =
7298

7399
let win = jsnew electron.BrowserWindow(initInfo)
74100
win.on("maximize", proc() =
75-
win.webContents.executeJavaScript("document.body.style.backgroundColor = 'black';"))
101+
win.webContents.send "CODETRACER::maximize", js{}
102+
)
76103
win.on("unmaximize", proc() =
77-
win.webContents.executeJavaScript("document.body.style.backgroundColor = 'transparent';"))
104+
win.webContents.send "CODETRACER::unmaximize", js{}
105+
)
78106
win.maximize()
79-
let url = "file://" & $codetracerExeDir & "/index.html"
80107

81-
win.loadURL(cstring(url))
108+
let url = $codetracerExeDir & "/index.html"
109+
win.loadFile(url)
110+
setupSecureContext(win)
82111

83112
win.on("close", onClose)
84113
# TODO: eventually add a shortcut and ipc message that lets us

src/frontend/styles/components/welcome_screen.styl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,3 +637,6 @@
637637

638638
.stylus-content
639639
width: 850px !important
640+
641+
#context-menu-container
642+
display: none

src/frontend/subwindow.html

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
<!DOCTYPE html>
22
<html>
3-
<head>
4-
<meta charset="UTF-8">
5-
<title>Install Subwindow</title>
6-
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Install Subwindow</title>
76
<link rel='stylesheet' href='frontend/styles/subwindow.css'>
8-
</head>
9-
<body>
10-
11-
<div id="ROOT"></div>
12-
13-
<script>
14-
window.electron = require('electron');
15-
let inElectron = true
16-
</script>
17-
<script type="text/javascript" src="subwindow.js"></script>
18-
19-
</body>
7+
</head>
8+
<body>
9+
<div id="ROOT"></div>
10+
<script>
11+
window.electron = require('electron');
12+
window.inElectron = true
13+
</script>
14+
<script type="text/javascript" src="subwindow.js"></script>
15+
</body>
2016
</html>

src/frontend/ui_js.nim

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,11 @@ macro uiIpcHandlers*(namespace: static[string], messages: untyped): untyped =
12121212
result.add(messageCode)
12131213
# echo result.repr
12141214

1215+
proc onMaximize(data: Data) =
1216+
jq("body").style.backgroundColor = cstring"black"
1217+
proc onUnmaximize(data: Data) =
1218+
jq("body").style.backgroundColor = cstring"transparent"
1219+
12151220
proc configureIPC(data: Data) =
12161221
uiIpcHandlers("CODETRACER::"):
12171222
# "new-record-window"
@@ -1305,6 +1310,9 @@ proc configureIPC(data: Data) =
13051310
"dap-receive-response"
13061311
"dap-receive-event"
13071312

1313+
"maximize"
1314+
"unmaximize"
1315+
13081316
duration("configureIPCRun")
13091317

13101318
proc zoomInEditors*(data: Data) =

0 commit comments

Comments
 (0)