Skip to content

Commit

Permalink
Prevent XSS from API call (#436)
Browse files Browse the repository at this point in the history
### Description: 
Prevent XSS

### Test
test in confidant-staging
  • Loading branch information
whu-lyft authored Sep 13, 2024
1 parent ef1d611 commit 8876b07
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 6.6.2

* XSS security fix / enhancement for Flask API response

## 6.6.1

* Upgrade confidant to python 3.10.14
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.6.1
6.6.2
7 changes: 7 additions & 0 deletions confidant/routes/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@


@blueprint.route('/v1/credentials', methods=['GET'])
@misc.prevent_xss_decorator
@authnz.require_auth
def get_credential_list():
"""
Expand Down Expand Up @@ -132,6 +133,7 @@ def get_credential_list():


@blueprint.route('/v1/credentials/<id>', methods=['GET'])
@misc.prevent_xss_decorator
@authnz.require_auth
def get_credential(id):
"""
Expand Down Expand Up @@ -369,6 +371,7 @@ def diff_credential(id, old_revision, new_revision):


@blueprint.route('/v1/archive/credentials/<id>', methods=['GET'])
@misc.prevent_xss_decorator
@authnz.require_auth
def get_archive_credential_revisions(id):
"""
Expand Down Expand Up @@ -451,6 +454,7 @@ def get_archive_credential_revisions(id):


@blueprint.route('/v1/archive/credentials', methods=['GET'])
@misc.prevent_xss_decorator
@authnz.require_auth
def get_archive_credential_list():
"""
Expand Down Expand Up @@ -534,6 +538,7 @@ def get_archive_credential_list():


@blueprint.route('/v1/credentials', methods=['POST'])
@misc.prevent_xss_decorator
@authnz.require_auth
@authnz.require_csrf_token
@maintenance.check_maintenance_mode
Expand Down Expand Up @@ -727,6 +732,7 @@ def get_credential_dependencies(id):


@blueprint.route('/v1/credentials/<id>', methods=['PUT'])
@misc.prevent_xss_decorator
@authnz.require_auth
@authnz.require_csrf_token
@maintenance.check_maintenance_mode
Expand Down Expand Up @@ -952,6 +958,7 @@ def update_credential(id):


@blueprint.route('/v1/credentials/<id>/<to_revision>', methods=['PUT'])
@misc.prevent_xss_decorator
@authnz.require_auth
@authnz.require_csrf_token
@maintenance.check_maintenance_mode
Expand Down
7 changes: 7 additions & 0 deletions confidant/routes/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def get_iam_roles_list():


@blueprint.route('/v1/services', methods=['GET'])
@misc.prevent_xss_decorator
@authnz.require_auth
def get_service_list():
"""
Expand Down Expand Up @@ -164,10 +165,12 @@ def get_service_list():
services_response = ServicesResponse.from_services(
Service.data_type_date_index.query('service'),
)

return services_response_schema.dumps(services_response)


@blueprint.route('/v1/services/<id>', methods=['GET'])
@misc.prevent_xss_decorator
@authnz.require_auth
def get_service(id):
'''
Expand Down Expand Up @@ -334,6 +337,7 @@ def get_service(id):


@blueprint.route('/v1/archive/services/<id>', methods=['GET'])
@misc.prevent_xss_decorator
@authnz.require_auth
def get_archive_service_revisions(id):
"""
Expand Down Expand Up @@ -414,6 +418,7 @@ def get_archive_service_revisions(id):


@blueprint.route('/v1/archive/services', methods=['GET'])
@misc.prevent_xss_decorator
@authnz.require_auth
def get_archive_service_list():
"""
Expand Down Expand Up @@ -492,6 +497,7 @@ def get_archive_service_list():


@blueprint.route('/v1/services/<id>', methods=['PUT'])
@misc.prevent_xss_decorator
@authnz.require_auth
@authnz.require_csrf_token
@maintenance.check_maintenance_mode
Expand Down Expand Up @@ -701,6 +707,7 @@ def map_service_credentials(id):


@blueprint.route('/v1/services/<id>/<to_revision>', methods=['PUT'])
@misc.prevent_xss_decorator
@authnz.require_auth
@authnz.require_csrf_token
@maintenance.check_maintenance_mode
Expand Down
27 changes: 27 additions & 0 deletions confidant/utils/misc.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from functools import wraps
import importlib
import pytz
from datetime import datetime
from flask import make_response


def dict_deep_update(a, b):
Expand Down Expand Up @@ -54,3 +56,28 @@ def utcnow():
"""
now = datetime.utcnow()
return now.replace(tzinfo=pytz.utc)


def prevent_xss_decorator(func):
"""
Prevents XSS attacks:
1. Set content type to be application/json
2. Set Content Security Policy (already specified at app level)
3. Enable XSS Protection
4. Prevent MIME Type Sniffing
5. Limit Referrer Information
"""
@wraps(func)
def wrapper(*args, **kwargs):
# Call the original function to get the response
pre_xss_response = func(*args, **kwargs)

# Apply XSS prevention
response = make_response(pre_xss_response)
response.headers['Content-Type'] = 'application/json'
response.headers['X-XSS-Protection'] = '1; mode=block'
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['Referrer-Policy'] = 'no-referrer'

return response
return wrapper
1 change: 0 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: "3.8"
networks:
confidant:
name: confidant
Expand Down

0 comments on commit 8876b07

Please sign in to comment.