Exemplo n.º 1
0
    def handle_endtag(self, tag):

        tag = tag.lower()

        if DEBUG:  # pragma: no cover
            print "E: ", tag, self.xml_state

        if not self.xml_state:
            if "closing_tags" in self.reported or not self.strict:
                if DEBUG:
                    print "Unstrict; extra closing tags ------"
                return
            self.err.warning(
                err_id=("markup", "handle_endtag", "extra_closing_tags"),
                warning="Markup parsing error",
                description="The markup file has more closing tags than it "
                            "has opening tags.",
                filename=self.filename,
                line=self.line,
                context=self.context,
                tier=2)

            self.reported.add("closing_tags")
            if DEBUG:  # pragma: no cover
                print "Too many closing tags ------"
            return

        elif "script" in self.xml_state[:-1]:
            # If we're in a script tag, nothing else matters. Just rush
            # everything possible into the xml buffer.

            self._save_to_buffer("</%s>" % tag)
            if DEBUG:
                print "Markup as text in script ------"
            return

        elif tag not in self.xml_state:
            # If the tag we're processing isn't on the stack, then
            # something is wrong.
            self.err.warning(
                err_id=("markup", "handle_endtag", "extra_closing_tags"),
                warning="Parse error: tag closed before opened",
                description=["Markup tags cannot be closed before they are "
                             "opened. Perhaps you were just a little "
                             "overzealous with forward-slashes?",
                             'Tag `%s` closed before it was opened' % tag],
                filename=self.filename,
                line=self.line,
                context=self.context,
                tier=2)

            if DEBUG:  # pragma: no cover
                print "Tag closed before opened ------"
            return

        data_buffer = self.xml_buffer.pop()
        old_state = self.xml_state.pop()
        old_line = self.xml_line_stack.pop()

        # If the tag on the stack isn't what's being closed and it also
        # classifies as a self-closing tag, we just recursively close
        # down to the level of the tag we're actualy closing.
        if old_state != tag and old_state in SELF_CLOSING_TAGS:
            if DEBUG:
                print "Self closing tag cascading down ------"
            return self.handle_endtag(tag)

        # If this is an XML-derived language, everything must nest
        # properly. No overlapping tags.
        if (old_state != tag and self.extension[0] == 'x' and not self.strict):
            self.err.warning(
                err_id=("testcases_markup_markuptester", "handle_endtag",
                        "invalid_nesting"),
                warning="Markup invalidly nested",
                description="It has been determined that the document "
                            "invalidly nests its tags. This is not permitted "
                            "in the specified document type.",
                filename=self.filename,
                line=self.line,
                context=self.context,
                tier=2)
            if DEBUG:  # pragma: no cover
                print "Invalid markup nesting ------"

        data_buffer = data_buffer.strip()

        # Perform analysis on collected data.
        if data_buffer:
            if tag == "script":
                message_csp(err=self.err, filename=self.filename,
                            line=self.line, column=None,
                            context=self.context,
                            violation_type="inline_script",
                            severity="error")
            elif tag == "style":
                csstester.test_css_file(self.err, self.filename, data_buffer,
                                        old_line)
Exemplo n.º 2
0
    def handle_starttag(self, tag, attrs, self_closing=False):

        # Normalize!
        tag = tag.lower()

        # Be extra sure it's not a self-closing tag.
        if not self_closing:
            self_closing = tag in SELF_CLOSING_TAGS

        if DEBUG:  # pragma: no cover
            print "S: ", self.xml_state, tag, self_closing

        attr_dict = dict([(a[0].lower(), a[1]) for a in attrs if a[1]])

        if "style" in attr_dict:
            csstester.test_css_snippet(self.err, self.filename,
                                       attr_dict["style"], self.line)

        script_attributes = dict(
            (k, v) for k, v in attr_dict.iteritems() if k.startswith("on"))
        if script_attributes:
            if any(k in DOM_MUTATION_HANDLERS for k in script_attributes):
                self.err.error(
                    err_id=("testcases_markup_markuptester", "handle_starttag",
                            "dom_manipulation_handler"),
                    error="DOM Mutation Events Prohibited",
                    description="DOM mutation events are flagged because of "
                    "their deprecated status, as well as thier "
                    "extreme inefficiency. Consider using a "
                    "different event.",
                    filename=self.filename,
                    line=self.line,
                    context=self.context)

            message_csp(err=self.err,
                        filename=self.filename,
                        line=self.line,
                        column=None,
                        context=self.context,
                        violation_type="script_attribute",
                        severity="error")

        # When the dev forgets their <!-- --> on a script tag, bad
        # things happen.
        if "script" in self.xml_state and tag != "script":
            self._save_to_buffer("<" + tag + self._format_args(attrs) + ">")
            return

        elif (tag == "script"
              and ("type" not in attr_dict
                   or any(a[0] == "type" and "javascript" in a[1].lower()
                          for a in attrs))):
            # Inspect scripts which either have no type or have a type which
            # is JS.

            if "src" not in attr_dict:
                # CSP warnings for inline scripts
                message_csp(err=self.err,
                            filename=self.filename,
                            line=self.line,
                            column=None,
                            context=self.context,
                            violation_type="inline_script",
                            severity="error")

            elif not self._is_url_local(attr_dict.get("src", "")):
                # If there's a remote SRC, then that's a CSP violation.
                message_csp(err=self.err,
                            filename=self.filename,
                            line=self.line,
                            column=None,
                            context=self.context,
                            violation_type="remote_script",
                            severity="error")

        self.xml_state.append(tag)
        self.xml_line_stack.append(self.line)
        self.xml_buffer.append(u"")
Exemplo n.º 3
0
    def handle_starttag(self, tag, attrs, self_closing=False):

        # Normalize!
        tag = tag.lower()
        orig_tag = tag

        # Be extra sure it's not a self-closing tag.
        if not self_closing:
            self_closing = tag in SELF_CLOSING_TAGS

        if DEBUG:  # pragma: no cover
            print "S: ", self.xml_state, tag, self_closing

        # Find CSS and JS attributes and handle their values like they
        # would otherwise be handled by the standard parser flow.
        for attr in attrs:
            attr_name, attr_value = attr[0].lower(), attr[1]

            # We don't care about valueless attributes.
            if attr_value is None:
                continue

            if attr_name == "style":
                csstester.test_css_snippet(self.err,
                                           self.filename,
                                           attr_value,
                                           self.line)
            elif attr_name.startswith("on"):  # JS attribute
                # Warn about DOM mutation event handlers.
                if attr_name in DOM_MUTATION_HANDLERS:
                    self.err.error(
                        err_id=("testcases_markup_markuptester",
                                "handle_starttag",
                                "dom_manipulation_handler"),
                        error="DOM Mutation Events Prohibited",
                        description="DOM mutation events are flagged because "
                                    "of their deprecated status, as well as "
                                    "their extreme inefficiency. Consider "
                                    "using a different event.",
                        filename=self.filename,
                        line=self.line,
                        context=self.context)

                message_csp(err=self.err, filename=self.filename,
                            line=self.line, column=None,
                            context=self.context,
                            violation_type="script_attribute",
                            severity="error")

            elif attr_name == "src" and tag == "script":
                if not self._is_url_local(attr_value):
                    message_csp(err=self.err, filename=self.filename,
                                line=self.line, column=None,
                                context=self.context,
                                violation_type="remote_script",
                                severity="error")

        # When the dev forgets their <!-- --> on a script tag, bad
        # things happen.
        if "script" in self.xml_state and tag != "script":
            self._save_to_buffer("<" + tag + self._format_args(attrs) + ">")
            return

        self.xml_state.append(orig_tag)
        self.xml_line_stack.append(self.line)
        self.xml_buffer.append(unicode(""))
Exemplo n.º 4
0
    def handle_starttag(self, tag, attrs, self_closing=False):

        # Normalize!
        tag = tag.lower()

        # Be extra sure it's not a self-closing tag.
        if not self_closing:
            self_closing = tag in SELF_CLOSING_TAGS

        if DEBUG:  # pragma: no cover
            print "S: ", self.xml_state, tag, self_closing

        attr_dict = dict([(a[0].lower(), a[1]) for a in attrs if a[1]])

        if "style" in attr_dict:
            csstester.test_css_snippet(
                self.err, self.filename, attr_dict["style"], self.line)

        script_attributes = dict(
            (k, v) for k, v in attr_dict.iteritems() if k.startswith("on"))
        if script_attributes:
            if any(k in DOM_MUTATION_HANDLERS for k in script_attributes):
                self.err.error(
                    err_id=("testcases_markup_markuptester",
                            "handle_starttag", "dom_manipulation_handler"),
                    error="DOM Mutation Events Prohibited",
                    description="DOM mutation events are flagged because of "
                                "their deprecated status, as well as thier "
                                "extreme inefficiency. Consider using a "
                                "different event.",
                    filename=self.filename,
                    line=self.line,
                    context=self.context)

            message_csp(err=self.err, filename=self.filename,
                        line=self.line, column=None, context=self.context,
                        violation_type="script_attribute", severity="error")

        # When the dev forgets their <!-- --> on a script tag, bad
        # things happen.
        if "script" in self.xml_state and tag != "script":
            self._save_to_buffer("<" + tag + self._format_args(attrs) + ">")
            return

        elif (tag == "script" and
              ("type" not in attr_dict or
               any(a[0] == "type" and "javascript" in a[1].lower() for
                   a in attrs))):
            # Inspect scripts which either have no type or have a type which
            # is JS.

            if "src" not in attr_dict:
                # CSP warnings for inline scripts
                message_csp(err=self.err, filename=self.filename,
                            line=self.line, column=None,
                            context=self.context,
                            violation_type="inline_script",
                            severity="error")

            elif not self._is_url_local(attr_dict.get("src", "")):
                # If there's a remote SRC, then that's a CSP violation.
                message_csp(err=self.err, filename=self.filename,
                            line=self.line, column=None, context=self.context,
                            violation_type="remote_script", severity="error")

        self.xml_state.append(tag)
        self.xml_line_stack.append(self.line)
        self.xml_buffer.append(u"")