Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit 8bcde56

Browse files
committed
[feat] added tsr-detect-unsafe-cross-origin-communication rule
1 parent 3e9516e commit 8bcde56

File tree

5 files changed

+59
-1
lines changed

5 files changed

+59
-1
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,17 @@ db.query('SELECT * FROM `books` WHERE `author` = ?', ['David'], function (error,
191191
```
192192

193193
More examples: [test/rules/tsr-detect-sql-literal-injection/default/test.ts.lint](test/rules/tsr-detect-sql-literal-injection/default/test.ts.lint)
194+
195+
#### `tsr-detect-unsafe-cross-origin-communication`
196+
197+
Detects when all windows & frames on your page (including ones that were injected by 3rd-party scripts)
198+
may receive your data.
199+
200+
> Always provide a specific targetOrigin, not *, if you know where the other window's document should be located. Failing to provide a specific target discloses the data you send to any interested malicious site.
201+
> https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
202+
203+
```js
204+
const myWindow = document.getElementById('myIFrame').contentWindow;
205+
206+
myWindow.postMessage(message, "*"); // Noncompliant
207+
```

index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module.exports = {
1414
'tsr-detect-unsafe-regexp': [true],
1515
'tsr-disable-mustache-escape': [true],
1616
'tsr-detect-html-injection': [true],
17-
'tsr-detect-sql-literal-injection': [true]
17+
'tsr-detect-sql-literal-injection': [true],
18+
'tsr-detect-unsafe-cross-origin-communication': [true]
1819
}
1920
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import * as ts from 'typescript';
2+
import * as Lint from 'tslint';
3+
4+
export class Rule extends Lint.Rules.AbstractRule {
5+
apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
6+
return this.applyWithWalker(new RuleWalker(sourceFile, this.getOptions()));
7+
}
8+
}
9+
10+
class RuleWalker extends Lint.RuleWalker {
11+
visitCallExpression(node: ts.CallExpression) {
12+
const {name} = node.expression as ts.PropertyAccessExpression;
13+
const [, targetOrigin]: ts.NodeArray<ts.Expression> = node.arguments || [];
14+
15+
if (
16+
name &&
17+
targetOrigin &&
18+
name.getText() === 'postMessage' &&
19+
((targetOrigin as ts.StringLiteral).text || '').trim() === '*'
20+
) {
21+
this.addFailureAtNode(node, 'Found a wildcard keyword (*) in the targetOrigin argument');
22+
}
23+
24+
super.visitCallExpression(node);
25+
}
26+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const myWindow = document.getElementById('myIFrame').contentWindow;
2+
3+
myWindow.postMessage(message, "*");
4+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Found a wildcard keyword (*) in the targetOrigin argument]
5+
myWindow.postMessage(message, '*');
6+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Found a wildcard keyword (*) in the targetOrigin argument]
7+
myWindow.postMessage(message, ' *');
8+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Found a wildcard keyword (*) in the targetOrigin argument]
9+
myWindow.postMessage(message, `*`);
10+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Found a wildcard keyword (*) in the targetOrigin argument]
11+
myWindow.postMessage(message, "http://example.com");
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"rulesDirectory": "../../../../dist/rules",
3+
"rules": {
4+
"tsr-detect-unsafe-cross-origin-communication": true
5+
}
6+
}

0 commit comments

Comments
 (0)