Skip to content

Authentication

Johannes vom Dorp edited this page Feb 19, 2018 · 12 revisions

Using FACT with Authentication

Overview

  1. Concept
  2. Configuration
  3. Default Privileges

Concept

By utilizing flask_security, a role based access control was added as an optional feature to secure the FACT GUI. The idea is to define a privilege to each functionality and link that privilege to a set of roles. E.g. let upload analysis and update analysis have the privilege submit. Then the endpoints /upload, /rest/firmware and all secondary paths require the submit privilege. To ease the amount of configuration, this privilege can be applied to multiple roles as well as one or none role.

The standard browser interface is given an additional login/logout tab to enter username/password. Additionally an api key is generated for each user which can be used in the Authorization header field of a http request to authenticate against the REST-API.

Configuration

The authentication feature is turned off by default to keep backwards compatibility as well as spare internal setups the unnecessary overhead. Turning it on is achieved by simply setting the authentication option in the config file to true. The authentication feature comes packaged with a user management tool src/manage_users.py that can create users and roles. Also it allows adding/removing roles to/from users and listing the api key for an existing user. A GUI based user management is not considered yet.

Adding privileges to a role can be achieved by changing the PRIVILEGES field in the src/security_switch.py script. This field is a dictionary mapping each privilege to a set of roles. The privilege of an endpoint is given to the roles_accepted decorator of the endpoint function. Thus, by changing the parameter of the endpoint, the privilege can be changed.

Warning: Because the common ajax endpoints, the compare privilege, has to be at least as powerful as view_analysis, when the default privilege <> endpoint mapping is applied.

Default Privileges

As of now these privileges and roles are configured:

ROLES = ['superuser', 'senior_analyst', 'analyst', 'guest_analyst', 'guest']

PRIVILEGES = {
    'status':           ['superuser', 'senior_analyst', 'analyst', 'guest_analyst', 'guest'],
    'basic_search':     ['superuser', 'senior_analyst', 'analyst', 'guest_analyst'],
    'view_analysis':    ['superuser', 'senior_analyst', 'analyst', 'guest_analyst'],
    'comment':          ['superuser', 'senior_analyst', 'analyst'],
    'compare':          ['superuser', 'senior_analyst', 'analyst'],
    'advanced_search':  ['superuser', 'senior_analyst', 'analyst'],
    'pattern_search':   ['superuser', 'senior_analyst', 'analyst'],
    'submit_analysis':  ['superuser', 'senior_analyst'],
    'download':         ['superuser', 'senior_analyst'],
    'delete':           ['superuser']
}

The default privilege / endpoint mapping looks as follows:

{
    'view_analysis': [
       '/analysis/<uid>',
       '/analysis/<uid>/ro/<root_uid>',
       '/analysis/<uid>/<selected_analysis>',
       '/analysis/<uid>/<selected_analysis>/ro/<root_uid>',
       '/analysis/<uid>/<selected_analysis>/<root_uid>',
       '/ajax_tree/<uid>/<root_uid>',
       '/ajax_root/<uid>',
       '/rest/firmware/<uid>',
       '/rest/file_object/<uid>',
       '/rest/file_object',
       '/ajax_get_binary/<mime_type>/<uid>',
       '/ajax_get_binary/<type>/<uid>'
    ],
    'submit': [
       '/update-analysis/<uid>',
       '/compare',
       '/rest/firmware',
       '/upload'
    ],
    'compare': [
       '/database/browse_compare',
       '/compare/<compare_id>',
       '/rest/compare',
       '/rest/compare/<compare_id>',
       '/compare/ajax_tree/<compare_id>/<root_uid>/<uid>',
       '/compare/ajax_common_files/<compare_id>/<feature_id>/',
       '/comparison/add/<uid>',
       '/comparison/remove/<analysis_uid>/<compare_uid>',
       '/comparison/remove_all/<analysis_uid>'
    ],
    'pattern_search': [
       '/database/binary_search',
       '/database/database_binary_search_results.html'
    ],

    'advanced_search': [
       '/database/advanced_search'
    ], 
    'basic_search': [
       '/database/browse',
       '/database/search',
       '/database/quick_search'
    ],
    'download': [
       '/rest/binary/<uid>',
       '/download/<uid>',
       '/tar-download/<uid>',
       '/ida-download/<compare_id>',
       '/base64-download/<uid>/<section>/<expression_id>',
       '/hex-dump/<uid>'
    ],
    'comment': [
       '/comment/<uid>'
    ],
    'delete': [
       '/admin/delete_comment/<uid>/<timestamp>',
       '/admin/delete/<uid>',
       '/admin/re-do_analysis/<uid>'
    ],
    'status': [
       '/statistic',
       '/system_health',
       '/' ,
       '/about'
    ]
}

Note: No route is accessible without authentication.