@kitajs/ts-html-plugin 5.0.0-next.0 → 5.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -20
- package/bin/index.js +4 -4
- package/dist/cli.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js.map +1 -1
- package/package.json +10 -10
- package/src/cli.ts +66 -66
- package/src/errors.ts +5 -5
- package/src/index.ts +18 -18
- package/src/util.ts +70 -70
package/README.md
CHANGED
|
@@ -142,22 +142,22 @@ address this:
|
|
|
142
142
|
After all, what's the problem of being safe twice?
|
|
143
143
|
|
|
144
144
|
```tsx
|
|
145
|
-
const html = <div safe>{content}</div
|
|
145
|
+
const html = <div safe>{content}</div>
|
|
146
146
|
```
|
|
147
147
|
|
|
148
148
|
2. **Prepend the Variable with `safe`:** Indicate to the plugin that you are confident the
|
|
149
149
|
variable is safe to use by adding `safe` before it.
|
|
150
150
|
|
|
151
151
|
```tsx
|
|
152
|
-
const safeContent = ''
|
|
153
|
-
const html = <div>{safeContent}</div
|
|
152
|
+
const safeContent = ''
|
|
153
|
+
const html = <div>{safeContent}</div>
|
|
154
154
|
```
|
|
155
155
|
|
|
156
156
|
3. **Cast to `'safe'`:** When using raw values or function calls without saving them into
|
|
157
157
|
a variable, you can append `as 'safe'` to the expression to inform the plugin.
|
|
158
158
|
|
|
159
159
|
```tsx
|
|
160
|
-
const html = <div>{content as 'safe'}</div
|
|
160
|
+
const html = <div>{content as 'safe'}</div>
|
|
161
161
|
```
|
|
162
162
|
|
|
163
163
|
<br />
|
|
@@ -208,17 +208,17 @@ Please use the safe attribute on the JSX element or prepend your variable with `
|
|
|
208
208
|
```tsx
|
|
209
209
|
// ❌ Content variable may have a value of `<script>alert('xss')</script>`
|
|
210
210
|
// which will lead to XSS vulnerabilities.
|
|
211
|
-
const html = <div>{content}</div
|
|
211
|
+
const html = <div>{content}</div>
|
|
212
212
|
|
|
213
213
|
// ✅ Content variable may have a value of `<script>alert('xss')</script>`,
|
|
214
214
|
// but it's safe to use because it will get escaped to =
|
|
215
215
|
// `<script>alert('xss')</script>`.
|
|
216
|
-
const html = <div safe>{content}</div
|
|
216
|
+
const html = <div safe>{content}</div>
|
|
217
217
|
|
|
218
218
|
// ⚠️ Content variable may have a value of `<script>alert('xss')</script>`,
|
|
219
219
|
// but variable starts with safe, so the error is suppressed.
|
|
220
|
-
const safeContent = content
|
|
221
|
-
const html = <div>{safeContent}</div
|
|
220
|
+
const safeContent = content
|
|
221
|
+
const html = <div>{safeContent}</div>
|
|
222
222
|
```
|
|
223
223
|
|
|
224
224
|
<br />
|
|
@@ -239,7 +239,7 @@ const html = (
|
|
|
239
239
|
<a safe>
|
|
240
240
|
<b>1</b>
|
|
241
241
|
</a>
|
|
242
|
-
)
|
|
242
|
+
)
|
|
243
243
|
|
|
244
244
|
// ✅ Safe attribute in the inner element will escape only the inner element.
|
|
245
245
|
// In this case the <b> tag will be escaped, resulting into
|
|
@@ -248,7 +248,7 @@ const html = (
|
|
|
248
248
|
<a>
|
|
249
249
|
<b safe>1</b>
|
|
250
250
|
</a>
|
|
251
|
-
)
|
|
251
|
+
)
|
|
252
252
|
```
|
|
253
253
|
|
|
254
254
|
<br />
|
|
@@ -267,16 +267,16 @@ native JSX.
|
|
|
267
267
|
```tsx
|
|
268
268
|
// ❌ Content variable may have a value of `<script>alert('xss')</script>`
|
|
269
269
|
// which will lead to XSS vulnerabilities.
|
|
270
|
-
const html = <Component>{content}</Component
|
|
270
|
+
const html = <Component>{content}</Component>
|
|
271
271
|
|
|
272
272
|
// ✅ Content variable may have a value of `<script>alert('xss')</script>`,
|
|
273
273
|
// but it's safe to use because you manually call the escape function.
|
|
274
|
-
const html = <Component>{Html.escapeHtml(content)}</Component
|
|
274
|
+
const html = <Component>{Html.escapeHtml(content)}</Component>
|
|
275
275
|
|
|
276
276
|
// ⚠️ Content variable may have a value of `<script>alert('xss')</script>`,
|
|
277
277
|
// but variable starts with safe, so the error is suppressed.
|
|
278
|
-
const safeContent = content
|
|
279
|
-
const html = <Component>{safeContent}</Component
|
|
278
|
+
const safeContent = content
|
|
279
|
+
const html = <Component>{safeContent}</Component>
|
|
280
280
|
```
|
|
281
281
|
|
|
282
282
|
<br />
|
|
@@ -291,16 +291,16 @@ vulnerabilities. Please remove the safe attribute or prepend your variable with
|
|
|
291
291
|
```tsx
|
|
292
292
|
// ⚠️ The variable will never have any harmful XSS content, so the safe attribute is
|
|
293
293
|
// not needed and can be removed.
|
|
294
|
-
const html = <div safe>{numberVariable}</div
|
|
294
|
+
const html = <div safe>{numberVariable}</div>
|
|
295
295
|
|
|
296
296
|
// ✅ This variable will never have any harmful XSS content, so we can use it
|
|
297
297
|
// as is.
|
|
298
|
-
const html = <div>{numberVariable}</div
|
|
298
|
+
const html = <div>{numberVariable}</div>
|
|
299
299
|
|
|
300
300
|
// ✅ You manually told this plugin that the variable is unsafe, so errors will
|
|
301
301
|
// be thrown.
|
|
302
|
-
const unsafeVariable = numberVariable
|
|
303
|
-
const html = <div safe>{unsafeVariable}</div
|
|
302
|
+
const unsafeVariable = numberVariable
|
|
303
|
+
const html = <div safe>{unsafeVariable}</div>
|
|
304
304
|
```
|
|
305
305
|
|
|
306
306
|
<br />
|
|
@@ -318,14 +318,14 @@ information.
|
|
|
318
318
|
execute the content anyways.
|
|
319
319
|
|
|
320
320
|
```tsx
|
|
321
|
-
const html = <script>{content}</script
|
|
321
|
+
const html = <script>{content}</script>
|
|
322
322
|
```
|
|
323
323
|
|
|
324
324
|
2. Ternary and binary operations are evaluated in both sides separately and will throw
|
|
325
325
|
errors if any of the sides is not safe, even their condition never gets hit at runtime.
|
|
326
326
|
|
|
327
327
|
```tsx
|
|
328
|
-
const html = <div>{true ? safeContent : content}</div
|
|
328
|
+
const html = <div>{true ? safeContent : content}</div>
|
|
329
329
|
// ~~~~~~~
|
|
330
330
|
```
|
|
331
331
|
|
package/bin/index.js
CHANGED
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,GAAG;;;CAGf,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,GAAG;;;CAGf,CAAA;AAED,eAAO,MAAM,YAAY;;;CAGxB,CAAA;AAED,eAAO,MAAM,YAAY;;;CAGxB,CAAA;AAED,eAAO,MAAM,UAAU;;;CAGtB,CAAA"}
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA,SAAS,WAAW,CAAC,IAAY,EAAE,OAAe
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA,SAAS,WAAW,CAAC,IAAY,EAAE,OAAe;IAChD,OAAO;QACL,IAAI;QACJ,OAAO,EACL,OAAO,CAAC,GAAG,CAAC,yBAAyB,KAAK,MAAM;YAC9C,CAAC,CAAC,GAAG,OAAO,mCAAmC,IAAI,EAAE;YACrD,CAAC,CAAC,OAAO;KACd,CAAA;AACH,CAAC;AAED,wDAAwD;AACxD,gBAAgB;AAChB,iCAAiC;AACjC,oBAAoB;AAEP,QAAA,GAAG,GAAG,WAAW,CAC5B,KAAK,EACL,4FAA4F,CAC7F,CAAA;AAEY,QAAA,YAAY,GAAG,WAAW,CACrC,KAAK,EACL,0EAA0E,CAC3E,CAAA;AAEY,QAAA,YAAY,GAAG,WAAW,CACrC,KAAK,EACL,gEAAgE,CACjE,CAAA;AAEY,QAAA,UAAU,GAAG,WAAW,CACnC,KAAK,EACL,mDAAmD,CACpD,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { default as TS, server } from 'typescript/lib/tsserverlibrary';
|
|
|
2
2
|
declare const _default: (modules: {
|
|
3
3
|
typescript: typeof TS;
|
|
4
4
|
}) => {
|
|
5
|
-
create(info: Pick<server.PluginCreateInfo,
|
|
5
|
+
create(info: Pick<server.PluginCreateInfo, 'languageService'>): TS.LanguageService;
|
|
6
6
|
};
|
|
7
7
|
export = _default;
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAA;kCAG/C;IAAE,UAAU,EAAE,OAAO,EAAE,CAAA;CAAE;IAIjD,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,iBAAiB,CAAC;;AAJjE,kBAuCC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,iCAAkE;AAElE,iBAAS,UAAU,OAAkC;IACnD,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAA;IAE7B,OAAO;QACL,MAAM,CAAC,IAAsD;YAC3D,MAAM,KAAK,GAAG,IAAA,kBAAW,EAAC,IAAI,CAAC,eAAe,CAAC,CAAA;YAE/C,KAAK,CAAC,sBAAsB,GAAG,SAAS,yBAAyB,CAAC,QAAQ;gBACxE,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAA;gBAEzE,uCAAuC;gBACvC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC7D,OAAO,WAAW,CAAA;gBACpB,CAAC;gBAED,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,CAAA;gBAEjD,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,WAAW,CAAA;gBACpB,CAAC;gBAED,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;gBAE9C,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,OAAO,WAAW,CAAA;gBACpB,CAAC;gBAED,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,EAAE,CAAA;gBAE5C,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,eAAe,CAAC,IAAI;oBACnD,IAAA,mCAA4B,EAAC,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;gBAClE,CAAC,CAAC,CAAA;gBAEF,OAAO,WAAW,CAAA;YACpB,CAAC,CAAA;YAED,OAAO,KAAK,CAAA;QACd,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}
|
package/dist/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,OAAO,IAAI,EAAE,EACnB,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,OAAO,IAAI,EAAE,EACnB,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAEV,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,IAAI,EACJ,OAAO,IAAI,EAAE,EACb,IAAI,EACJ,WAAW,EACZ,MAAM,gCAAgC,CAAA;AAgBvC,wBAAgB,4BAA4B,CAC1C,EAAE,EAAE,OAAO,EAAE,EACb,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,UAAU,EAAE,QAwBvB;AAkBD,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,OAAO,EAAE,EACb,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,qBAAqB,EACtD,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,UAAU,EAAE,GACxB,IAAI,CA+FN;AAkED,wBAAgB,eAAe,CAC7B,EAAE,EAAE,OAAO,EAAE,EACb,IAAI,EAAE,IAAI,GAAG,SAAS,EACtB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,EAAE,CAAC,IAAI,GACZ,OAAO,CAkHT;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,mCAQ1D;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAUvD"}
|
package/dist/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeA,MAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitajs/ts-html-plugin",
|
|
3
|
-
"version": "5.0.0-next.
|
|
3
|
+
"version": "5.0.0-next.1",
|
|
4
4
|
"homepage": "https://github.com/kitajs/html/tree/master/packages/ts-html-plugin#readme",
|
|
5
5
|
"bugs": "https://github.com/kitajs/html/issues",
|
|
6
6
|
"repository": {
|
|
@@ -26,23 +26,23 @@
|
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"chalk": "^5.6.2",
|
|
29
|
-
"tslib": "
|
|
29
|
+
"tslib": "2.8.1",
|
|
30
30
|
"yargs": "^18.0.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@types/node": "
|
|
33
|
+
"@types/node": "24.12.2",
|
|
34
34
|
"@types/yargs": "^17.0.35",
|
|
35
|
-
"@typescript/native-preview": "
|
|
36
|
-
"@vitest/coverage-v8": "
|
|
35
|
+
"@typescript/native-preview": "7.0.0-dev.20260411.1",
|
|
36
|
+
"@vitest/coverage-v8": "4.1.4",
|
|
37
37
|
"fast-defer": "^1.1.9",
|
|
38
38
|
"self-ts-plugin": "link:",
|
|
39
|
-
"typescript": "
|
|
40
|
-
"vitest": "
|
|
41
|
-
"@kitajs/html": "^5.0.0-next.
|
|
39
|
+
"typescript": "6.0.2",
|
|
40
|
+
"vitest": "4.1.4",
|
|
41
|
+
"@kitajs/html": "^5.0.0-next.1"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"typescript": "
|
|
45
|
-
"@kitajs/html": "^5.0.0-next.
|
|
44
|
+
"typescript": "6.0.2",
|
|
45
|
+
"@kitajs/html": "^5.0.0-next.1"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "tsgo -p tsconfig.build.json",
|
package/src/cli.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
import fs from 'node:fs'
|
|
3
|
-
import path from 'node:path'
|
|
4
|
-
import ts from 'typescript'
|
|
5
|
-
import yargs from 'yargs'
|
|
6
|
-
import { hideBin } from 'yargs/helpers'
|
|
7
|
-
import { recursiveDiagnoseJsxElements } from './util'
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
import fs from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import ts from 'typescript'
|
|
5
|
+
import yargs from 'yargs'
|
|
6
|
+
import { hideBin } from 'yargs/helpers'
|
|
7
|
+
import { recursiveDiagnoseJsxElements } from './util'
|
|
8
8
|
|
|
9
|
-
const { version } = require('../package.json')
|
|
9
|
+
const { version } = require('../package.json')
|
|
10
10
|
|
|
11
11
|
const help = `
|
|
12
12
|
|
|
@@ -34,13 +34,13 @@ Exit codes:
|
|
|
34
34
|
1 - XSS vulnerabilities were found
|
|
35
35
|
2 - Only warnings were found
|
|
36
36
|
|
|
37
|
-
`.trim()
|
|
37
|
+
`.trim()
|
|
38
38
|
|
|
39
39
|
function readCompilerOptions(tsconfigPath: string) {
|
|
40
|
-
const { config, error } = ts.readConfigFile(tsconfigPath, ts.sys.readFile)
|
|
40
|
+
const { config, error } = ts.readConfigFile(tsconfigPath, ts.sys.readFile)
|
|
41
41
|
|
|
42
42
|
if (error) {
|
|
43
|
-
return { errors: [error] }
|
|
43
|
+
return { errors: [error] }
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
const { options, errors, fileNames } = ts.parseJsonConfigFileContent(
|
|
@@ -49,38 +49,38 @@ function readCompilerOptions(tsconfigPath: string) {
|
|
|
49
49
|
path.dirname(tsconfigPath),
|
|
50
50
|
undefined,
|
|
51
51
|
tsconfigPath
|
|
52
|
-
)
|
|
52
|
+
)
|
|
53
53
|
|
|
54
54
|
if (errors.length) {
|
|
55
|
-
return { errors }
|
|
55
|
+
return { errors }
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
return { options, fileNames, errors: undefined }
|
|
58
|
+
return { options, fileNames, errors: undefined }
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function prettyPrintErrorCount(diagnostics: ts.Diagnostic[], root: string) {
|
|
62
|
-
const files = new Map<string, number>()
|
|
62
|
+
const files = new Map<string, number>()
|
|
63
63
|
|
|
64
64
|
// Counts the amount of errors per file
|
|
65
65
|
for (const diagnostic of diagnostics) {
|
|
66
66
|
if (!diagnostic.file) {
|
|
67
|
-
continue
|
|
67
|
+
continue
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const file = files.get(diagnostic.file.fileName)
|
|
70
|
+
const file = files.get(diagnostic.file.fileName)
|
|
71
71
|
|
|
72
72
|
if (file !== undefined) {
|
|
73
|
-
files.set(diagnostic.file.fileName, file + 1)
|
|
74
|
-
continue
|
|
73
|
+
files.set(diagnostic.file.fileName, file + 1)
|
|
74
|
+
continue
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
files.set(diagnostic.file.fileName, 1)
|
|
77
|
+
files.set(diagnostic.file.fileName, 1)
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
if (files.size > 1) {
|
|
81
81
|
console.error(
|
|
82
82
|
chalk.red(`Found a total of ${diagnostics.length} errors in ${files.size} files\n`)
|
|
83
|
-
)
|
|
83
|
+
)
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
for (const [file, amount] of files.entries()) {
|
|
@@ -88,31 +88,31 @@ function prettyPrintErrorCount(diagnostics: ts.Diagnostic[], root: string) {
|
|
|
88
88
|
chalk.red(
|
|
89
89
|
`Found ${amount} error${amount === 1 ? '' : 's'} in ${path.relative(root, file)}`
|
|
90
90
|
)
|
|
91
|
-
)
|
|
91
|
+
)
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
function fileExists(p: string) {
|
|
96
96
|
try {
|
|
97
|
-
fs.statSync(p)
|
|
98
|
-
return true
|
|
97
|
+
fs.statSync(p)
|
|
98
|
+
return true
|
|
99
99
|
} catch {
|
|
100
|
-
return false
|
|
100
|
+
return false
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
export async function main() {
|
|
105
|
-
const args = await yargs(hideBin(process.argv)).help(false).version(version).argv
|
|
105
|
+
const args = await yargs(hideBin(process.argv)).help(false).version(version).argv
|
|
106
106
|
|
|
107
107
|
if (args.help || args.h) {
|
|
108
|
-
console.log(help)
|
|
109
|
-
return process.exit(0)
|
|
108
|
+
console.log(help)
|
|
109
|
+
return process.exit(0)
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
// Detects unknown arguments
|
|
113
113
|
for (const key in args) {
|
|
114
114
|
if (key === '_' || key === '$0') {
|
|
115
|
-
continue
|
|
115
|
+
continue
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
switch (key) {
|
|
@@ -121,56 +121,56 @@ export async function main() {
|
|
|
121
121
|
case 'p':
|
|
122
122
|
case 's':
|
|
123
123
|
case 'simplified':
|
|
124
|
-
continue
|
|
124
|
+
continue
|
|
125
125
|
default:
|
|
126
|
-
console.error(`Unknown argument: ${key}. Run --help for more information.`)
|
|
127
|
-
return process.exit(1)
|
|
126
|
+
console.error(`Unknown argument: ${key}. Run --help for more information.`)
|
|
127
|
+
return process.exit(1)
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
const root = args.cwd ? String(args.cwd) : process.cwd()
|
|
131
|
+
const root = args.cwd ? String(args.cwd) : process.cwd()
|
|
132
132
|
|
|
133
|
-
const tsconfigPath = String(args.project || args.p || 'tsconfig.json')
|
|
133
|
+
const tsconfigPath = String(args.project || args.p || 'tsconfig.json')
|
|
134
134
|
|
|
135
|
-
const simplified = !!(args.simplified || args.s)
|
|
135
|
+
const simplified = !!(args.simplified || args.s)
|
|
136
136
|
|
|
137
137
|
const diagnosticFormatter =
|
|
138
138
|
!process.stdout.isTTY || simplified
|
|
139
139
|
? ts.formatDiagnostics
|
|
140
|
-
: ts.formatDiagnosticsWithColorAndContext
|
|
140
|
+
: ts.formatDiagnosticsWithColorAndContext
|
|
141
141
|
|
|
142
142
|
if (!fileExists(tsconfigPath)) {
|
|
143
|
-
console.error((!simplified ? chalk.red : String)(`Could not find ${tsconfigPath}`))
|
|
144
|
-
return process.exit(1)
|
|
143
|
+
console.error((!simplified ? chalk.red : String)(`Could not find ${tsconfigPath}`))
|
|
144
|
+
return process.exit(1)
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
const tsconfig = readCompilerOptions(tsconfigPath)
|
|
147
|
+
const tsconfig = readCompilerOptions(tsconfigPath)
|
|
148
148
|
|
|
149
149
|
const diagnosticHost: ts.FormatDiagnosticsHost = {
|
|
150
150
|
getCurrentDirectory: ts.sys.getCurrentDirectory,
|
|
151
151
|
getCanonicalFileName: (fileName) => fileName,
|
|
152
152
|
getNewLine: () => ts.sys.newLine
|
|
153
|
-
}
|
|
153
|
+
}
|
|
154
154
|
|
|
155
155
|
if (tsconfig.errors) {
|
|
156
|
-
console.error(diagnosticFormatter(tsconfig.errors, diagnosticHost))
|
|
157
|
-
return process.exit(1)
|
|
156
|
+
console.error(diagnosticFormatter(tsconfig.errors, diagnosticHost))
|
|
157
|
+
return process.exit(1)
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
let files = tsconfig.fileNames
|
|
160
|
+
let files = tsconfig.fileNames
|
|
161
161
|
|
|
162
162
|
if (args._.length) {
|
|
163
163
|
// Prefer the files passed as arguments, otherwise use the files in tsconfig.json
|
|
164
|
-
files = []
|
|
164
|
+
files = []
|
|
165
165
|
|
|
166
166
|
for (let i = 0; i < args._.length; i++) {
|
|
167
|
-
const file = String(args._[i])
|
|
167
|
+
const file = String(args._[i])
|
|
168
168
|
|
|
169
169
|
if (!fileExists(file)) {
|
|
170
170
|
console.error(
|
|
171
171
|
(!simplified ? chalk.red : String)(`Could not find provided '${file}' file.`)
|
|
172
|
-
)
|
|
173
|
-
return process.exit(1)
|
|
172
|
+
)
|
|
173
|
+
return process.exit(1)
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
if (!file.match(/(t|j)sx$/)) {
|
|
@@ -178,52 +178,52 @@ export async function main() {
|
|
|
178
178
|
(!simplified ? chalk.yellow : String)(
|
|
179
179
|
`Provided '${file}' file is not a TSX/JSX file.`
|
|
180
180
|
)
|
|
181
|
-
)
|
|
182
|
-
continue
|
|
181
|
+
)
|
|
182
|
+
continue
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
files.push(file)
|
|
185
|
+
files.push(file)
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
if (!files.length) {
|
|
190
|
-
console.error((!simplified ? chalk.red : String)('No files were found to check.'))
|
|
191
|
-
return process.exit(1)
|
|
190
|
+
console.error((!simplified ? chalk.red : String)('No files were found to check.'))
|
|
191
|
+
return process.exit(1)
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
const program = ts.createProgram(files, tsconfig.options)
|
|
195
|
-
const typeChecker = program.getTypeChecker()
|
|
196
|
-
const sources = program.getSourceFiles()
|
|
194
|
+
const program = ts.createProgram(files, tsconfig.options)
|
|
195
|
+
const typeChecker = program.getTypeChecker()
|
|
196
|
+
const sources = program.getSourceFiles()
|
|
197
197
|
|
|
198
|
-
const diagnostics: ts.Diagnostic[] = []
|
|
198
|
+
const diagnostics: ts.Diagnostic[] = []
|
|
199
199
|
|
|
200
200
|
for (const source of sources) {
|
|
201
|
-
const filename = source.fileName
|
|
201
|
+
const filename = source.fileName
|
|
202
202
|
|
|
203
203
|
// Not a tsx file, so don't do anything
|
|
204
204
|
if (!filename.match(/(t|j)sx$/)) {
|
|
205
|
-
continue
|
|
205
|
+
continue
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
ts.forEachChild(source, function loopSourceNodes(node) {
|
|
209
|
-
recursiveDiagnoseJsxElements(ts, node, typeChecker, diagnostics)
|
|
210
|
-
})
|
|
209
|
+
recursiveDiagnoseJsxElements(ts, node, typeChecker, diagnostics)
|
|
210
|
+
})
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
if (diagnostics.length) {
|
|
214
214
|
const hasError = diagnostics.some(
|
|
215
215
|
(diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error
|
|
216
|
-
)
|
|
216
|
+
)
|
|
217
217
|
|
|
218
|
-
console.error(diagnosticFormatter(diagnostics, diagnosticHost))
|
|
218
|
+
console.error(diagnosticFormatter(diagnostics, diagnosticHost))
|
|
219
219
|
|
|
220
220
|
if (!simplified) {
|
|
221
|
-
prettyPrintErrorCount(diagnostics, root)
|
|
221
|
+
prettyPrintErrorCount(diagnostics, root)
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
process.exit(hasError ? 1 : 2)
|
|
224
|
+
process.exit(hasError ? 1 : 2)
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
-
console.log(chalk.green(`No XSS vulnerabilities found in ${files.length} files!`))
|
|
228
|
-
process.exit(0)
|
|
227
|
+
console.log(chalk.green(`No XSS vulnerabilities found in ${files.length} files!`))
|
|
228
|
+
process.exit(0)
|
|
229
229
|
}
|
package/src/errors.ts
CHANGED
|
@@ -5,7 +5,7 @@ function createError(code: number, message: string) {
|
|
|
5
5
|
process.env.INTERNAL_DISABLE_URL_DOCS !== 'true'
|
|
6
6
|
? `${message}\nSee https://html.kitajs.org/TS${code}`
|
|
7
7
|
: message
|
|
8
|
-
}
|
|
8
|
+
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
// 88600 is the base code for all errors in this plugin.
|
|
@@ -16,19 +16,19 @@ function createError(code: number, message: string) {
|
|
|
16
16
|
export const Xss = createError(
|
|
17
17
|
88601,
|
|
18
18
|
`Content may introduce an XSS vulnerability and must be marked with the \`safe\` attribute.`
|
|
19
|
-
)
|
|
19
|
+
)
|
|
20
20
|
|
|
21
21
|
export const DoubleEscape = createError(
|
|
22
22
|
88602,
|
|
23
23
|
`The \`safe\` attribute causes this content to be escaped more than once.`
|
|
24
|
-
)
|
|
24
|
+
)
|
|
25
25
|
|
|
26
26
|
export const ComponentXss = createError(
|
|
27
27
|
88603,
|
|
28
28
|
`Content inside a Component must be escaped using escapeHtml().`
|
|
29
|
-
)
|
|
29
|
+
)
|
|
30
30
|
|
|
31
31
|
export const UnusedSafe = createError(
|
|
32
32
|
88604,
|
|
33
33
|
`The \`safe\` attribute is unused in this context.`
|
|
34
|
-
)
|
|
34
|
+
)
|
package/src/index.ts
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
import type { default as TS, server } from 'typescript/lib/tsserverlibrary'
|
|
2
|
-
import { proxyObject, recursiveDiagnoseJsxElements } from './util'
|
|
1
|
+
import type { default as TS, server } from 'typescript/lib/tsserverlibrary'
|
|
2
|
+
import { proxyObject, recursiveDiagnoseJsxElements } from './util'
|
|
3
3
|
|
|
4
4
|
export = function (modules: { typescript: typeof TS }) {
|
|
5
|
-
const ts = modules.typescript
|
|
5
|
+
const ts = modules.typescript
|
|
6
6
|
|
|
7
7
|
return {
|
|
8
8
|
create(info: Pick<server.PluginCreateInfo, 'languageService'>) {
|
|
9
|
-
const proxy = proxyObject(info.languageService)
|
|
9
|
+
const proxy = proxyObject(info.languageService)
|
|
10
10
|
|
|
11
11
|
proxy.getSemanticDiagnostics = function clonedSemanticDiagnostics(filename) {
|
|
12
|
-
const diagnostics = info.languageService.getSemanticDiagnostics(filename)
|
|
12
|
+
const diagnostics = info.languageService.getSemanticDiagnostics(filename)
|
|
13
13
|
|
|
14
14
|
// Not a tsx file, so don't do anything
|
|
15
15
|
if (!filename.endsWith('.tsx') && !filename.endsWith('.jsx')) {
|
|
16
|
-
return diagnostics
|
|
16
|
+
return diagnostics
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const program = info.languageService.getProgram()
|
|
19
|
+
const program = info.languageService.getProgram()
|
|
20
20
|
|
|
21
21
|
if (!program) {
|
|
22
|
-
return diagnostics
|
|
22
|
+
return diagnostics
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
const source = program.getSourceFile(filename)
|
|
25
|
+
const source = program.getSourceFile(filename)
|
|
26
26
|
|
|
27
27
|
if (!source) {
|
|
28
|
-
return diagnostics
|
|
28
|
+
return diagnostics
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const typeChecker = program.getTypeChecker()
|
|
31
|
+
const typeChecker = program.getTypeChecker()
|
|
32
32
|
|
|
33
33
|
ts.forEachChild(source, function loopSourceNodes(node) {
|
|
34
|
-
recursiveDiagnoseJsxElements(ts, node, typeChecker, diagnostics)
|
|
35
|
-
})
|
|
34
|
+
recursiveDiagnoseJsxElements(ts, node, typeChecker, diagnostics)
|
|
35
|
+
})
|
|
36
36
|
|
|
37
|
-
return diagnostics
|
|
38
|
-
}
|
|
37
|
+
return diagnostics
|
|
38
|
+
}
|
|
39
39
|
|
|
40
|
-
return proxy
|
|
40
|
+
return proxy
|
|
41
41
|
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
42
|
+
}
|
|
43
|
+
}
|
package/src/util.ts
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
type JsxFragment,
|
|
3
3
|
type JsxSelfClosingElement,
|
|
4
4
|
type default as ts
|
|
5
|
-
} from 'typescript'
|
|
5
|
+
} from 'typescript'
|
|
6
6
|
import type {
|
|
7
7
|
BinaryOperatorToken,
|
|
8
8
|
Diagnostic,
|
|
@@ -12,11 +12,11 @@ import type {
|
|
|
12
12
|
default as TS,
|
|
13
13
|
Type,
|
|
14
14
|
TypeChecker
|
|
15
|
-
} from 'typescript/lib/tsserverlibrary'
|
|
16
|
-
import * as Errors from './errors'
|
|
15
|
+
} from 'typescript/lib/tsserverlibrary'
|
|
16
|
+
import * as Errors from './errors'
|
|
17
17
|
|
|
18
|
-
const UPPERCASE = /[A-Z]
|
|
19
|
-
const ESCAPE_HTML_REGEX = /^(\w+\.)?(escapeHtml|e\s*`|escape)/i
|
|
18
|
+
const UPPERCASE = /[A-Z]/
|
|
19
|
+
const ESCAPE_HTML_REGEX = /^(\w+\.)?(escapeHtml|e\s*`|escape)/i
|
|
20
20
|
|
|
21
21
|
/** If the node is a JSX element or fragment */
|
|
22
22
|
function isJsx(
|
|
@@ -25,7 +25,7 @@ function isJsx(
|
|
|
25
25
|
): node is JsxElement | JsxFragment | JsxSelfClosingElement {
|
|
26
26
|
return (
|
|
27
27
|
ts.isJsxElement(node) || ts.isJsxFragment(node) || ts.isJsxSelfClosingElement(node)
|
|
28
|
-
)
|
|
28
|
+
)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export function recursiveDiagnoseJsxElements(
|
|
@@ -36,14 +36,14 @@ export function recursiveDiagnoseJsxElements(
|
|
|
36
36
|
) {
|
|
37
37
|
ts.forEachChild(node, function loopSourceNodes(node) {
|
|
38
38
|
// Recurse through children first
|
|
39
|
-
ts.forEachChild(node, loopSourceNodes)
|
|
39
|
+
ts.forEachChild(node, loopSourceNodes)
|
|
40
40
|
|
|
41
41
|
// Adds children to the array
|
|
42
42
|
if (isJsx(ts, node)) {
|
|
43
43
|
// Diagnose the node
|
|
44
|
-
diagnoseJsxElement(ts, node, typeChecker, original)
|
|
44
|
+
diagnoseJsxElement(ts, node, typeChecker, original)
|
|
45
45
|
}
|
|
46
|
-
})
|
|
46
|
+
})
|
|
47
47
|
|
|
48
48
|
// Filter out duplicates
|
|
49
49
|
for (let i = 0; i < original.length; i++) {
|
|
@@ -52,7 +52,7 @@ export function recursiveDiagnoseJsxElements(
|
|
|
52
52
|
original[i]!.start === original[j]!.start &&
|
|
53
53
|
original[i]!.length === original[j]!.length
|
|
54
54
|
) {
|
|
55
|
-
original.splice(j--, 1)
|
|
55
|
+
original.splice(j--, 1)
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -71,7 +71,7 @@ function diagnostic(
|
|
|
71
71
|
file: node.getSourceFile(),
|
|
72
72
|
length: node.getWidth(),
|
|
73
73
|
start: node.getStart()
|
|
74
|
-
}
|
|
74
|
+
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
export function diagnoseJsxElement(
|
|
@@ -84,10 +84,10 @@ export function diagnoseJsxElement(
|
|
|
84
84
|
if (ts.isJsxElement(node)) {
|
|
85
85
|
// Script tags should be ignored
|
|
86
86
|
if (node.openingElement.tagName.getText() === 'script') {
|
|
87
|
-
return
|
|
87
|
+
return
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
const safeAttribute = getSafeAttribute(node.openingElement)
|
|
90
|
+
const safeAttribute = getSafeAttribute(node.openingElement)
|
|
91
91
|
|
|
92
92
|
// Safe mode warnings
|
|
93
93
|
if (safeAttribute && node.children) {
|
|
@@ -97,8 +97,8 @@ export function diagnoseJsxElement(
|
|
|
97
97
|
// Only text elements
|
|
98
98
|
(node.children.length === 1 && node.children[0]!.kind === ts.SyntaxKind.JsxText)
|
|
99
99
|
) {
|
|
100
|
-
diagnostics.push(diagnostic(ts, safeAttribute, 'UnusedSafe', 'Warning'))
|
|
101
|
-
return
|
|
100
|
+
diagnostics.push(diagnostic(ts, safeAttribute, 'UnusedSafe', 'Warning'))
|
|
101
|
+
return
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
for (const exp of node.children) {
|
|
@@ -108,8 +108,8 @@ export function diagnoseJsxElement(
|
|
|
108
108
|
// Element is using safe with escapeHtml
|
|
109
109
|
(ts.isJsxExpression(exp) && exp.expression?.getText().match(ESCAPE_HTML_REGEX))
|
|
110
110
|
) {
|
|
111
|
-
diagnostics.push(diagnostic(ts, safeAttribute, 'DoubleEscape', 'Error'))
|
|
112
|
-
continue
|
|
111
|
+
diagnostics.push(diagnostic(ts, safeAttribute, 'DoubleEscape', 'Error'))
|
|
112
|
+
continue
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
// Warn on unnecessary safe attributes
|
|
@@ -119,12 +119,12 @@ export function diagnoseJsxElement(
|
|
|
119
119
|
exp.expression
|
|
120
120
|
) {
|
|
121
121
|
// gets this expression or array of sub expressions
|
|
122
|
-
const expressions = getNodeExpressions(ts, exp.expression) || [exp.expression]
|
|
122
|
+
const expressions = getNodeExpressions(ts, exp.expression) || [exp.expression]
|
|
123
123
|
|
|
124
124
|
// at least one jsx inside another jsx with safe (includes self-closing elements)
|
|
125
125
|
if (expressions.some((inner) => isJsx(ts, inner))) {
|
|
126
|
-
diagnostics.push(diagnostic(ts, safeAttribute, 'DoubleEscape', 'Error'))
|
|
127
|
-
continue
|
|
126
|
+
diagnostics.push(diagnostic(ts, safeAttribute, 'DoubleEscape', 'Error'))
|
|
127
|
+
continue
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
// all of them must be safe
|
|
@@ -138,30 +138,30 @@ export function diagnoseJsxElement(
|
|
|
138
138
|
)
|
|
139
139
|
)
|
|
140
140
|
) {
|
|
141
|
-
diagnostics.push(diagnostic(ts, safeAttribute, 'UnusedSafe', 'Warning'))
|
|
141
|
+
diagnostics.push(diagnostic(ts, safeAttribute, 'UnusedSafe', 'Warning'))
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
return
|
|
146
|
+
return
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
// If this expression does not have children, we can ignore it
|
|
151
151
|
// for example it could be a self closing element
|
|
152
152
|
if (ts.isJsxSelfClosingElement(node) || !node.children) {
|
|
153
|
-
return
|
|
153
|
+
return
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
// Look for expressions
|
|
157
157
|
for (const exp of node.children) {
|
|
158
158
|
if (!ts.isJsxExpression(exp)) {
|
|
159
|
-
continue
|
|
159
|
+
continue
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
// Should always have an expression
|
|
163
163
|
if (!exp.expression) {
|
|
164
|
-
continue
|
|
164
|
+
continue
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
diagnoseExpression(
|
|
@@ -170,10 +170,10 @@ export function diagnoseJsxElement(
|
|
|
170
170
|
typeChecker,
|
|
171
171
|
diagnostics,
|
|
172
172
|
ts.isJsxElement(node) && !!node.openingElement.tagName.getText().match(UPPERCASE)
|
|
173
|
-
)
|
|
173
|
+
)
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
return
|
|
176
|
+
return
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
function diagnoseExpression(
|
|
@@ -185,58 +185,58 @@ function diagnoseExpression(
|
|
|
185
185
|
): void {
|
|
186
186
|
// Unwrap parenthesis
|
|
187
187
|
if (ts.isParenthesizedExpression(node)) {
|
|
188
|
-
node = node.expression
|
|
188
|
+
node = node.expression
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
// Ignores JSX elements as they are already diagnosed by the loopChildNodes
|
|
192
192
|
if (isJsx(ts, node)) {
|
|
193
|
-
return
|
|
193
|
+
return
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
const expressions = getNodeExpressions(ts, node)
|
|
196
|
+
const expressions = getNodeExpressions(ts, node)
|
|
197
197
|
|
|
198
198
|
// ternary or binary expressions should be evaluated on each side
|
|
199
199
|
if (expressions) {
|
|
200
200
|
for (const inner of expressions) {
|
|
201
|
-
diagnoseExpression(ts, inner, typeChecker, diagnostics, isComponent)
|
|
201
|
+
diagnoseExpression(ts, inner, typeChecker, diagnostics, isComponent)
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
return
|
|
204
|
+
return
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
const type = typeChecker.getTypeAtLocation(node)
|
|
207
|
+
const type = typeChecker.getTypeAtLocation(node)
|
|
208
208
|
|
|
209
209
|
// Safe can be ignored
|
|
210
210
|
if (isSafeAttribute(ts, type, typeChecker, node)) {
|
|
211
|
-
return
|
|
211
|
+
return
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
// Anything other than a identifier should be diagnosed
|
|
215
215
|
if (!ts.isIdentifier(node)) {
|
|
216
|
-
let hadJsx = false
|
|
216
|
+
let hadJsx = false
|
|
217
217
|
|
|
218
218
|
for (const tag of node.getChildren()) {
|
|
219
219
|
if (!isJsx(ts, tag)) {
|
|
220
|
-
continue
|
|
220
|
+
continue
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
hadJsx = true
|
|
223
|
+
hadJsx = true
|
|
224
224
|
|
|
225
|
-
diagnoseJsxElement(ts, tag, typeChecker, diagnostics)
|
|
225
|
+
diagnoseJsxElement(ts, tag, typeChecker, diagnostics)
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
// If root JSX element found inside array, diagnose it,
|
|
229
229
|
// otherwise let the diagnostic pass
|
|
230
230
|
if (hadJsx) {
|
|
231
|
-
return
|
|
231
|
+
return
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
// Switch between component and element xss errors
|
|
236
236
|
if (isComponent || ts.isJsxFragment(node)) {
|
|
237
|
-
diagnostics.push(diagnostic(ts, node, 'ComponentXss', 'Error'))
|
|
237
|
+
diagnostics.push(diagnostic(ts, node, 'ComponentXss', 'Error'))
|
|
238
238
|
} else {
|
|
239
|
-
diagnostics.push(diagnostic(ts, node, 'Xss', 'Error'))
|
|
239
|
+
diagnostics.push(diagnostic(ts, node, 'Xss', 'Error'))
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
242
|
|
|
@@ -248,26 +248,26 @@ export function isSafeAttribute(
|
|
|
248
248
|
): boolean {
|
|
249
249
|
// Nothing to do if type cannot be resolved
|
|
250
250
|
if (!type) {
|
|
251
|
-
return true
|
|
251
|
+
return true
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
// Check if this is a property access to .children (from PropsWithChildren)
|
|
255
255
|
// This must be checked BEFORE union recursion to avoid false positives
|
|
256
256
|
if (ts.isPropertyAccessExpression(node) && node.name.text === 'children') {
|
|
257
|
-
return true
|
|
257
|
+
return true
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
// Consolidated identifier checks - MUST be before union recursion
|
|
261
261
|
if (ts.isIdentifier(node)) {
|
|
262
262
|
// Destructured or direct `children` parameter (e.g., function Test({ children }: PropsWithChildren))
|
|
263
263
|
if (node.text === 'children') {
|
|
264
|
-
return true
|
|
264
|
+
return true
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
// Check if variable is initialized with JSX (e.g., const element = <div />)
|
|
268
|
-
const symbol = checker.getSymbolAtLocation(node)
|
|
268
|
+
const symbol = checker.getSymbolAtLocation(node)
|
|
269
269
|
if (symbol) {
|
|
270
|
-
const declarations = symbol.getDeclarations()
|
|
270
|
+
const declarations = symbol.getDeclarations()
|
|
271
271
|
if (declarations) {
|
|
272
272
|
for (const decl of declarations) {
|
|
273
273
|
if (
|
|
@@ -275,7 +275,7 @@ export function isSafeAttribute(
|
|
|
275
275
|
decl.initializer &&
|
|
276
276
|
isJsx(ts, decl.initializer)
|
|
277
277
|
) {
|
|
278
|
-
return true
|
|
278
|
+
return true
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
281
|
}
|
|
@@ -284,7 +284,7 @@ export function isSafeAttribute(
|
|
|
284
284
|
|
|
285
285
|
// Any type is never safe
|
|
286
286
|
if (type.flags & ts.TypeFlags.Any) {
|
|
287
|
-
return false
|
|
287
|
+
return false
|
|
288
288
|
}
|
|
289
289
|
|
|
290
290
|
// Check type aliases for JSX.Element and Html.Children
|
|
@@ -298,7 +298,7 @@ export function isSafeAttribute(
|
|
|
298
298
|
// Only allows in .map(), other method calls or the expression itself
|
|
299
299
|
(ts.isCallExpression(node) || ts.isIdentifier(node))
|
|
300
300
|
) {
|
|
301
|
-
return true
|
|
301
|
+
return true
|
|
302
302
|
}
|
|
303
303
|
|
|
304
304
|
// Allows Html.Children
|
|
@@ -317,25 +317,25 @@ export function isSafeAttribute(
|
|
|
317
317
|
// @ts-expect-error - When using export as namespace X, parent.escapedName ends up
|
|
318
318
|
type.aliasSymbol.parent?.escapedName.endsWith('packages/html/index"')))
|
|
319
319
|
) {
|
|
320
|
-
return true
|
|
320
|
+
return true
|
|
321
321
|
}
|
|
322
322
|
}
|
|
323
323
|
|
|
324
324
|
// Union types should be checked recursively
|
|
325
325
|
if (type.isUnionOrIntersection()) {
|
|
326
|
-
return type.types.every((innerType) => isSafeAttribute(ts, innerType, checker, node))
|
|
326
|
+
return type.types.every((innerType) => isSafeAttribute(ts, innerType, checker, node))
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
// For Array or Promise, we check the type of the first generic
|
|
330
330
|
if (checker.isArrayType(type) || type.symbol?.escapedName === 'Promise') {
|
|
331
|
-
return isSafeAttribute(ts, (type as any).resolvedTypeArguments?.[0], checker, node)
|
|
331
|
+
return isSafeAttribute(ts, (type as any).resolvedTypeArguments?.[0], checker, node)
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
-
const text = node.getText()
|
|
334
|
+
const text = node.getText()
|
|
335
335
|
|
|
336
336
|
// manual unsafe variables should not pass
|
|
337
337
|
if (text.startsWith('unsafe')) {
|
|
338
|
-
return false
|
|
338
|
+
return false
|
|
339
339
|
}
|
|
340
340
|
|
|
341
341
|
// We allow literal string types here, as if they have XSS content,
|
|
@@ -346,7 +346,7 @@ export function isSafeAttribute(
|
|
|
346
346
|
// Objects may have toString() overridden
|
|
347
347
|
!(type.flags & ts.TypeFlags.Object)
|
|
348
348
|
) {
|
|
349
|
-
return true
|
|
349
|
+
return true
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
if (
|
|
@@ -355,32 +355,32 @@ export function isSafeAttribute(
|
|
|
355
355
|
// Starts with a call to a escapeHtml function name
|
|
356
356
|
text.match(ESCAPE_HTML_REGEX)
|
|
357
357
|
) {
|
|
358
|
-
return true
|
|
358
|
+
return true
|
|
359
359
|
}
|
|
360
360
|
|
|
361
|
-
return false
|
|
361
|
+
return false
|
|
362
362
|
}
|
|
363
363
|
|
|
364
364
|
export function getSafeAttribute(element: JsxOpeningElement) {
|
|
365
365
|
for (const attribute of element.attributes.properties) {
|
|
366
366
|
if (attribute.getText() === 'safe') {
|
|
367
|
-
return attribute
|
|
367
|
+
return attribute
|
|
368
368
|
}
|
|
369
369
|
}
|
|
370
370
|
|
|
371
|
-
return undefined
|
|
371
|
+
return undefined
|
|
372
372
|
}
|
|
373
373
|
|
|
374
374
|
export function proxyObject<T extends object>(obj: T): T {
|
|
375
|
-
const proxy: T = Object.create(null)
|
|
375
|
+
const proxy: T = Object.create(null)
|
|
376
376
|
|
|
377
377
|
for (const k of Object.keys(obj) as Array<keyof T>) {
|
|
378
|
-
const x = obj[k]
|
|
378
|
+
const x = obj[k]!
|
|
379
379
|
// @ts-expect-error - JS runtime trickery which is tricky to type tersely
|
|
380
|
-
proxy[k] = (...args: Array<{}>) => x.apply(obj, args)
|
|
380
|
+
proxy[k] = (...args: Array<{}>) => x.apply(obj, args)
|
|
381
381
|
}
|
|
382
382
|
|
|
383
|
-
return proxy
|
|
383
|
+
return proxy
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
/**
|
|
@@ -395,28 +395,28 @@ function getNodeExpressions(
|
|
|
395
395
|
if (ts.isBinaryExpression(node)) {
|
|
396
396
|
// Ignores operations which results in a boolean
|
|
397
397
|
if (isBooleanBinaryOperatorToken(ts, node.operatorToken)) {
|
|
398
|
-
return []
|
|
398
|
+
return []
|
|
399
399
|
}
|
|
400
400
|
|
|
401
401
|
// For && operator, the left side is only rendered when falsy
|
|
402
402
|
// (empty string, null, undefined, 0, false, NaN) - none of which are XSS risks
|
|
403
403
|
// So we only need to diagnose the right side
|
|
404
404
|
if (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
405
|
-
return [node.right]
|
|
405
|
+
return [node.right]
|
|
406
406
|
}
|
|
407
407
|
|
|
408
408
|
// For || and ?? operators, both sides can be rendered with potentially unsafe values
|
|
409
409
|
// So we diagnose both sides
|
|
410
|
-
return [node.left, node.right]
|
|
410
|
+
return [node.left, node.right]
|
|
411
411
|
}
|
|
412
412
|
|
|
413
413
|
// Checks the inner expression
|
|
414
414
|
if (ts.isConditionalExpression(node)) {
|
|
415
415
|
// ignore node.condition because its value will never be rendered
|
|
416
|
-
return [node.whenTrue, node.whenFalse]
|
|
416
|
+
return [node.whenTrue, node.whenFalse]
|
|
417
417
|
}
|
|
418
418
|
|
|
419
|
-
return undefined
|
|
419
|
+
return undefined
|
|
420
420
|
}
|
|
421
421
|
|
|
422
422
|
function isBooleanBinaryOperatorToken(ts: typeof TS, operator: BinaryOperatorToken) {
|
|
@@ -431,8 +431,8 @@ function isBooleanBinaryOperatorToken(ts: typeof TS, operator: BinaryOperatorTok
|
|
|
431
431
|
case ts.SyntaxKind.LessThanToken:
|
|
432
432
|
case ts.SyntaxKind.InstanceOfKeyword:
|
|
433
433
|
case ts.SyntaxKind.InKeyword:
|
|
434
|
-
return true
|
|
434
|
+
return true
|
|
435
435
|
}
|
|
436
436
|
|
|
437
|
-
return false
|
|
437
|
+
return false
|
|
438
438
|
}
|