Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6722c17

Browse files
author
Stephan Brandauer
committed
JS: Functionality from untrusted sources query (CWE-830)
1 parent e42f759 commit 6722c17

6 files changed

Lines changed: 138 additions & 0 deletions

File tree

javascript/ql/lib/semmle/javascript/HTML.qll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,24 @@ module HTML {
173173
DocumentElement() { getName() = "html" }
174174
}
175175

176+
/**
177+
* An HTML `<iframe>` element.
178+
*
179+
* Example:
180+
*
181+
* ```
182+
* <iframe src="https://test.local/somepage.html"></iframe>
183+
* ```
184+
*/
185+
class IframeElement extends Element {
186+
IframeElement() { getName() = "iframe" }
187+
188+
/**
189+
* Gets the value of the `src` attribute.
190+
*/
191+
string getSourcePath() { result = getAttributeByName("src").getValue() }
192+
}
193+
176194
/**
177195
* An HTML `<script>` element.
178196
*
@@ -207,6 +225,11 @@ module HTML {
207225
*/
208226
string getSourcePath() { result = getAttributeByName("src").getValue() }
209227

228+
/**
229+
* Gets the value of the `integrity` attribute.
230+
*/
231+
string getIntegrityDigest() { result = getAttributeByName("integrity").getValue() }
232+
210233
/**
211234
* Gets the folder relative to which the `src` attribute is resolved.
212235
*/
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>
7+
8+
Including functionality from an external source via an http link may
9+
allow an attacker to inject malicious code via a MITM (man-in-the-middle) attack.
10+
11+
</p>
12+
13+
</overview>
14+
15+
<recommendation>
16+
<p>
17+
18+
When including external pages or behaviour, use <em>https</em> links (instead of http)
19+
to be certain that you are getting a response from the intended server, not
20+
someone else.
21+
22+
</p>
23+
24+
<p>
25+
26+
Using http links is unsafe because the request sent may be intercepted by an attacker,
27+
and malicious data may be sent back in reply.
28+
29+
</p>
30+
31+
</recommendation>
32+
33+
<references>
34+
35+
<li>
36+
37+
MDN — Subresource Integrity: <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity">
38+
39+
</li>
40+
</references>
41+
</qhelp>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* @name Inclusion of untrusted functionality by a HTML element.
3+
* @description Including untrusted functionality by a HTML element
4+
* opens up for potential man-in-the-middle attacks.
5+
* @kind problem
6+
* @problem.severity warning
7+
* @security-severity 8.1
8+
* @precision high
9+
* @id js/functionality-from-untrusted-source
10+
* @tags security
11+
* external/cwe/cwe-830
12+
*/
13+
14+
import javascript
15+
import semmle.javascript.HTML
16+
17+
bindingset[host]
18+
predicate isAllowedHost(string host) { host.toLowerCase().regexpMatch("localhost(:[0-9]+)?/.*") }
19+
20+
bindingset[path]
21+
predicate isUntrustedSourcePath(string path) {
22+
path.substring(0, 2) = "//"
23+
or
24+
exists(string hostPath | hostPath = path.regexpCapture("http://(.*)", 1) |
25+
not isAllowedHost(hostPath)
26+
)
27+
}
28+
29+
abstract class IncludesUntrustedContent extends HTML::Element {
30+
IncludesUntrustedContent() { this = this }
31+
32+
/** Gets an explanation why this source is untrusted. */
33+
abstract string getProblem();
34+
}
35+
36+
/** A script element that refers to untrusted content. */
37+
class ScriptElementWithUntrustedContent extends IncludesUntrustedContent, HTML::ScriptElement {
38+
ScriptElementWithUntrustedContent() {
39+
isUntrustedSourcePath(this.getSourcePath()) and
40+
not exists(string digest | not digest = "" | this.getIntegrityDigest() = digest)
41+
}
42+
43+
override string getProblem() {
44+
result = "script elements should use an https link and/or use the integrity attribute"
45+
}
46+
}
47+
48+
/** An iframe element that includes untrusted content. */
49+
class IframeElementWithUntrustedContent extends HTML::IframeElement, IncludesUntrustedContent {
50+
IframeElementWithUntrustedContent() { isUntrustedSourcePath(this.getSourcePath()) }
51+
52+
override string getProblem() { result = "iframe elements should use an https link" }
53+
}
54+
55+
from IncludesUntrustedContent s, string problem
56+
where problem = s.getProblem()
57+
select s, "HTML-element imports untrusted content (" + problem + ")"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| test.html:6:9:6:56 | <script>...</> | HTML-element imports untrusted content (script elements should use an https link and/or use the integrity attribute) |
2+
| test.html:9:9:9:58 | <iframe>...</> | HTML-element imports untrusted content (iframe elements should use an https link) |
3+
| test.html:11:9:11:53 | <iframe>...</> | HTML-element imports untrusted content (iframe elements should use an https link) |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Security/CWE-830/FunctionalityFromUntrustedSource.ql
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
</head>
5+
<body>
6+
<script src="http://test.local/foo.js"></script>> <!-- NOT OK -->
7+
<script src="http://test.local/foo.js" integrity="some-integrity-hash"></script>> <!-- OK (integrity digest present) -->
8+
<script src="https://test.local/bar.js"></script>> <!-- OK (https) -->
9+
<iframe src="http://test.local/foo.html"></iframe> <!-- NOT OK -->
10+
<iframe src="https://test.local/foo.html"></iframe> <!-- OK (https) -->
11+
<iframe src="//test.local/foo.html"></iframe> <!-- NOT OK (protocol-relative url) -->
12+
</body>
13+
</html>

0 commit comments

Comments
 (0)