Skip to content

Commit f9b244e

Browse files
committed
Polish documentation
1 parent 68f79f0 commit f9b244e

13 files changed

+74
-1
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import jwt
2+
3+
# algorithm set to None
4+
jwt.encode(payload, "somekey", None)
5+
6+
# empty key
7+
jwt.encode(payload, key="", algorithm="HS256")
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Applications encoding a JSON Web Token (JWT) may be vulnerable when the applied key or algorithm
7+
is empty or None.</p>
8+
</overview>
9+
10+
<recommendation>
11+
<p>Use non-empty nor None values while encoding JWT payloads.</p>
12+
</recommendation>
13+
14+
<example>
15+
<p>This example shows two PyJWT encoding calls.
16+
17+
In the first place, the encoding process use a None algorithm whereas the second example uses an
18+
empty key. Both examples leave the payload insecurely encoded.
19+
</p>
20+
21+
<sample src="JWTEmptyKeyOrAlgorithm.py" />
22+
</example>
23+
24+
<references>
25+
<li>PyJWT: <a href="https://pyjwt.readthedocs.io/en/stable/">Documentation</a>.</li>
26+
<li>Authlib JWT: <a href="https://docs.authlib.org/en/latest/specs/rfc7519.html">Documentation</a>.</li>
27+
<li>Python-Jose: <a href="https://github.com/mpdavis/python-jose">Documentation</a>.</li>
28+
<li>Auth0 Blog: <a href="https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/#Meet-the--None--Algorithm">Meet the "None" Algorithm</a>.</li>
29+
</references>
30+
</qhelp>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import jwt
2+
3+
# unverified decoding
4+
jwt.decode(payload, key="somekey", verify=False)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Applications decoding a JSON Web Token (JWT) may be vulnerable when the
7+
key isn't verified in the process.
8+
</p>
9+
</overview>
10+
11+
<recommendation>
12+
<p>Set the <code>verify</code> argument to <code>True</code> or use
13+
a framework that does it by default.
14+
</p>
15+
</recommendation>
16+
17+
<example>
18+
<p>This example shows a PyJWT encoding call with the <code>verify</code>
19+
argument set to <code>False</code>.
20+
</p>
21+
22+
<sample src="JWTMissingSecretOrPublicKeyVerification.py" />
23+
</example>
24+
25+
<references>
26+
<li>PyJWT: <a href="https://pyjwt.readthedocs.io/en/stable/">Documentation</a>.</li>
27+
<li>Authlib JWT: <a href="https://docs.authlib.org/en/latest/specs/rfc7519.html">Documentation</a>.</li>
28+
<li>Python-Jose: <a href="https://github.com/mpdavis/python-jose">Documentation</a>.</li>
29+
</references>
30+
</qhelp>

python/ql/src/experimental/semmle/python/Concepts.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ class JWTEncoding extends DataFlow::Node {
213213
/** Provides classes for modeling JWT decoding-related APIs. */
214214
module JWTDecoding {
215215
/**
216-
* A data-flow node that collects functions escaping regular expressions.
216+
* A data-flow node that collects methods encoding a JWT token.
217217
*
218218
* Extend this class to model new APIs. If you want to refine existing API models,
219219
* extend `JWTDecoding` instead.

python/ql/src/experimental/semmle/python/libraries/PyJWT.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ private module PyJWT {
1313
/** Gets a reference to `jwt.decode` */
1414
private API::Node pyjwtDecode() { result = pyjwt().getMember("decode") }
1515

16+
// def encode(self, payload, key, algorithm="HS256", headers=None, json_encoder=None)
1617
private class PyJWTEncodeCall extends DataFlow::CallCfgNode, JWTEncoding::Range {
1718
PyJWTEncodeCall() { this = pyjwtEncode().getACall() }
1819

@@ -34,6 +35,7 @@ private module PyJWT {
3435
}
3536
}
3637

38+
// def decode(self, jwt, key="", algorithms=None, options=None)
3739
private class PyJWTDecodeCall extends DataFlow::CallCfgNode, JWTDecoding::Range {
3840
PyJWTDecodeCall() { this = pyjwtDecode().getACall() }
3941

0 commit comments

Comments
 (0)