JS: add some parsed torrent properties as remote flow sources

This commit is contained in:
Esben Sparre Andreasen
2019-11-13 15:23:53 +01:00
parent 08620046ab
commit bea59ec8ad
10 changed files with 101 additions and 0 deletions

View File

@@ -90,6 +90,7 @@ import semmle.javascript.frameworks.SystemCommandExecutors
import semmle.javascript.frameworks.SQL
import semmle.javascript.frameworks.SocketIO
import semmle.javascript.frameworks.StringFormatters
import semmle.javascript.frameworks.TorrentLibraries
import semmle.javascript.frameworks.UriLibraries
import semmle.javascript.frameworks.Vue
import semmle.javascript.frameworks.XmlParsers

View File

@@ -0,0 +1,61 @@
/**
* Provides classes for modelling Torrent libraries.
*/
import javascript
/**
* Provides classes for working with [parse-torrent](https://github.com/webtorrent/parse-torrent) code.
*/
module ParseTorrent {
private DataFlow::SourceNode mod() { result = DataFlow::moduleImport("parse-torrent") }
/**
* A torrent that has been parsed into a JavaScript object.
*/
class ParsedTorrent extends DataFlow::SourceNode {
ParsedTorrent() {
this = mod().getACall() or
this = mod().getAMemberCall("remote").getCallback(1).getParameter(1)
}
}
private DataFlow::SourceNode parsedTorrentRef(DataFlow::TypeTracker t) {
t.start() and
result instanceof ParsedTorrent
or
exists(DataFlow::TypeTracker t2 | result = parsedTorrentRef(t2).track(t2, t))
}
/** Gets a data flow node referring to a parsed torrent. */
DataFlow::SourceNode parsedTorrentRef() {
result = parsedTorrentRef(DataFlow::TypeTracker::end())
}
/**
* An access to user-controlled torrent information.
*/
class UserControlledTorrentInfo extends RemoteFlowSource {
UserControlledTorrentInfo() {
exists(DataFlow::SourceNode ref, DataFlow::PropRead read |
ref = parsedTorrentRef() and
read = ref.getAPropertyRead() and
this = read
|
exists(string prop |
not (
prop = "private" or
prop = "infoHash" or
prop = "length"
// "pieceLength" and "lastPieceLength" are not guaranteed to be numbers as of commit ae3ad15d
) and
read.getPropertyName() = prop
)
or
not exists(read.getPropertyName())
)
}
override string getSourceType() { result = "torrent information" }
}
}

View File

@@ -0,0 +1 @@
| tst.js:4:15:4:28 | parseTorrent() |

View File

@@ -0,0 +1,3 @@
import javascript
select any(ParseTorrent::ParsedTorrent t)

View File

@@ -0,0 +1,4 @@
| tst.js:6:2:6:12 | parsed.name |
| tst.js:8:2:8:19 | parsed.pieceLength |
| tst.js:14:2:14:25 | indirec ... ed.name |
| tst.js:20:2:20:7 | t.name |

View File

@@ -0,0 +1,3 @@
import javascript
select any(ParseTorrent::UserControlledTorrentInfo i)

View File

@@ -0,0 +1,3 @@
| tst.js:4:15:4:28 | parseTorrent() |
| tst.js:14:2:14:20 | indirection1.parsed |
| tst.js:19:23:19:23 | t |

View File

@@ -0,0 +1,3 @@
import javascript
select ParseTorrent::parsedTorrentRef()

View File

@@ -0,0 +1,21 @@
const parseTorrent = require('parse-torrent');
(function(){
let parsed = parseTorrent();
parsed.name;
parsed.length;
parsed.pieceLength;
let indirection1 = {
parsed: parsed
};
indirection1.parsed.name;
indirection2(parsed);
});
function indirection2(t) {
t.name;
}