← Back to team overview

webapps team mailing list archive

Webapps security auditing

 

Hi All,

part of the apt-daemon FFE, the security team asked for some
documentation on auditing integration scripts.

https://bugs.launchpad.net/ubuntu/+source/aptdaemon/+bug/1035207

Notably:

Up-to-date documentation for the exact steps required for auditing the
security of contributed webapp scripts. This needs to be written by
someone familiar with the intricacies of how the scripts are integrated
in the browser security model and how the webapps functionality was
implemented.

I put together a document along those lines that tries to cover a bit of
ground in the area and give some background/guidelines on things to
watch when reviewing an integration script per-se:

https://docs.google.com/a/canonical.com/document/d/1Ny_W8LKfv_jFqh3UiBdvdpSoEdIc2HoEbCSr6C2XxKA/edit

Could you please review it and send me any comment? (or modify the
document), I need to expand it a bit w/ some comments on browser
specific stuff (maybe),

Also I quickly setup a (very) dumb script that does some sort of static
analysis/search that could be used as a basis/help. It could/should be
expanded with time and with any functionality necessary (ideally less
dumb than what I put there). The script is *not* meant for being
exhaustive (it cannot) and only emits warning for obvious this to
further inspect,

See attachement,

Cheers!

-- 
Alexandre Abreu
Software developer
alexandre.abreu at canonical.com

#!/usr/bin/python
import sys


def _get_script_name():
    if len(sys.argv) == 2:
        return sys.argv[1]
    else:
        return ""
    
def _exit_with_error(message):
    sys.stderr.write("Error: %s\n" % message)
    sys.exit(1)

#
# list of specific audits performed
# the naming matters (automatic detection of audit functions)
#

def _perform_webapps_audit_usages_of_eval(content):
    """
    Checks direct usages of eval()
    """
    return content.find('eval') != -1

def _perform_webapps_audit_document_write(content):
    """
    Checks direct usages of document.write
    """
    return content.find('document.write') != -1

def _perform_webapps_audit_innerhtml(content):
    """
    Checks presence of innerHTML accesses
    """
    return content.find('innerHTML') != -1

def _perform_webapps_audit_unicode_presence(content):
    """
    Checks potential presence of unicode
    """
    return content.find('\u') != -1

def _perform_webapps_audit_iframe(content):
    """
    Checks direct usages of iframe
    """
    return content.find('iframe') != -1

def _perform_webapps_audit_xmlhttprequest(content):
    """
    Checks direct usages of XMLHTTPRequest
    """
    return content.find('XMLHTTPRequest') != -1

def _perform_webapps_audit_settimeout(content):
    """
    Checks direct usages of setTimeout function()
    """
    return content.find('setTimeout') != -1

def _perform_webapps_audit_document_location(content):
    """
    Checks direct usages of the 'location' property()
    """
    return content.find('document.location') != -1 or content.find('.location') != -1

def _perform_webapps_audit_document_location(content):
    """
    Checks the presence of base64 or dataurl
    """
    return content.find('"data:') != -1 or content.find('base64') != -1


def _perform_javascript_validation(content):
    import inspect
    audit_functions_prefix = '_perform_webapps_audit_'
    audit_functions = [{'name': member[0], 'function': member[1]}
                       for member in inspect.getmembers(sys.modules[__name__], inspect.isfunction)
                       if member[0].startswith(audit_functions_prefix)]

    for audit_function in audit_functions:
        func = audit_function['function']
        if func(content):
            print "Audit potential issue detected:", audit_function['name'], "performing", inspect.getdoc(audit_function['function'])


def _validate_script(script_name):
    """
    """
    if not script_name or len(script_name) == 0:
        return
    import os
    if not os.path.exists(script_name) or not os.path.isfile(script_name):
        _exit_with_error("Script not found")
    try:
        _perform_javascript_validation(open(script_name).read())
    except Exception, e:
        _exit_with_error("Could not validate script (error %s)" % str(e))


if __name__ == "__main__":
    _validate_script(_get_script_name())

References