Skip to content

Commit 22dfe84

Browse files
committed
add xss sink for react-tooltip
1 parent fb57c5f commit 22dfe84

File tree

5 files changed

+60
-0
lines changed

5 files changed

+60
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
lgtm,codescanning
2+
* The XSS queries now recognize when the `react-tooltip` library is being used with HTML.
3+
Affected packages are
4+
[react-tooltip](https://npmjs.com/package/react-tooltip)

javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,20 @@ module DomBasedXss {
318318
}
319319
}
320320

321+
/**
322+
* A React tooltip where the `data-html` attribute is set to `true`.
323+
*/
324+
class TooltipSink extends Sink {
325+
TooltipSink() {
326+
exists(JSXElement el |
327+
el.getAttributeByName("data-html").getStringValue() = "true" or
328+
el.getAttributeByName("data-html").getValue().mayHaveBooleanValue(true)
329+
|
330+
this = el.getAttributeByName("data-tip").getValue().flow()
331+
)
332+
}
333+
}
334+
321335
/**
322336
* The HTML body of an email, viewed as an XSS sink.
323337
*/

javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,13 @@ nodes
374374
| string-manipulations.js:10:16:10:45 | String( ... n.href) |
375375
| string-manipulations.js:10:23:10:44 | documen ... on.href |
376376
| string-manipulations.js:10:23:10:44 | documen ... on.href |
377+
| tooltip.jsx:6:11:6:30 | source |
378+
| tooltip.jsx:6:20:6:30 | window.name |
379+
| tooltip.jsx:6:20:6:30 | window.name |
380+
| tooltip.jsx:10:25:10:30 | source |
381+
| tooltip.jsx:10:25:10:30 | source |
382+
| tooltip.jsx:11:25:11:30 | source |
383+
| tooltip.jsx:11:25:11:30 | source |
377384
| translate.js:6:7:6:39 | target |
378385
| translate.js:6:16:6:39 | documen ... .search |
379386
| translate.js:6:16:6:39 | documen ... .search |
@@ -1077,6 +1084,12 @@ edges
10771084
| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) |
10781085
| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) |
10791086
| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) |
1087+
| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source |
1088+
| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source |
1089+
| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source |
1090+
| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source |
1091+
| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source |
1092+
| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source |
10801093
| translate.js:6:7:6:39 | target | translate.js:7:42:7:47 | target |
10811094
| translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target |
10821095
| translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target |
@@ -1483,6 +1496,8 @@ edges
14831496
| string-manipulations.js:8:16:8:48 | documen ... mLeft() | string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | Cross-site scripting vulnerability due to $@. | string-manipulations.js:8:16:8:37 | documen ... on.href | user-provided value |
14841497
| string-manipulations.js:9:16:9:58 | String. ... n.href) | string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | Cross-site scripting vulnerability due to $@. | string-manipulations.js:9:36:9:57 | documen ... on.href | user-provided value |
14851498
| string-manipulations.js:10:16:10:45 | String( ... n.href) | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | Cross-site scripting vulnerability due to $@. | string-manipulations.js:10:23:10:44 | documen ... on.href | user-provided value |
1499+
| tooltip.jsx:10:25:10:30 | source | tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:10:25:10:30 | source | Cross-site scripting vulnerability due to $@. | tooltip.jsx:6:20:6:30 | window.name | user-provided value |
1500+
| tooltip.jsx:11:25:11:30 | source | tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:11:25:11:30 | source | Cross-site scripting vulnerability due to $@. | tooltip.jsx:6:20:6:30 | window.name | user-provided value |
14861501
| translate.js:9:27:9:50 | searchP ... 'term') | translate.js:6:16:6:39 | documen ... .search | translate.js:9:27:9:50 | searchP ... 'term') | Cross-site scripting vulnerability due to $@. | translate.js:6:16:6:39 | documen ... .search | user-provided value |
14871502
| tst3.js:4:25:4:32 | data.src | tst3.js:2:42:2:63 | window. ... .search | tst3.js:4:25:4:32 | data.src | Cross-site scripting vulnerability due to $@. | tst3.js:2:42:2:63 | window. ... .search | user-provided value |
14881503
| tst3.js:5:26:5:31 | data.p | tst3.js:2:42:2:63 | window. ... .search | tst3.js:5:26:5:31 | data.p | Cross-site scripting vulnerability due to $@. | tst3.js:2:42:2:63 | window. ... .search | user-provided value |

javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,13 @@ nodes
381381
| string-manipulations.js:10:16:10:45 | String( ... n.href) |
382382
| string-manipulations.js:10:23:10:44 | documen ... on.href |
383383
| string-manipulations.js:10:23:10:44 | documen ... on.href |
384+
| tooltip.jsx:6:11:6:30 | source |
385+
| tooltip.jsx:6:20:6:30 | window.name |
386+
| tooltip.jsx:6:20:6:30 | window.name |
387+
| tooltip.jsx:10:25:10:30 | source |
388+
| tooltip.jsx:10:25:10:30 | source |
389+
| tooltip.jsx:11:25:11:30 | source |
390+
| tooltip.jsx:11:25:11:30 | source |
384391
| translate.js:6:7:6:39 | target |
385392
| translate.js:6:16:6:39 | documen ... .search |
386393
| translate.js:6:16:6:39 | documen ... .search |
@@ -1101,6 +1108,12 @@ edges
11011108
| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) |
11021109
| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) |
11031110
| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) |
1111+
| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source |
1112+
| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:10:25:10:30 | source |
1113+
| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source |
1114+
| tooltip.jsx:6:11:6:30 | source | tooltip.jsx:11:25:11:30 | source |
1115+
| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source |
1116+
| tooltip.jsx:6:20:6:30 | window.name | tooltip.jsx:6:11:6:30 | source |
11041117
| translate.js:6:7:6:39 | target | translate.js:7:42:7:47 | target |
11051118
| translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target |
11061119
| translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target |
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import ReactTooltip from 'react-tooltip';
4+
5+
function tooltips() {
6+
const source = window.name;
7+
return <span>
8+
<span data-tip={source}/> // OK
9+
<span data-tip={source} data-html={false} /> // OK
10+
<span data-tip={source} data-html="true" /> // NOT OK
11+
<span data-tip={source} data-html={true} /> // NOT OK
12+
<ReactTooltip />
13+
</span>
14+
}

0 commit comments

Comments
 (0)