forked from saltcorn/saltcorn
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* initial * org as pytest * content * reset * sc session * misc login conditions * fix hard crash * start, kill server * in github actions * path to saltcorn bin * order back * timeout. test to fixtures * readme * futher tests * signup tests * reset first * different port
- Loading branch information
Showing
9 changed files
with
299 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,4 +111,6 @@ sessions.sqlite | |
|
||
.greenlockrc | ||
|
||
infosec_scan_tmp/ | ||
infosec_scan_tmp/ | ||
|
||
*.pyc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Python security tests for Saltcorn | ||
|
||
### Install | ||
|
||
`pip3 install requests pytest` | ||
|
||
### To run | ||
|
||
`PGDATABASE=saltcorn_test pytest` in the saltcorn repository root directory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
from scsession import SaltcornSession | ||
|
||
sess = SaltcornSession(3000) | ||
email = "[email protected]" | ||
password="AhGGr6rhu45" | ||
|
||
# helpers | ||
def cannot_access_admin(): | ||
sess.get('/table') | ||
assert sess.status == 302 | ||
assert "Your tables" not in sess.content | ||
|
||
def is_incorrect_user_or_password(): | ||
assert sess.redirect_url == '/auth/login' | ||
sess.follow_redirect() | ||
assert "Incorrect user or password" in sess.content | ||
|
||
|
||
def test_public_cannot_access_admin(): | ||
sess.reset() | ||
cannot_access_admin() | ||
|
||
def test_can_login_as_admin(): | ||
sess.reset() | ||
sess.get('/auth/login') | ||
assert "Login" in sess.content | ||
assert sess.status == 200 | ||
sess.postForm('/auth/login', | ||
{'email': email, | ||
'password': password, | ||
'_csrf': sess.csrf() | ||
}) | ||
assert sess.redirect_url == '/' | ||
sess.get('/table') | ||
assert sess.status == 200 | ||
assert "Your tables" in sess.content | ||
|
||
def test_login_without_csrf(): | ||
sess.reset() | ||
sess.get('/auth/login') | ||
sess.postForm('/auth/login', | ||
{'email': email, | ||
'password': password, | ||
}) | ||
assert sess.redirect_url == '/auth/login' | ||
cannot_access_admin() | ||
|
||
def test_login_with_wrong_csrf(): | ||
sess.reset() | ||
sess.get('/auth/login') | ||
sess.postForm('/auth/login', | ||
{'email': email, | ||
'password': password, | ||
'_csrf': 'ytjutydetjk' | ||
}) | ||
assert sess.redirect_url == '/auth/login' | ||
cannot_access_admin() | ||
|
||
def test_login_with_blank_csrf(): | ||
sess.reset() | ||
sess.get('/auth/login') | ||
sess.postForm('/auth/login', | ||
{'email': email, | ||
'password': password, | ||
'_csrf': '' | ||
}) | ||
assert sess.redirect_url == '/auth/login' | ||
cannot_access_admin() | ||
|
||
def test_login_with_wrong_password(): | ||
sess.reset() | ||
sess.get('/auth/login') | ||
sess.postForm('/auth/login', | ||
{'email': email, | ||
'password': 'fidelio', | ||
'_csrf': sess.csrf() | ||
}) | ||
is_incorrect_user_or_password() | ||
cannot_access_admin() | ||
|
||
def test_login_with_no_password(): | ||
sess.reset() | ||
sess.get('/auth/login') | ||
sess.postForm('/auth/login', {'email': email , '_csrf': sess.csrf()}) | ||
is_incorrect_user_or_password() | ||
cannot_access_admin() | ||
|
||
def test_login_with_no_email(): | ||
sess.reset() | ||
sess.get('/auth/login') | ||
sess.postForm('/auth/login', {'password': password, '_csrf': sess.csrf()}) | ||
is_incorrect_user_or_password() | ||
cannot_access_admin() | ||
|
||
def test_login_with_blank_email(): | ||
sess.reset() | ||
sess.get('/auth/login') | ||
sess.postForm('/auth/login', {'email':'', 'password': password, '_csrf': sess.csrf()}) | ||
is_incorrect_user_or_password() | ||
cannot_access_admin() | ||
|
||
def test_login_with_nothing(): | ||
sess.reset() | ||
sess.get('/auth/login') | ||
sess.postForm('/auth/login', {'_csrf': sess.csrf()}) | ||
is_incorrect_user_or_password() | ||
cannot_access_admin() | ||
|
||
def test_login_with_blank_password(): | ||
sess.reset() | ||
sess.get('/auth/login') | ||
sess.postForm('/auth/login', {'email': email,'password': '', '_csrf': sess.csrf()}) | ||
is_incorrect_user_or_password() | ||
cannot_access_admin() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from sectest import Session | ||
import re | ||
import subprocess | ||
|
||
class SaltcornSession(Session): | ||
def __init__(self, port=3000): | ||
self.salcorn_process = subprocess.Popen(["packages/saltcorn-cli/bin/saltcorn", "serve", "-p", str(port)]) | ||
Session.__init__(self, 'http://localhost:%d/' % port) | ||
self.wait_for_port_open() | ||
|
||
def __del__(self): | ||
self.salcorn_process.kill() | ||
|
||
def csrf(self): | ||
m = re.findall('_sc_globalCsrf = "([^"]*)"', self.content) | ||
return m[0] | ||
|
||
@staticmethod | ||
def reset_to_fixtures(): | ||
subprocess.run(["packages/saltcorn-cli/bin/saltcorn", "fixtures", "-r"], check=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import requests | ||
from urllib.parse import urljoin | ||
from urllib.request import urlopen | ||
import time | ||
|
||
class Session: | ||
def __init__(self, base_url): | ||
self.base_url = base_url | ||
self.reset() | ||
|
||
def wait_for_port_open(self): | ||
i=0 | ||
while i<30: | ||
try: | ||
response = urlopen(self.base_url,timeout=1) | ||
return | ||
except: | ||
print("Closed, retry") | ||
time.sleep(0.25) | ||
i=i+1 | ||
pass | ||
raise ValueError("wait_for_port_open: Iterations exceeded") | ||
|
||
def __read_response(self, resp): | ||
self.status = resp.status_code | ||
self.content = resp.text | ||
if self.status >= 300 and self.status <400: | ||
ws = self.content.split() | ||
self.redirect_url=ws[len(ws)-1] | ||
else: | ||
self.redirect_url = None | ||
|
||
def get(self, url): | ||
resp = self.session.get(urljoin(self.base_url, url), allow_redirects=False) | ||
self.__read_response(resp) | ||
|
||
def postForm(self, url, data): | ||
resp = self.session.post(urljoin(self.base_url, url), data=data, allow_redirects=False) | ||
self.__read_response(resp) | ||
|
||
def follow_redirect(self): | ||
self.get(self.redirect_url) | ||
|
||
|
||
def reset(self): | ||
self.status = None | ||
self.content = None | ||
self.redirect_url = None | ||
self.session = requests.Session() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
from scsession import SaltcornSession | ||
|
||
SaltcornSession.reset_to_fixtures() | ||
sess = SaltcornSession(3001) | ||
|
||
# helpers | ||
def cannot_access_admin(): | ||
sess.get('/table') | ||
assert sess.status == 302 | ||
assert "Your tables" not in sess.content | ||
|
||
def test_public_home_is_redirect(): | ||
sess.reset() | ||
sess.get('/') | ||
assert sess.redirect_url == '/auth/login' | ||
cannot_access_admin() | ||
|
||
def test_can_signup(): | ||
sess.reset() | ||
sess.get('/auth/signup') | ||
assert "Sign up" in sess.content | ||
assert sess.status == 200 | ||
sess.postForm('/auth/signup', | ||
{'email': '[email protected]', | ||
'password': 'ty435y5OPtyj', | ||
'_csrf': sess.csrf() | ||
}) | ||
assert sess.redirect_url == '/' | ||
sess.follow_redirect() | ||
assert 'Welcome to Saltcorn!' in sess.content | ||
cannot_access_admin() | ||
sess.get('/auth/logout') | ||
assert sess.redirect_url == '/auth/login' | ||
sess.follow_redirect() | ||
sess.postForm('/auth/login', | ||
{'email': '[email protected]', | ||
'password': 'ty435y5OPtyj', | ||
'_csrf': sess.csrf() | ||
}) | ||
assert sess.redirect_url == '/' | ||
|
||
def test_cannot_signup_again(): | ||
sess.reset() | ||
sess.get('/auth/signup') | ||
sess.postForm('/auth/signup', | ||
{'email': '[email protected]', | ||
'password': 'ty435y5OPtyj', | ||
'_csrf': sess.csrf() | ||
}) | ||
assert sess.redirect_url == '/auth/signup' | ||
|
||
def test_signup_no_csrf(): | ||
sess.reset() | ||
sess.get('/auth/signup') | ||
sess.postForm('/auth/signup', | ||
{'email': '[email protected]', | ||
'password': 'ty435yqpiOPtyj', | ||
}) | ||
assert sess.redirect_url == '/' | ||
sess.follow_redirect() | ||
assert sess.redirect_url == '/auth/login' | ||
sess.follow_redirect() | ||
sess.postForm('/auth/login', | ||
{'email': '[email protected]', | ||
'password': 'ty435yqpiOPtyj', | ||
'_csrf': sess.csrf() | ||
}) | ||
assert sess.redirect_url == '/auth/login' | ||
sess.follow_redirect() | ||
assert "Incorrect user or password" in sess.content | ||
|
||
def test_cannot_inject_role_id(): | ||
sess.reset() | ||
sess.get('/auth/signup') | ||
assert "Sign up" in sess.content | ||
assert sess.status == 200 | ||
sess.postForm('/auth/signup', | ||
{'email': '[email protected]', | ||
'password': 'ty11y5OPtyj', | ||
'role_id': '1', | ||
'_csrf': sess.csrf() | ||
}) | ||
assert sess.redirect_url == '/' | ||
sess.follow_redirect() | ||
cannot_access_admin() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,8 @@ class FixturesCommand extends Command { | |
await reset(); | ||
} | ||
await fixtures(); | ||
this.exit(0); | ||
|
||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters