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

Skip to content

Commit 114984b

Browse files
committed
Python: Added tests based on security analysis
currently we do not: - recognize the pattern `{'author': {"$eq": author}}` as protected - recognize arguements to `$where` (and friends) as vulnerable
1 parent bf8bfd9 commit 114984b

5 files changed

Lines changed: 93 additions & 0 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from pymongo import MongoClient
2+
client = MongoClient()
3+
4+
db = client.test_database
5+
6+
import datetime
7+
post = {
8+
"author": "Mike",
9+
"text": "My first blog post!",
10+
"tags": ["mongodb", "python", "pymongo"],
11+
"date": datetime.datetime.now(tz=datetime.timezone.utc),
12+
}
13+
14+
posts = db.posts
15+
post_id = posts.insert_one(post).inserted_id
16+
post_id
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Tutorials:
2+
- [pymongo](https://pymongo.readthedocs.io/en/stable/tutorial.html)
3+
- [install mongodb](https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-os-x/#std-label-install-mdb-community-macos)
4+
5+
I recommend creating a virtual environment with venv and then installing dependencies via
6+
```
7+
python -m pip --install -r requirements.txt
8+
```
9+
10+
Start mongodb:
11+
```
12+
mongod --config /usr/local/etc/mongod.conf --fork
13+
```
14+
run flask app:
15+
```
16+
flask --app server run
17+
```
18+
19+
Navigate to the root to see routes. For each route try to get the system to reveal the person in the database. If you know the name, you can just input it, but in some cases you can get to the person without knowing the name!
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
flask
2+
pymongo
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from flask import Flask, request
2+
from pymongo import MongoClient
3+
import json
4+
5+
client = MongoClient()
6+
db = client.test_database
7+
posts = db.posts
8+
9+
app = Flask(__name__)
10+
11+
12+
def show_post(post, query):
13+
if post:
14+
return "You found " + post['author'] + "!"
15+
else:
16+
return "You did not find " + query
17+
18+
@app.route('/plain', methods=['GET'])
19+
def plain():
20+
author = request.args['author']
21+
post = posts.find_one({'author': author}) # $ result=OK
22+
return show_post(post, author)
23+
24+
@app.route('/dict', methods=['GET'])
25+
def as_dict():
26+
author_string = request.args['author']
27+
author = json.loads(author_string)
28+
# Use {"$ne": 1} as author
29+
# Found by http://127.0.0.1:5000/dict?author={%22$ne%22:1}
30+
post = posts.find_one({'author': author}) # $ result=BAD
31+
return show_post(post, author)
32+
33+
@app.route('/dictHardened', methods=['GET'])
34+
def as_dict_hardened():
35+
author_string = request.args['author']
36+
author = json.loads(author_string)
37+
post = posts.find_one({'author': {"$eq": author}}) # $ SPURIOUS: result=BAD
38+
return show_post(post, author)
39+
40+
@app.route('/byWhere', methods=['GET'])
41+
def by_where():
42+
author = request.args['author']
43+
# Use `" | "a" === "a` as author
44+
# making the query `this.author === "" | "a" === "a"`
45+
# Found by http://127.0.0.1:5000/byWhere?author=%22%20|%20%22a%22%20===%20%22a
46+
post = posts.find_one({'$where': 'this.author === "'+author+'"'}) # $ MISSING: result=BAD
47+
return show_post(post, author)
48+
49+
@app.route('/', methods=['GET'])
50+
def show_routes():
51+
links = []
52+
for rule in app.url_map.iter_rules():
53+
if "GET" in rule.methods:
54+
links.append((rule.rule, rule.endpoint))
55+
return links
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
semmle-extractor-options: --max-import-depth=1 -r PoC

0 commit comments

Comments
 (0)