Ejemplo n.º 1
0
class JsDomFuzzer(Fuzzer):
    NAME = "js_dom_fuzzer"
    CONFIG_PARAMS = ["starting_elements", "total_operations", "browser", "seed", "file_type"]

    def __init__(self, starting_elements, total_operations, browser, seed=31337, file_type="html"):
        self._starting_elements = int(starting_elements)
        self._total_operations = int(total_operations)
        self._browser = browser
        seed = int(seed)
        #  self._html_fuzzer = HtmlFuzzer(self._starting_elements, 3, seed)
        self._html_fuzzer = Html5Fuzzer(int(seed), self._starting_elements, 10, 5, file_type)
        self._css_fuzzer = CssFuzzer(seed)
        if seed == 0:
            random.seed()
        else:
            random.seed(seed)
        self._file_type = file_type
        self._function_count = 0
        self._operations_count = 0
        self._js_elements = {}
        """:type dict(JsElement)"""
        self._window_timeout = 20
        self._occurring_events = {}
        for event in DomObjects.DOM_EVENTS:
            self._occurring_events[event] = 0

    @classmethod
    def from_list(cls, params):
        return cls(params[0], params[1], params[2], params[3], params[4])

    @property
    def prng_state(self):
        return random.getstate()

    @property
    def file_type(self):
        return self._file_type

    @staticmethod
    def __get_html_ids(html):
        start = html.find("IDS:") + 5
        end = html.find("-->")
        ids = html[start:end].split("; ")
        del (ids[-1])
        return ids

    def set_seed(self, seed=0):
        random.seed(seed)

    def __reinit(self):
        self._function_count = 0
        self._operations_count = 0
        self._function_count = 0
        self._operations_count = 0
        self._js_elements = {}
        """:type dict(JsElement)"""
        self._window_timeout = 20
        self._occurring_events = {}
        for event in DomObjects.DOM_EVENTS:
            self._occurring_events[event] = 0

    def create_testcases(self, count, directory):
        for i in range(count):
            test_name = "/test" + str(i) if i > 9 else "/test0" + str(i)
            with open(directory + test_name + "." + self._file_type, "wb+") as html_fd, open(
                directory + test_name + ".css", "wb+"
            ) as css_fd:
                html, css = self.fuzz()
                html = html.replace("TESTCASE", test_name)
                html_fd.write(html)
                css_fd.write(css)

    def fuzz(self):
        html = self._html_fuzzer.fuzz()
        self._css_fuzzer.set_tags(self._html_fuzzer.tags)
        css = self._css_fuzzer.fuzz()
        ids = self._html_fuzzer.elem_ids
        js_code = self.__create_startup(ids)
        while self._total_operations > self._operations_count:
            js_code += self.__add_function()
        js_code = js_code.replace(
            Window.setTimeout("func" + str(self._function_count) + "()", self._window_timeout), "event_firing()"
        )
        js_code += self.__add_event_dipatcher()
        js_code += self.__add_event_handlers()
        doc = html.replace("SCRIPT_BODY", js_code)
        self.__reinit()
        return (doc, css)

    def set_state(self, state):
        random.setstate(state)

    def __create_startup(self, elem_ids):
        code = "function startup() {\n"
        i = 0
        for elem_id in elem_ids:
            code += "\t" + "elem" + str(i) + " = " + JsDocument.getElementById(elem_id) + "\n"
            self._js_elements["elem" + str(i)] = JsElement("elem" + str(i))
            i += 1
        code += "\t" + Window.setTimeout("func0" + "()", self._window_timeout) + "\n}\n"
        return code

    def __add_function(self, func_name=None, event=False):
        if not func_name:
            func_name = "func" + str(self._function_count) + "()"
        code = "function " + func_name + " {\n"
        func_count = random.randint(10, 50)
        for i in range(func_count):
            code += "\t" + JsGlobal.try_catch_block(self.__add_element_method())
        if not event:
            self._function_count += 1
            code += "\t" + Window.setTimeout("func" + str(self._function_count) + "()", self._window_timeout) + " \n"
        code += "}\n"
        return code

    def __add_event_handlers(self):
        code = ""
        for event in self._occurring_events:
            code += self.__add_function(event + "_handler" + "(event)", True)
        return code

    def __add_event_dipatcher(self):
        code = "function event_firing() {\n"
        for key in self._js_elements:
            for event in self._js_elements[key].registered_events.keys():
                if "DOM" in event:
                    continue
                elif event == "click":
                    code += JsGlobal.try_catch_block(self._js_elements[key].click() + "\n", "ex")
                elif event == "error":
                    pass
                elif event == "load":
                    pass
                elif event == "scroll":
                    code += JsGlobal.try_catch_block(self._js_elements[key].prop_scrollLeft() + " = 10;" + "\n", "ex")
                elif event == "resize" or event == "change":
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].prop_innerHtml() + ' = "' + "A" * 100 + '";\n', "ex"
                    )
                elif event == "focus" or event == "focusin":
                    code += JsGlobal.try_catch_block(self._js_elements[key].focus() + "\n", "ex")
                elif event == "blur":
                    code += JsGlobal.try_catch_block(self._js_elements[key].blur() + "\n", "ex")
                elif event == "select":
                    code += JsGlobal.try_catch_block(self._js_elements[key].select() + "\n", "ex")
        code += "}\n"
        return code

    def __add__new_element(self):
        elem_name = "elem_cr" + str(len(self._js_elements))
        code = elem_name + " = " + JsDocument.createElement(random.choice(HtmlObjects.HTML_OBJECTS)) + "\n"
        self._js_elements[elem_name] = JsElement(elem_name)
        return elem_name, code

    def __add_element_method(self, key=None):
        code = ""
        if not key:
            key = random.choice(self._js_elements.keys())
        method = random.choice(DomObjects.DOM_ELEMENT_FUZZ_STUFF)
        if method == "addEventListener":
            event = random.choice(DomObjects.DOM_EVENTS)
            self._occurring_events[event] += 1
            code += self._js_elements[key].addEventListener(event, event + "_handler")
        elif method == "appendChild":
            if random.randint(1, 100) < 80:
                child = random.choice(self._js_elements.keys())
                if child == key:
                    elem_name, add_code = self.__add__new_element()
                    code += add_code
                    self._js_elements[elem_name] = JsElement(elem_name)
                    child = elem_name
                code += self._js_elements[key].appendChild(child)
            else:
                elem_name, add_code = self.__add__new_element()
                code += add_code
                self._js_elements[elem_name] = JsElement(elem_name)
                code += self._js_elements[key].appendChild(elem_name)
        elif method == "cloneNode":
            length = len(self._js_elements)
            elem_name = "elem_cr" + str(length)
            code += elem_name + " = " + self._js_elements[key].cloneNode(True)
            self._js_elements[elem_name] = JsElement(elem_name)
            self._js_elements[elem_name].set_children(self._js_elements[key].get_children())
        elif method == "hasAttribute":
            code += self._js_elements[key].hasAttribute(random.choice(HtmlObjects.HTML_ATTR_GENERIC))
        elif method == "hasChildNode":
            code += self._js_elements[key].hasChildNodes()
        elif method == "insertBefore":
            if not self._js_elements[key].get_children():
                elem_name, add_code = self.__add__new_element()
                code += add_code
                code += "\t" + self._js_elements[key].appendChild(elem_name) + "\n"
            elem_name, add_code = self.__add__new_element()
            code += add_code
            code += self._js_elements[key].insertBefore(elem_name, random.choice(self._js_elements[key].get_children()))
        elif method == "normalize":
            code += self._js_elements[key].normalize()
        elif method == "removeAttribute":
            if not self._js_elements[key].attributes:
                code += self._js_elements[key].setAttribute(
                    random.choice(HtmlObjects.HTML_ATTR_GENERIC), random.choice(FuzzValues.INTERESTING_VALUES)
                )
            else:
                code += self._js_elements[key].removeAttribute(random.choice(self._js_elements[key].attributes.keys()))
        elif method == "removeChild":
            if not self._js_elements[key].get_children():
                elem_name, add_code = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].appendChild(elem_name)
            else:
                code += self._js_elements[key].removeChild(random.choice(self._js_elements[key].get_children()))
        elif method == "replaceChild":
            if not self._js_elements[key].get_children():
                elem_name, add_code = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].appendChild(elem_name)
            else:
                elem_name, add_code = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].replaceChild(
                    elem_name, random.choice(self._js_elements[key].get_children())
                )
        elif method == "removeEventListener":
            if not self._js_elements[key].registered_events:
                event = random.choice(DomObjects.DOM_EVENTS)
                self._occurring_events[event] += 1
                code += self._js_elements[key].addEventListener(event, event + "_handler")
            else:
                event = random.choice(self._js_elements[key].registered_events.keys())
                self._occurring_events[event] -= 1
                event = random.choice(self._js_elements[key].registered_events.keys())
                code += self._js_elements[key].removeEventListener(
                    event, self._js_elements[key].registered_events[event]
                )
        elif method == "setAttribute":
            attr = random.choice(HtmlObjects.HTML_ATTR_GENERIC)
            if attr == "style":
                val = ""
                for i in range(1, 50):
                    css = random.choice(FuzzValues.CSS_STYLES)
                    val += css[0] + ": " + random.choice(css[1:]) + "; "
            else:
                val = random.choice(FuzzValues.INTERESTING_VALUES)
            code += self._js_elements[key].setAttribute(attr, val)
        elif method == "REPLACE_EXIST_ELEMENT":
            elem_name, add_code = self.__add__new_element()
            code += add_code
            code += "\t" + key + " = " + elem_name + ";"
            self._js_elements[key] = self._js_elements[elem_name]
        elif method == "MIX_REFERENCES":
            code += self._js_elements[key]
        elif method == "className":
            code += self._js_elements[key].prop_className() + ' = "' + random.choice(FuzzValues.STRINGS) + '";'
        elif method == "contentEditable":
            code += self._js_elements[key].prop_contentEditable() + " = " + random.choice(FuzzValues.BOOL) + ";"
        elif method == "dir":
            code += self._js_elements[key].prop_dir() + ' = "' + random.choice(FuzzValues.TEXT_DIRECTION) + '";'
        elif method == "id":
            code += self._js_elements[key].prop_id() + ' = "' + random.choice(FuzzValues.STRINGS) + '";'
        elif method == "innerHTML":
            code += self._js_elements[key].prop_innerHtml() + ' = "' + random.choice(FuzzValues.STRINGS) + '";'
        elif method == "lang":
            code += self._js_elements[key].prop_lang() + ' = "' + random.choice(FuzzValues.LANG_CODES) + '";'
        elif method == "scrollLeft":
            code += self._js_elements[key].prop_scrollLeft() + ' = "' + random.choice(FuzzValues.INTS) + '";'
        elif method == "scrollTop":
            code += self._js_elements[key].prop_scrollTop() + ' = "' + random.choice(FuzzValues.INTS) + '";'
        elif method == "style":
            value = random.choice(FuzzValues.CSS_STYLES)
            if "-" in value[0]:
                pos = value[0].find("-")
                value[0] = value[0].replace("-", "")
                value[0] = value[0][0 : pos - 1] + value[0][pos].upper() + value[0][pos + 1 :]
            code += self._js_elements[key].prop_style() + "." + value[0] + ' = "' + random.choice(value[1:]) + '";'
        elif method == "tabIndex":
            code += self._js_elements[key].prop_tabIndex() + " = " + str(random.randint(-20, 20)) + ";"
        elif method == "textContent":
            code += self._js_elements[key].prop_textContent() + ' = "' + random.choice(FuzzValues.STRINGS) + '";'
        elif method == "title":
            code += self._js_elements[key].prop_title() + ' = "' + random.choice(FuzzValues.STRINGS) + '";'
        self._operations_count += 1
        if random.randint(1, 10000) < 50:
            code += "CollectGarbage();"
        return code
Ejemplo n.º 2
0
class JsDomFuzzer(Fuzzer):
    NAME = "js_dom_fuzzer"
    CONFIG_PARAMS = ["starting_elements", "total_operations", "browser", "seed", "canvas_size", "file_type"]
    CALLING_COMMENT = "//FUNCTION_CALLING"
    TIMEOUT = 20

    def __init__(self, starting_elements, total_operations, browser, seed, canvas_size, file_type='html'):
        self._starting_elements = int(starting_elements)
        self._total_operations = int(total_operations)
        self._browser = browser
        seed = int(seed)
        #  self._html_fuzzer = HtmlFuzzer(self._starting_elements, 3, seed)
        self._html_fuzzer = Html5Fuzzer(int(seed), self._starting_elements, 10, 5, file_type)
        self._css_fuzzer = CssFuzzer(seed)
        self._canvas_fuzzer = CanvasFuzzer(int(canvas_size))
        if seed == 0:
            random.seed()
        else:
            random.seed(seed)
        self._file_type = file_type
        self._function_count = 0
        self._operations_count = 0
        self._js_elements = {}
        """:type dict(JsElement)"""
        self._occurring_events = {}
        for event in DomObjectTypes.DOM_EVENTS:
            self._occurring_events[event] = 0
        self._html_page = None
        self._calls_in_startup = []
        # arrays dictionary layout: {'array_id': [JsObject, .... JsObject], ...}
        self._arrays = {}

    @classmethod
    def from_list(cls, params):
        return cls(params[0], params[1], params[2], params[3], params[4], params[5])

    @property
    def prng_state(self):
        return random.getstate()

    @property
    def file_type(self):
        return self._file_type

    def set_seed(self, seed=0):
        random.seed(seed)

    def __re_init(self):
        self._function_count = 0
        self._operations_count = 0
        self._function_count = 0
        self._operations_count = 0
        self._js_elements = {}
        self._calls_in_startup = []
        self._arrays = []
        self._occurring_events = {}
        for event in DomObjectTypes.DOM_EVENTS:
            self._occurring_events[event] = 0

    def create_testcases(self, count, directory):
        for i in range(count):
            test_name = "/test" + str(i) if i > 9 else "/test0" + str(i)
            with open(directory + test_name + "." + self._file_type, "wb+") as html_fd, open(directory + test_name + ".css", "wb+") as css_fd:
                html, css = self.fuzz()
                html = html.replace("TESTCASE", test_name)
                html_fd.write(html)
                css_fd.write(css)

    def fuzz(self):
        self._html_page = self._html_fuzzer.fuzz()
        html = self._html_page.get_raw_html()
        self._css_fuzzer.set_tags(self._html_page.get_elements_by_html_tag().keys())
        css = self._css_fuzzer.fuzz()
        js_code = ""
        js_code += self.__create_canvas_functions()
        js_code += self.__create_startup()
        while self._total_operations > self._operations_count:
            js_code += self.__add_function()
        js_code += self.__add_event_dispatcher()
        js_code += self.__create_event_handlers()
        js_code = js_code.replace(self.CALLING_COMMENT, self.__concate_startup_list())
        doc = html.replace("SCRIPT_BODY", js_code)
        self.__re_init()
        return doc, css

    def set_state(self, state):
        random.setstate(state)

    def __create_startup(self):
        code = "function startup() {\n"
        i = 0
        for elem_id in self._html_page.get_element_ids():
            code += "\t" + "elem" + str(i) + " = " + JsDocument.getElementById(elem_id) + "\n"
            self._js_elements["elem"+str(i)] = JsDomElement("elem" + str(i), self._html_page.get_element_by_id(elem_id))
            i += 1
        code += "\t" + self.CALLING_COMMENT + \
                "\n\tevent_firing();\n}\n"
        return code

    def __create_canvas_functions(self):
        code = ""
        for canvas_id in (self._html_page.get_elements_by_html_tag())['canvas']:
            self._calls_in_startup.append("\tfunc_" + canvas_id + "();")
            self._canvas_fuzzer.set_canvas_id(canvas_id)
            code += self._canvas_fuzzer.fuzz()
        return code

    def __add_function(self, func_name=None, event=False):
        if not func_name:
            func_name = "func_" + str(self._function_count) + "()"
        code = "function " + func_name + " {\n"
        func_count = random.randint(10, 50)
        for i in range(func_count):
            code += "\t" + JsGlobal.try_catch_block(self.__add_element_method())
        if not event:
            self._function_count += 1
            if random.randint(0, 10) <= 3:
                code += "\t" + JsWindow.setTimeout("func_" + str(self._function_count) + "()", self.TIMEOUT) + "\n"
            else:
                self._calls_in_startup.append("\tfunc_" + str(self._function_count) + "();")
        code += "}\n"
        return code

    def __create_event_handlers(self):
        code = ""
        for event in self._occurring_events:
            code += self.__add_function(event + "_handler" + "(event)", True)
        return code

    def __add_event_dispatcher(self):
        code = "function event_firing() {\n"
        for key in self._js_elements:
            for event in self._js_elements[key].registered_events.keys():
                if 'DOM' in event:
                    continue
                elif event == 'click':
                    code += JsGlobal.try_catch_block(self._js_elements[key].click() + "\n", "ex")
                elif event == 'error':
                    pass
                elif event == 'load':
                    pass
                elif event == 'scroll':
                    code += JsGlobal.try_catch_block(self._js_elements[key].scrollLeft() + " = 10;" + "\n", "ex")
                elif event == 'resize' or event == 'change':
                    code += JsGlobal.try_catch_block(self._js_elements[key].innerHtml() + " = \"" + "A" * 100 + "\";\n", "ex")
                elif event == 'focus' or event == 'focusin':
                    code += JsGlobal.try_catch_block(self._js_elements[key].focus() + "\n", "ex")
                elif event == 'blur':
                    code += JsGlobal.try_catch_block(self._js_elements[key].blur() + "\n", "ex")
                elif event == 'select':
                    code += JsGlobal.try_catch_block(self._js_elements[key].select() + "\n", "ex")
        code += "}\n"
        return code

    def __add__new_element(self):
        elem_name = "elem_cr" + str(len(self._js_elements))
        html_type = random.choice(HTML_OBJECTS)
        code = elem_name + " = " + JsDocument.createElement(html_type) + "\n"
        self._js_elements[elem_name] = JsDomElement(elem_name, html_type)
        return elem_name, code, html_type

    def __add_element_method(self, key=None):
        code = ""
        if not key:
            key = random.choice(self._js_elements.keys())
        method = random.choice(DomObjectTypes.DOM_ELEMENT_FUZZ_STUFF)
        if method == 'addEventListener':
            event = random.choice(DomObjectTypes.DOM_EVENTS)
            self._occurring_events[event] += 1
            code += self._js_elements[key].addEventListener(event, event + "_handler")
        elif method == 'appendChild':
            if random.randint(1, 100) < 80:
                child = random.choice(self._js_elements.keys())
                if child == key:
                    elem_name, add_code, html_type = self.__add__new_element()
                    code += add_code
                    self._js_elements[elem_name] = JsDomElement(elem_name, self._js_elements[key].html_type)
                    child = elem_name
                code += self._js_elements[key].appendChild(child)
            else:
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                self._js_elements[elem_name] = JsDomElement(elem_name, html_type)
                code += self._js_elements[key].appendChild(elem_name)
        elif method == 'cloneNode':
            length = len(self._js_elements)
            elem_name = "elem_cr" + str(length)
            code += elem_name + " = " + self._js_elements[key].cloneNode(True)
            self._js_elements[elem_name] = JsDomElement(elem_name, self._js_elements[key].html_type)
            self._js_elements[elem_name].set_children(self._js_elements[key].get_children())
        elif method == 'hasAttribute':
            code += self._js_elements[key].hasAttribute(random.choice(HTML_ATTR_GENERIC))
        elif method == 'hasChildNode':
            code += self._js_elements[key].hasChildNodes()
        elif method == 'insertBefore':
            if not self._js_elements[key].get_children():
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += "\t" + self._js_elements[key].appendChild(elem_name) + "\n"
            elem_name, add_code, html_type = self.__add__new_element()
            code += add_code
            code += self._js_elements[key].insertBefore(elem_name, random.choice(self._js_elements[key].get_children()))
        elif method == 'normalize':
            code += self._js_elements[key].normalize()
        elif method == 'removeAttribute':
            if not self._js_elements[key].attributes:
                code += self._js_elements[key].setAttribute(random.choice(HTML_ATTR_GENERIC),
                                                            random.choice(FuzzValues.INTERESTING_VALUES))
            else:
                code += self._js_elements[key].removeAttribute(random.choice(self._js_elements[key].attributes.keys()))
        elif method == 'removeChild':
            if not self._js_elements[key].get_children():
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].appendChild(elem_name)
            else:
                code += self._js_elements[key].removeChild(random.choice(self._js_elements[key].get_children()))
        elif method == 'replaceChild':
            if not self._js_elements[key].get_children():
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].appendChild(elem_name)
            else:
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].replaceChild(elem_name,
                                                            random.choice(self._js_elements[key].get_children()))
        elif method == 'removeEventListener':
            if not self._js_elements[key].registered_events:
                event = random.choice(DomObjectTypes.DOM_EVENTS)
                self._occurring_events[event] += 1
                code += self._js_elements[key].addEventListener(event, event + "_handler")
            else:
                event = random.choice(self._js_elements[key].registered_events.keys())
                self._occurring_events[event] -= 1
                event = random.choice(self._js_elements[key].registered_events.keys())
                code += self._js_elements[key].removeEventListener(event,
                                                                   self._js_elements[key].registered_events[event])
        elif method == 'setAttribute':
            attr = random.choice(HTML_ATTR_GENERIC)
            if attr == 'style':
                val = ""
                for i in range(1, 50):
                    css = random.choice(CSS_STYLES)
                    val += css[0] + ": " + random.choice(css[1:]) + "; "
            else:
                val = random.choice(FuzzValues.INTERESTING_VALUES)
            code += self._js_elements[key].setAttribute(attr, val)
        elif method == 'REPLACE_EXIST_ELEMENT':
            elem_name, add_code, html_type = self.__add__new_element()
            code += add_code
            code += "\t" + key + " = " + elem_name + ";"
            self._js_elements[key] = self._js_elements[elem_name]
        elif method == 'MIX_REFERENCES':
            code += self._js_elements[key]
        elif method == 'className':
            code += self._js_elements[key].className() + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'contentEditable':
            code += self._js_elements[key].contentEditable() + " = " + random.choice(FuzzValues.BOOL) + ";"
        elif method == 'dir':
            code += self._js_elements[key].dir() + " = \"" + random.choice(FuzzValues.TEXT_DIRECTION) + "\";"
        elif method == 'id':
            code += self._js_elements[key].id() + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'innerHTML':
            code += self._js_elements[key].innerHtml() + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'lang':
            code += self._js_elements[key].lang() + " = \"" + random.choice(FuzzValues.LANG_CODES) + "\";"
        elif method == 'scrollLeft':
            code += self._js_elements[key].scrollLeft() + " = \"" + random.choice(FuzzValues.INTS) + "\";"
        elif method == 'scrollTop':
            code += self._js_elements[key].scrollTop() + " = \"" + random.choice(FuzzValues.INTS) + "\";"
        elif method == 'style':
            value = random.choice(CSS_STYLES)
            if "-" in value[0]:
                pos = value[0].find("-")
                value[0] = value[0].replace("-", "")
                value[0] = value[0][0:pos-1] + value[0][pos].upper() + value[0][pos+1:]
            code += self._js_elements[key].style() + "." + value[0] + " = \"" + random.choice(value[1:]) + "\";"
        elif method == 'tabIndex':
            code += self._js_elements[key].tabIndex() + " = " + str(random.randint(-20, 20)) + ";"
        elif method == 'textContent':
            code += self._js_elements[key].textContent() + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'title':
            code += self._js_elements[key].title() + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        self._operations_count += 1
        if random.randint(1, 10000) < 50:
            code += "CollectGarbage();"
        return code

    def __build_array(self, length=0):
        array_id = "array_" + str(len(self._arrays.keys()))
        self._arrays[array_id] = []
        code = array_id + " = ["
        array_length = length if length != 0 else random.randint(1, len(self._js_elements.keys()) / 2)
        for i in range(array_length):
            element_to_add = random.choice(self._js_elements.keys())
            self._arrays[array_id].append(self._js_elements[element_to_add])
            code += element_to_add + ","
        code = code[:-1] + "];\n"
        return code

    def __create_for_loop(self):
        pass

    def __create_if_clause(self):
        pass

    def __concate_startup_list(self):
        code = ""
        for item in self._calls_in_startup[:-1]:
            if random.randint(0,10) < 5:
                code += item + "\n"
            else:
                code += "\t" + JsWindow.setTimeout(item, self.TIMEOUT)
        return code
Ejemplo n.º 3
0
class JsDomFuzzer(Fuzzer):
    NAME = "js_dom_fuzzer"
    CONFIG_PARAMS = [
        "starting_elements", "total_operations", "browser", "seed", "file_type"
    ]

    def __init__(self,
                 starting_elements,
                 total_operations,
                 browser,
                 seed=31337,
                 file_type='html'):
        self._starting_elements = int(starting_elements)
        self._total_operations = int(total_operations)
        self._browser = browser
        seed = int(seed)
        #  self._html_fuzzer = HtmlFuzzer(self._starting_elements, 3, seed)
        self._html_fuzzer = Html5Fuzzer(int(seed), self._starting_elements, 10,
                                        5, file_type)
        self._css_fuzzer = CssFuzzer(seed)
        if seed == 0:
            random.seed()
        else:
            random.seed(seed)
        self._file_type = file_type
        self._function_count = 0
        self._operations_count = 0
        self._js_elements = {}
        """:type dict(JsElement)"""
        self._window_timeout = 20
        self._occurring_events = {}
        for event in DomObjects.DOM_EVENTS:
            self._occurring_events[event] = 0

    @classmethod
    def from_list(cls, params):
        return cls(params[0], params[1], params[2], params[3], params[4])

    @property
    def prng_state(self):
        return random.getstate()

    @property
    def file_type(self):
        return self._file_type

    @staticmethod
    def __get_html_ids(html):
        start = html.find("IDS:") + 5
        end = html.find("-->")
        ids = html[start:end].split("; ")
        del (ids[-1])
        return ids

    def set_seed(self, seed=0):
        random.seed(seed)

    def __reinit(self):
        self._function_count = 0
        self._operations_count = 0
        self._function_count = 0
        self._operations_count = 0
        self._js_elements = {}
        """:type dict(JsElement)"""
        self._window_timeout = 20
        self._occurring_events = {}
        for event in DomObjects.DOM_EVENTS:
            self._occurring_events[event] = 0

    def create_testcases(self, count, directory):
        for i in range(count):
            test_name = "/test" + str(i) if i > 9 else "/test0" + str(i)
            with open(directory + test_name + "." + self._file_type,
                      "wb+") as html_fd, open(directory + test_name + ".css",
                                              "wb+") as css_fd:
                html, css = self.fuzz()
                html = html.replace("TESTCASE", test_name)
                html_fd.write(html)
                css_fd.write(css)

    def fuzz(self):
        html = self._html_fuzzer.fuzz()
        self._css_fuzzer.set_tags(self._html_fuzzer.tags)
        css = self._css_fuzzer.fuzz()
        ids = self._html_fuzzer.elem_ids
        js_code = self.__create_startup(ids)
        while self._total_operations > self._operations_count:
            js_code += self.__add_function()
        js_code = js_code.replace(
            Window.setTimeout("func" + str(self._function_count) + "()",
                              self._window_timeout), "event_firing()")
        js_code += self.__add_event_dipatcher()
        js_code += self.__add_event_handlers()
        doc = html.replace("SCRIPT_BODY", js_code)
        self.__reinit()
        return (doc, css)

    def set_state(self, state):
        random.setstate(state)

    def __create_startup(self, elem_ids):
        code = "function startup() {\n"
        i = 0
        for elem_id in elem_ids:
            code += "\t" + "elem" + str(i) + " = " + JsDocument.getElementById(
                elem_id) + "\n"
            self._js_elements["elem" + str(i)] = JsElement("elem" + str(i))
            i += 1
        code += "\t" + Window.setTimeout("func0" + "()",
                                         self._window_timeout) + "\n}\n"
        return code

    def __add_function(self, func_name=None, event=False):
        if not func_name:
            func_name = "func" + str(self._function_count) + "()"
        code = "function " + func_name + " {\n"
        func_count = random.randint(10, 50)
        for i in range(func_count):
            code += "\t" + JsGlobal.try_catch_block(
                self.__add_element_method())
        if not event:
            self._function_count += 1
            code += "\t" + Window.setTimeout(
                "func" + str(self._function_count) + "()",
                self._window_timeout) + " \n"
        code += "}\n"
        return code

    def __add_event_handlers(self):
        code = ""
        for event in self._occurring_events:
            code += self.__add_function(event + "_handler" + "(event)", True)
        return code

    def __add_event_dipatcher(self):
        code = "function event_firing() {\n"
        for key in self._js_elements:
            for event in self._js_elements[key].registered_events.keys():
                if 'DOM' in event:
                    continue
                elif event == 'click':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].click() + "\n", "ex")
                elif event == 'error':
                    pass
                elif event == 'load':
                    pass
                elif event == 'scroll':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].prop_scrollLeft() + " = 10;" +
                        "\n", "ex")
                elif event == 'resize' or event == 'change':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].prop_innerHtml() + " = \"" +
                        "A" * 100 + "\";\n", "ex")
                elif event == 'focus' or event == 'focusin':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].focus() + "\n", "ex")
                elif event == 'blur':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].blur() + "\n", "ex")
                elif event == 'select':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].select() + "\n", "ex")
        code += "}\n"
        return code

    def __add__new_element(self):
        elem_name = "elem_cr" + str(len(self._js_elements))
        code = elem_name + " = " + JsDocument.createElement(
            random.choice(HtmlObjects.HTML_OBJECTS)) + "\n"
        self._js_elements[elem_name] = JsElement(elem_name)
        return elem_name, code

    def __add_element_method(self, key=None):
        code = ""
        if not key:
            key = random.choice(self._js_elements.keys())
        method = random.choice(DomObjects.DOM_ELEMENT_FUZZ_STUFF)
        if method == 'addEventListener':
            event = random.choice(DomObjects.DOM_EVENTS)
            self._occurring_events[event] += 1
            code += self._js_elements[key].addEventListener(
                event, event + "_handler")
        elif method == 'appendChild':
            if random.randint(1, 100) < 80:
                child = random.choice(self._js_elements.keys())
                if child == key:
                    elem_name, add_code = self.__add__new_element()
                    code += add_code
                    self._js_elements[elem_name] = JsElement(elem_name)
                    child = elem_name
                code += self._js_elements[key].appendChild(child)
            else:
                elem_name, add_code = self.__add__new_element()
                code += add_code
                self._js_elements[elem_name] = JsElement(elem_name)
                code += self._js_elements[key].appendChild(elem_name)
        elif method == 'cloneNode':
            length = len(self._js_elements)
            elem_name = "elem_cr" + str(length)
            code += elem_name + " = " + self._js_elements[key].cloneNode(True)
            self._js_elements[elem_name] = JsElement(elem_name)
            self._js_elements[elem_name].set_children(
                self._js_elements[key].get_children())
        elif method == 'hasAttribute':
            code += self._js_elements[key].hasAttribute(
                random.choice(HtmlObjects.HTML_ATTR_GENERIC))
        elif method == 'hasChildNode':
            code += self._js_elements[key].hasChildNodes()
        elif method == 'insertBefore':
            if not self._js_elements[key].get_children():
                elem_name, add_code = self.__add__new_element()
                code += add_code
                code += "\t" + self._js_elements[key].appendChild(
                    elem_name) + "\n"
            elem_name, add_code = self.__add__new_element()
            code += add_code
            code += self._js_elements[key].insertBefore(
                elem_name,
                random.choice(self._js_elements[key].get_children()))
        elif method == 'normalize':
            code += self._js_elements[key].normalize()
        elif method == 'removeAttribute':
            if not self._js_elements[key].attributes:
                code += self._js_elements[key].setAttribute(
                    random.choice(HtmlObjects.HTML_ATTR_GENERIC),
                    random.choice(FuzzValues.INTERESTING_VALUES))
            else:
                code += self._js_elements[key].removeAttribute(
                    random.choice(self._js_elements[key].attributes.keys()))
        elif method == 'removeChild':
            if not self._js_elements[key].get_children():
                elem_name, add_code = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].appendChild(elem_name)
            else:
                code += self._js_elements[key].removeChild(
                    random.choice(self._js_elements[key].get_children()))
        elif method == 'replaceChild':
            if not self._js_elements[key].get_children():
                elem_name, add_code = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].appendChild(elem_name)
            else:
                elem_name, add_code = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].replaceChild(
                    elem_name,
                    random.choice(self._js_elements[key].get_children()))
        elif method == 'removeEventListener':
            if not self._js_elements[key].registered_events:
                event = random.choice(DomObjects.DOM_EVENTS)
                self._occurring_events[event] += 1
                code += self._js_elements[key].addEventListener(
                    event, event + "_handler")
            else:
                event = random.choice(
                    self._js_elements[key].registered_events.keys())
                self._occurring_events[event] -= 1
                event = random.choice(
                    self._js_elements[key].registered_events.keys())
                code += self._js_elements[key].removeEventListener(
                    event, self._js_elements[key].registered_events[event])
        elif method == 'setAttribute':
            attr = random.choice(HtmlObjects.HTML_ATTR_GENERIC)
            if attr == 'style':
                val = ""
                for i in range(1, 50):
                    css = random.choice(FuzzValues.CSS_STYLES)
                    val += css[0] + ": " + random.choice(css[1:]) + "; "
            else:
                val = random.choice(FuzzValues.INTERESTING_VALUES)
            code += self._js_elements[key].setAttribute(attr, val)
        elif method == 'REPLACE_EXIST_ELEMENT':
            elem_name, add_code = self.__add__new_element()
            code += add_code
            code += "\t" + key + " = " + elem_name + ";"
            self._js_elements[key] = self._js_elements[elem_name]
        elif method == 'MIX_REFERENCES':
            code += self._js_elements[key]
        elif method == 'className':
            code += self._js_elements[key].prop_className(
            ) + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'contentEditable':
            code += self._js_elements[key].prop_contentEditable(
            ) + " = " + random.choice(FuzzValues.BOOL) + ";"
        elif method == 'dir':
            code += self._js_elements[key].prop_dir(
            ) + " = \"" + random.choice(FuzzValues.TEXT_DIRECTION) + "\";"
        elif method == 'id':
            code += self._js_elements[key].prop_id() + " = \"" + random.choice(
                FuzzValues.STRINGS) + "\";"
        elif method == 'innerHTML':
            code += self._js_elements[key].prop_innerHtml(
            ) + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'lang':
            code += self._js_elements[key].prop_lang(
            ) + " = \"" + random.choice(FuzzValues.LANG_CODES) + "\";"
        elif method == 'scrollLeft':
            code += self._js_elements[key].prop_scrollLeft(
            ) + " = \"" + random.choice(FuzzValues.INTS) + "\";"
        elif method == 'scrollTop':
            code += self._js_elements[key].prop_scrollTop(
            ) + " = \"" + random.choice(FuzzValues.INTS) + "\";"
        elif method == 'style':
            value = random.choice(FuzzValues.CSS_STYLES)
            if "-" in value[0]:
                pos = value[0].find("-")
                value[0] = value[0].replace("-", "")
                value[0] = value[0][0:pos -
                                    1] + value[0][pos].upper() + value[0][pos +
                                                                          1:]
            code += self._js_elements[key].prop_style(
            ) + "." + value[0] + " = \"" + random.choice(value[1:]) + "\";"
        elif method == 'tabIndex':
            code += self._js_elements[key].prop_tabIndex() + " = " + str(
                random.randint(-20, 20)) + ";"
        elif method == 'textContent':
            code += self._js_elements[key].prop_textContent(
            ) + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'title':
            code += self._js_elements[key].prop_title(
            ) + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        self._operations_count += 1
        if random.randint(1, 10000) < 50:
            code += "CollectGarbage();"
        return code
Ejemplo n.º 4
0
class JsDomFuzzer(Fuzzer):
    NAME = "js_dom_fuzzer"
    CONFIG_PARAMS = [
        "starting_elements", "total_operations", "browser", "seed",
        "canvas_size", "file_type"
    ]
    CALLING_COMMENT = "//FUNCTION_CALLING"
    TIMEOUT = 20

    def __init__(self,
                 starting_elements,
                 total_operations,
                 browser,
                 seed,
                 canvas_size,
                 file_type='html'):
        self._starting_elements = int(starting_elements)
        self._total_operations = int(total_operations)
        self._browser = browser
        seed = int(seed)
        #  self._html_fuzzer = HtmlFuzzer(self._starting_elements, 3, seed)
        self._html_fuzzer = Html5Fuzzer(int(seed), self._starting_elements, 10,
                                        5, file_type)
        self._css_fuzzer = CssFuzzer(seed)
        self._canvas_fuzzer = CanvasFuzzer(int(canvas_size))
        if seed == 0:
            random.seed()
        else:
            random.seed(seed)
        self._file_type = file_type
        self._function_count = 0
        self._operations_count = 0
        self._js_elements = {}
        """:type dict(JsElement)"""
        self._occurring_events = {}
        for event in DomObjectTypes.DOM_EVENTS:
            self._occurring_events[event] = 0
        self._html_page = None
        self._calls_in_startup = []
        # arrays dictionary layout: {'array_id': [JsObject, .... JsObject], ...}
        self._arrays = {}

    @classmethod
    def from_list(cls, params):
        return cls(params[0], params[1], params[2], params[3], params[4],
                   params[5])

    @property
    def prng_state(self):
        return random.getstate()

    @property
    def file_type(self):
        return self._file_type

    def set_seed(self, seed=0):
        random.seed(seed)

    def __re_init(self):
        self._function_count = 0
        self._operations_count = 0
        self._function_count = 0
        self._operations_count = 0
        self._js_elements = {}
        self._calls_in_startup = []
        self._arrays = []
        self._occurring_events = {}
        for event in DomObjectTypes.DOM_EVENTS:
            self._occurring_events[event] = 0

    def create_testcases(self, count, directory):
        for i in range(count):
            test_name = "/test" + str(i) if i > 9 else "/test0" + str(i)
            with open(directory + test_name + "." + self._file_type,
                      "wb+") as html_fd, open(directory + test_name + ".css",
                                              "wb+") as css_fd:
                html, css = self.fuzz()
                html = html.replace("TESTCASE", test_name)
                html_fd.write(html)
                css_fd.write(css)

    def fuzz(self):
        self._html_page = self._html_fuzzer.fuzz()
        html = self._html_page.get_raw_html()
        self._css_fuzzer.set_tags(
            self._html_page.get_elements_by_html_tag().keys())
        css = self._css_fuzzer.fuzz()
        js_code = ""
        js_code += self.__create_canvas_functions()
        js_code += self.__create_startup()
        while self._total_operations > self._operations_count:
            js_code += self.__add_function()
        js_code += self.__add_event_dispatcher()
        js_code += self.__create_event_handlers()
        js_code = js_code.replace(self.CALLING_COMMENT,
                                  self.__concate_startup_list())
        doc = html.replace("SCRIPT_BODY", js_code)
        self.__re_init()
        return doc, css

    def set_state(self, state):
        random.setstate(state)

    def __create_startup(self):
        code = "function startup() {\n"
        i = 0
        for elem_id in self._html_page.get_element_ids():
            code += "\t" + "elem" + str(i) + " = " + JsDocument.getElementById(
                elem_id) + "\n"
            self._js_elements["elem" + str(i)] = JsDomElement(
                "elem" + str(i), self._html_page.get_element_by_id(elem_id))
            i += 1
        code += "\t" + self.CALLING_COMMENT + \
                "\n\tevent_firing();\n}\n"
        return code

    def __create_canvas_functions(self):
        code = ""
        for canvas_id in (
                self._html_page.get_elements_by_html_tag())['canvas']:
            self._calls_in_startup.append("\tfunc_" + canvas_id + "();")
            self._canvas_fuzzer.set_canvas_id(canvas_id)
            code += self._canvas_fuzzer.fuzz()
        return code

    def __add_function(self, func_name=None, event=False):
        if not func_name:
            func_name = "func_" + str(self._function_count) + "()"
        code = "function " + func_name + " {\n"
        func_count = random.randint(10, 50)
        for i in range(func_count):
            code += "\t" + JsGlobal.try_catch_block(
                self.__add_element_method())
        if not event:
            self._function_count += 1
            if random.randint(0, 10) <= 3:
                code += "\t" + JsWindow.setTimeout(
                    "func_" + str(self._function_count) + "()",
                    self.TIMEOUT) + "\n"
            else:
                self._calls_in_startup.append("\tfunc_" +
                                              str(self._function_count) +
                                              "();")
        code += "}\n"
        return code

    def __create_event_handlers(self):
        code = ""
        for event in self._occurring_events:
            code += self.__add_function(event + "_handler" + "(event)", True)
        return code

    def __add_event_dispatcher(self):
        code = "function event_firing() {\n"
        for key in self._js_elements:
            for event in self._js_elements[key].registered_events.keys():
                if 'DOM' in event:
                    continue
                elif event == 'click':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].click() + "\n", "ex")
                elif event == 'error':
                    pass
                elif event == 'load':
                    pass
                elif event == 'scroll':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].scrollLeft() + " = 10;" + "\n",
                        "ex")
                elif event == 'resize' or event == 'change':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].innerHtml() + " = \"" +
                        "A" * 100 + "\";\n", "ex")
                elif event == 'focus' or event == 'focusin':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].focus() + "\n", "ex")
                elif event == 'blur':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].blur() + "\n", "ex")
                elif event == 'select':
                    code += JsGlobal.try_catch_block(
                        self._js_elements[key].select() + "\n", "ex")
        code += "}\n"
        return code

    def __add__new_element(self):
        elem_name = "elem_cr" + str(len(self._js_elements))
        html_type = random.choice(HTML_OBJECTS)
        code = elem_name + " = " + JsDocument.createElement(html_type) + "\n"
        self._js_elements[elem_name] = JsDomElement(elem_name, html_type)
        return elem_name, code, html_type

    def __add_element_method(self, key=None):
        code = ""
        if not key:
            key = random.choice(self._js_elements.keys())
        method = random.choice(DomObjectTypes.DOM_ELEMENT_FUZZ_STUFF)
        if method == 'addEventListener':
            event = random.choice(DomObjectTypes.DOM_EVENTS)
            self._occurring_events[event] += 1
            code += self._js_elements[key].addEventListener(
                event, event + "_handler")
        elif method == 'appendChild':
            if random.randint(1, 100) < 80:
                child = random.choice(self._js_elements.keys())
                if child == key:
                    elem_name, add_code, html_type = self.__add__new_element()
                    code += add_code
                    self._js_elements[elem_name] = JsDomElement(
                        elem_name, self._js_elements[key].html_type)
                    child = elem_name
                code += self._js_elements[key].appendChild(child)
            else:
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                self._js_elements[elem_name] = JsDomElement(
                    elem_name, html_type)
                code += self._js_elements[key].appendChild(elem_name)
        elif method == 'cloneNode':
            length = len(self._js_elements)
            elem_name = "elem_cr" + str(length)
            code += elem_name + " = " + self._js_elements[key].cloneNode(True)
            self._js_elements[elem_name] = JsDomElement(
                elem_name, self._js_elements[key].html_type)
            self._js_elements[elem_name].set_children(
                self._js_elements[key].get_children())
        elif method == 'hasAttribute':
            code += self._js_elements[key].hasAttribute(
                random.choice(HTML_ATTR_GENERIC))
        elif method == 'hasChildNode':
            code += self._js_elements[key].hasChildNodes()
        elif method == 'insertBefore':
            if not self._js_elements[key].get_children():
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += "\t" + self._js_elements[key].appendChild(
                    elem_name) + "\n"
            elem_name, add_code, html_type = self.__add__new_element()
            code += add_code
            code += self._js_elements[key].insertBefore(
                elem_name,
                random.choice(self._js_elements[key].get_children()))
        elif method == 'normalize':
            code += self._js_elements[key].normalize()
        elif method == 'removeAttribute':
            if not self._js_elements[key].attributes:
                code += self._js_elements[key].setAttribute(
                    random.choice(HTML_ATTR_GENERIC),
                    random.choice(FuzzValues.INTERESTING_VALUES))
            else:
                code += self._js_elements[key].removeAttribute(
                    random.choice(self._js_elements[key].attributes.keys()))
        elif method == 'removeChild':
            if not self._js_elements[key].get_children():
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].appendChild(elem_name)
            else:
                code += self._js_elements[key].removeChild(
                    random.choice(self._js_elements[key].get_children()))
        elif method == 'replaceChild':
            if not self._js_elements[key].get_children():
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].appendChild(elem_name)
            else:
                elem_name, add_code, html_type = self.__add__new_element()
                code += add_code
                code += self._js_elements[key].replaceChild(
                    elem_name,
                    random.choice(self._js_elements[key].get_children()))
        elif method == 'removeEventListener':
            if not self._js_elements[key].registered_events:
                event = random.choice(DomObjectTypes.DOM_EVENTS)
                self._occurring_events[event] += 1
                code += self._js_elements[key].addEventListener(
                    event, event + "_handler")
            else:
                event = random.choice(
                    self._js_elements[key].registered_events.keys())
                self._occurring_events[event] -= 1
                event = random.choice(
                    self._js_elements[key].registered_events.keys())
                code += self._js_elements[key].removeEventListener(
                    event, self._js_elements[key].registered_events[event])
        elif method == 'setAttribute':
            attr = random.choice(HTML_ATTR_GENERIC)
            if attr == 'style':
                val = ""
                for i in range(1, 50):
                    css = random.choice(CSS_STYLES)
                    val += css[0] + ": " + random.choice(css[1:]) + "; "
            else:
                val = random.choice(FuzzValues.INTERESTING_VALUES)
            code += self._js_elements[key].setAttribute(attr, val)
        elif method == 'REPLACE_EXIST_ELEMENT':
            elem_name, add_code, html_type = self.__add__new_element()
            code += add_code
            code += "\t" + key + " = " + elem_name + ";"
            self._js_elements[key] = self._js_elements[elem_name]
        elif method == 'MIX_REFERENCES':
            code += self._js_elements[key]
        elif method == 'className':
            code += self._js_elements[key].className(
            ) + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'contentEditable':
            code += self._js_elements[key].contentEditable(
            ) + " = " + random.choice(FuzzValues.BOOL) + ";"
        elif method == 'dir':
            code += self._js_elements[key].dir() + " = \"" + random.choice(
                FuzzValues.TEXT_DIRECTION) + "\";"
        elif method == 'id':
            code += self._js_elements[key].id() + " = \"" + random.choice(
                FuzzValues.STRINGS) + "\";"
        elif method == 'innerHTML':
            code += self._js_elements[key].innerHtml(
            ) + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'lang':
            code += self._js_elements[key].lang() + " = \"" + random.choice(
                FuzzValues.LANG_CODES) + "\";"
        elif method == 'scrollLeft':
            code += self._js_elements[key].scrollLeft(
            ) + " = \"" + random.choice(FuzzValues.INTS) + "\";"
        elif method == 'scrollTop':
            code += self._js_elements[key].scrollTop(
            ) + " = \"" + random.choice(FuzzValues.INTS) + "\";"
        elif method == 'style':
            value = random.choice(CSS_STYLES)
            if "-" in value[0]:
                pos = value[0].find("-")
                value[0] = value[0].replace("-", "")
                value[0] = value[0][0:pos -
                                    1] + value[0][pos].upper() + value[0][pos +
                                                                          1:]
            code += self._js_elements[key].style(
            ) + "." + value[0] + " = \"" + random.choice(value[1:]) + "\";"
        elif method == 'tabIndex':
            code += self._js_elements[key].tabIndex() + " = " + str(
                random.randint(-20, 20)) + ";"
        elif method == 'textContent':
            code += self._js_elements[key].textContent(
            ) + " = \"" + random.choice(FuzzValues.STRINGS) + "\";"
        elif method == 'title':
            code += self._js_elements[key].title() + " = \"" + random.choice(
                FuzzValues.STRINGS) + "\";"
        self._operations_count += 1
        if random.randint(1, 10000) < 50:
            code += "CollectGarbage();"
        return code

    def __build_array(self, length=0):
        array_id = "array_" + str(len(self._arrays.keys()))
        self._arrays[array_id] = []
        code = array_id + " = ["
        array_length = length if length != 0 else random.randint(
            1,
            len(self._js_elements.keys()) / 2)
        for i in range(array_length):
            element_to_add = random.choice(self._js_elements.keys())
            self._arrays[array_id].append(self._js_elements[element_to_add])
            code += element_to_add + ","
        code = code[:-1] + "];\n"
        return code

    def __create_for_loop(self):
        pass

    def __create_if_clause(self):
        pass

    def __concate_startup_list(self):
        code = ""
        for item in self._calls_in_startup[:-1]:
            if random.randint(0, 10) < 5:
                code += item + "\n"
            else:
                code += "\t" + JsWindow.setTimeout(item, self.TIMEOUT)
        return code