Skip to content

Commit

Permalink
Added security headers library for fastApi (#198)
Browse files Browse the repository at this point in the history
* Added security headers library for fastApi

* Fix TOML syntax and add to "all" list.

* Add secure library installation to apiserver image.

* Add test of secure middleware that checks the inserted headers.

* Update test to capture more output.

---------

Co-authored-by: Grigory Frantsuzov <[email protected]>
Co-authored-by: James Mathews <[email protected]>
  • Loading branch information
3 people authored Sep 12, 2023
1 parent dda3cbd commit 93a8be3
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 2 deletions.
1 change: 1 addition & 0 deletions build/apiserver/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ RUN python -m pip install pyshp==2.2.0
RUN python -m pip install scikit-learn==1.2.2
RUN python -m pip install Pillow==9.5.0
RUN python -m pip install pydantic==2.0.2
RUN python -m pip install secure==0.3.0
ARG version
ARG service_name
ARG WHEEL_FILENAME
Expand Down
6 changes: 4 additions & 2 deletions pyproject.toml.unversioned
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ apiserver = [
"pyshp==2.2.0",
"scikit-learn==1.2.2",
"Pillow==9.5.0",
"pydantic==2.0.2"
"pydantic==2.0.2",
"secure==0.3.0"
]
cggnn = [
"cg-gnn"
Expand Down Expand Up @@ -85,7 +86,8 @@ all = [
"pydantic==2.0.2",
"fastapi==0.100.0",
"Pillow==9.5.0",
"squidpy==1.3.0"
"squidpy==1.3.0",
"secure==0.3.0"
]
dev = [
"autopep8",
Expand Down
9 changes: 9 additions & 0 deletions spatialprofilingtoolbox/apiserver/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from fastapi import Response
from fastapi.responses import StreamingResponse

import secure

from spatialprofilingtoolbox.ondemand.service_client import OnDemandRequester
from spatialprofilingtoolbox.db.exchange_data_formats.study import StudyHandle
from spatialprofilingtoolbox.db.exchange_data_formats.study import StudySummary
Expand Down Expand Up @@ -76,6 +78,13 @@ def custom_openapi():

setattr(app, 'openapi', custom_openapi)

secure_headers = secure.Secure()

@app.middleware("http")
async def set_secure_headers(request, call_next):
response = await call_next(request)
secure_headers.framework.fastapi(response)
return response

@app.get("/")
async def get_root():
Expand Down
14 changes: 14 additions & 0 deletions test/apiserver/unit_tests/expected_headers_example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
< HTTP/1.1 200 OK
< server: uvicorn
< content-length: 97
< content-type: application/json
< strict-transport-security: max-age=63072000; includeSubdomains
< x-frame-options: SAMEORIGIN
< x-xss-protection: 0
< x-content-type-options: nosniff
< referrer-policy: no-referrer, strict-origin-when-cross-origin
< cache-control: no-store
<
{ [97 bytes data]
* Connection #0 to host spt-apiserver-testing left intact
[{"handle":"Melanoma intralesional IL2","display_name_detail":"Cancer Immunology Research 2022"}]
29 changes: 29 additions & 0 deletions test/apiserver/unit_tests/test_secure_headers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

query=http://spt-apiserver-testing:8080/study-names/

curl -s $query 1>/dev/null 2>/dev/null;
if [ "$?" -gt 0 ];
then
echo "Error with apiserver query."
curl $query
exit 1
fi

curl -s --verbose $query 2>&1 | tail -n +9 | grep -v 'date: ' | tr -d '\b\r' > response.txt

diff unit_tests/expected_headers_example.txt response.txt
status=$?
[ $status -eq 0 ] || (echo "API query for headers inspection failed."; )

if [ $status -eq 0 ];
then
echo "Response headers were as expected:"
echo
cat response.txt
rm response.txt
exit 0
else
cat response.txt
rm response.txt
exit 1
fi

0 comments on commit 93a8be3

Please sign in to comment.