Skip to content

Commit

Permalink
Resolve RCE vulnerability in local WordNet browser (#3100)
Browse files Browse the repository at this point in the history
* Restrict wordnet app pickle loading: disallow functions and classes

* Resolve typo: where -> were

In an error message for the wordnet browser
  • Loading branch information
tomaarsen committed Jan 2, 2023
1 parent a199b8e commit 50be0b8
Showing 1 changed file with 14 additions and 10 deletions.
24 changes: 14 additions & 10 deletions nltk/app/wordnet_app.py
Expand Up @@ -47,11 +47,10 @@

import base64
import copy
import datetime
import getopt
import io
import os
import pickle
import re
import sys
import threading
import time
Expand All @@ -60,17 +59,12 @@
from http.server import BaseHTTPRequestHandler, HTTPServer

# Allow this program to run inside the NLTK source tree.
from sys import argv, path
from sys import argv
from urllib.parse import unquote_plus

from nltk.corpus import wordnet as wn
from nltk.corpus.reader.wordnet import Lemma, Synset

# now included in local file
# from util import html_header, html_trailer, \
# get_static_index_page, get_static_page_by_path, \
# page_from_word, page_from_href

firstClient = True

# True if we're not also running a web browser. The value f server_mode
Expand Down Expand Up @@ -659,6 +653,16 @@ def make_synset_html(db_name, disp_name, rels):
return html


class RestrictedUnpickler(pickle.Unpickler):
"""
Unpickler that prevents any class or function from being used during loading.
"""

def find_class(self, module, name):
# Forbid every function
raise pickle.UnpicklingError(f"global '{module}.{name}' is forbidden")


class Reference:
"""
A reference to a page that may be generated by page_word
Expand Down Expand Up @@ -694,7 +698,7 @@ def decode(string):
Decode a reference encoded with Reference.encode
"""
string = base64.urlsafe_b64decode(string.encode())
word, synset_relations = pickle.loads(string)
word, synset_relations = RestrictedUnpickler(io.BytesIO(string)).load()
return Reference(word, synset_relations)

def toggle_synset_relation(self, synset, relation):
Expand Down Expand Up @@ -794,7 +798,7 @@ def page_from_reference(href):
except KeyError:
pass
if not body:
body = "The word or words '%s' where not found in the dictionary." % word
body = "The word or words '%s' were not found in the dictionary." % word
return body, word


Expand Down

0 comments on commit 50be0b8

Please sign in to comment.