threats.pl > Bezpieczeństwo aplikacji internetowych > Lekcja 23: Oczyszczanie HTML jest trudne > Kod parsera

Kod parsera wykorzystany w przykładzie

Na potrzeby przykładu Oczyszczanie HTML jest trudne napisałem w Pythonie prosty parser HTML oparty na klasie HTMLParser. Kod parsera prezentuję poniżej. A tu dostępne są przykłady przypadków, w których parser ten nie zachowuje się zgodnie z oczekiwaniami: przykładowe rozwiązania.

Aktualny kod parsera

Aktualnie wykorzystywany kod parsera (patrz: Dlaczego przykład przestał działać).

class parser(HTMLParser):
    allowed_tags = ("p", "b", "i")
    output = ""
    a_opened = False
    
    def unescape(self, s):
        if '&' not in s:
            return s
        s = s.replace("<", "<")
        s = s.replace(">", ">")
        s = s.replace("'", "'")
        s = s.replace(""", '"')
        s = s.replace("&amp;", "&") # Must be last
        return s
    
    def handle_starttag(self, tag, attrs):
        if tag in self.allowed_tags:
            self.output += "<%s>" % tag
        elif tag == "a":
            for i in attrs:
                if i[0] == "href":
                    if not i[1].lower().startswith("javascript"):
                        self.a_opened = True
                        self.output += "<a href=\"%s\" title=\"%s\">" % (i[1], i[1])
        elif tag == "img":
            for i in attrs:
                if i[0] == "src":
                    self.output += "<img src=\"%s\" />"%i[1]
    
    def handle_endtag(self, tag):
        if tag in self.allowed_tags:
            self.output += "</%s>" % tag
        elif tag == "a" and self.a_opened:
            self.output += "</a>"
            self.a_opened = False
    
    def handle_data(self, data):
        self.output += data

Oryginalny kod parsera wykorzystany w przykładzie

class parser(HTMLParser):
    allowed_tags = ("p", "b", "i")
    output = ""
    a_opened = False
    
    def handle_starttag(self, tag, attrs):
        if tag in self.allowed_tags:
            self.output += "<%s>" % tag
        elif tag == "a":
            for i in attrs:
                if i[0] == "href":
                    if not i[1].lower().startswith("javascript"):
                        self.a_opened = True
                        self.output += "<a href=\"%s\" title=\"%s\">" % (i[1], i[1])
        elif tag == "img":
            for i in attrs:
                if i[0] == "src":
                    self.output += "<img src=\"%s\" />"%i[1]
    
    def handle_endtag(self, tag):
        if tag in self.allowed_tags:
            self.output += "</%s>" % tag
        elif tag == "a" and self.a_opened:
            self.output += "</a>"
            self.a_opened = False
    
    def handle_data(self, data):
        self.output += data