CVE-2017-7266 (published 2017-03-26T05:59Z)

Netflix Security Monkey before 0.8.0 has an Open Redirect. The logout functionality accepted the "next" parameter which then redirects to any domain irrespective of the Host header.

Severity: MEDIUM
CVSS v2 base score: 5.8 (AV:N/AC:M/Au:N/C:P/I:P/A:N)
CVSS v3 base score: 6.1, MEDIUM (CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N)

Weakness information:
cwe_id: CWE-601
cwe_name: URL Redirection to Untrusted Site ('Open Redirect')
description: A web application accepts a user-controlled input that specifies a link to an external site, and uses that link in a Redirect. This simplifies phishing attacks.
extended_description: An http parameter may contain a URL value and could cause the web application to redirect the request to the specified URL. By modifying the URL value to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials. Because the server name in the modified link is identical to the original site, phishing attempts have a more trustworthy appearance. Whether this issue poses a vulnerability will be subject to the intended behavior of the application. For example, a search engine might intentionally provide redirects to arbitrary URLs.
         

Fix information:
repo_url: https://github.com/Netflix/security_monkey
commit_details: repo_url: https://github.com/Netflix/security_monkey
author: Patrick Kelley
author_date: 2016-12-30 00:33:29-07:00
msg: Replacing Flask-Security with Flask-Security-Fork. Removing some explicit dependencies to rely on flask-security-fork dependencies. SSO will use flask-security login_user instead of flask-login so that security_trackable works. Replacing current_user.is_authenticated() method with property so  we can use a newer version of flask-login. (#482)
repository: repo_url: https://github.com/Netflix/security_monkey
repo_name: Netflix/security_monkey
description: Security Monkey monitors AWS, GCP, OpenStack, and GitHub orgs for assets and their changes over time.
repo_language: Python
owner: Netflix
file_changes: filename: modules.py
change_type: ModificationType.MODIFY
diff: @@ -240,7 +240,7 @@ class RBAC(object):
 
     def _deny_hook(self, resource=None):
         app = self.get_app()
-        if current_user.is_authenticated():
+        if current_user.is_authenticated:
             status = 403
         else:
             status = 401
@@ -250,7 +250,7 @@ class RBAC(object):
                 url = "https://{}:{}{}".format(app.config.get('FQDN'), app.config.get('NGINX_PORT'), '/login')
         else:
                 url = "http://{}:{}{}".format(app.config.get('FQDN'), app.config.get('API_PORT'), '/login')
-        if current_user.is_authenticated():
+        if current_user.is_authenticated:
             auth_dict = {
                 "authenticated": True,
                 "user": current_user.email,

programming_language: Python
filename: views.py
change_type: ModificationType.MODIFY
diff: @@ -13,7 +13,7 @@ from flask import Blueprint, current_app, redirect, request
 
 from flask.ext.restful import reqparse, Resource, Api
 from flask.ext.principal import Identity, identity_changed
-from flask_login import login_user
+from flask_security.utils import login_user
 
 try:
     from onelogin.saml2.auth import OneLogin_Saml2_Auth
@@ -264,7 +264,7 @@ class OneLogin(Resource):
         auth.process_response()
         errors = auth.get_errors()
         if not errors:
-            if auth.is_authenticated():
+            if auth.is_authenticated:
                 return True
             else:
                 return False

programming_language: Python
filename: __init__.py
change_type: ModificationType.MODIFY
diff: @@ -144,7 +144,7 @@ class AuthenticatedService(Resource):
         self.reqparse = reqparse.RequestParser()
         super(AuthenticatedService, self).__init__()
         self.auth_dict = dict()
-        if current_user.is_authenticated():
+        if current_user.is_authenticated:
             roles_marshal = []
             for role in current_user.roles:
                 roles_marshal.append(marshal(role.__dict__, ROLE_FIELDS))

programming_language: Python
filename: logout.py
change_type: ModificationType.MODIFY
diff: @@ -25,7 +25,7 @@ class Logout(Resource):
     decorators = [rbac.exempt]
 
     def get(self):
-        if not current_user.is_authenticated():
+        if not current_user.is_authenticated:
             return "Must be logged in to log out", 200
 
         logout_user()

programming_language: Python
filename: setup.py
change_type: ModificationType.MODIFY
diff: @@ -23,25 +23,24 @@ setup(
     install_requires=[
         'APScheduler==2.1.2',
         'Flask==0.10.1',
-        'Flask-Login==0.2.10',
         'Flask-Mail==0.9.0',
         'Flask-Migrate==1.3.1',
         'Flask-Principal==0.4.0',
         'Flask-RESTful==0.3.3',
         'Flask-SQLAlchemy==1.0',
         'Flask-Script==0.6.3',
-        'Flask-Security==1.7.4',
-        'Flask-WTF==0.9.5',
+        # 'Flask-Security==1.7.4',
+        'Flask-Security-Fork==1.8.2',
         'Jinja2==2.8',
         'SQLAlchemy==0.9.2',
         'boto>=2.41.0',
         'ipaddr==2.1.11',
         'itsdangerous==0.23',
-        'psycopg2==2.5.2',
-        'bcrypt==2.0.0',
+        'psycopg2==2.6.2',
+        'bcrypt==3.1.2',
         'Sphinx==1.2.2',
         'gunicorn==18.0',
-        'cryptography==1.3.2',
+        'cryptography==1.7.1',
         'boto3>=1.4.2',
         'botocore>=1.4.81',
         'dpath==1.3.2',

programming_language: Python