Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
diff --git a/webapp/graphite/remote_storage.py b/webapp/graphite/remote_storage.py
index 693e0fd..d51d27c 100644
--- a/webapp/graphite/remote_storage.py
+++ b/webapp/graphite/remote_storage.py
@@ -5,11 +5,7 @@ from urllib import urlencode
from django.core.cache import cache
from django.conf import settings
from graphite.render.hashing import compactHash
-
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
+from graphite.util import unpickle
@@ -79,7 +75,7 @@ class FindRequest:
response = self.connection.getresponse()
assert response.status == 200, "received error response %s - %s" % (response.status, response.reason)
result_data = response.read()
- results = pickle.loads(result_data)
+ results = unpickle.loads(result_data)
except:
self.store.fail()
@@ -126,7 +122,7 @@ class RemoteNode:
assert response.status == 200, "Failed to retrieve remote data: %d %s" % (response.status, response.reason)
rawData = response.read()
- seriesList = pickle.loads(rawData)
+ seriesList = unpickle.loads(rawData)
assert len(seriesList) == 1, "Invalid result: seriesList=%s" % str(seriesList)
series = seriesList[0]
diff --git a/webapp/graphite/render/datalib.py b/webapp/graphite/render/datalib.py
index ef90812..af5bb43 100644
--- a/webapp/graphite/render/datalib.py
+++ b/webapp/graphite/render/datalib.py
@@ -18,11 +18,7 @@ import time
from django.conf import settings
from graphite.logger import log
from graphite.storage import STORE, LOCAL_STORE
-
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
+from graphite.util import unpickle
class TimeSeries(list):
@@ -162,7 +158,7 @@ class CarbonLinkPool:
self.putConnectionInPool(host, connection)
# Now parse the response
- points = pickle.loads(buf)
+ points = unpickle.loads(buf)
log.cache("CarbonLink to %s, retrieved %d points for %s" % (host,len(points),metric))
for point in points:
diff --git a/webapp/graphite/render/views.py b/webapp/graphite/render/views.py
index 7ad9b7f..87ed66a 100644
--- a/webapp/graphite/render/views.py
+++ b/webapp/graphite/render/views.py
@@ -23,7 +23,7 @@ try:
except ImportError:
import pickle
-from graphite.util import getProfileByUsername
+from graphite.util import getProfileByUsername, json, unpickle
from graphite.remote_storage import HTTPConnectionWithTimeout
from graphite.logger import log
from graphite.render.evaluator import evaluateTarget
@@ -270,7 +270,7 @@ def renderLocalView(request):
optionsPickle = reqParams.read()
reqParams.close()
graphClass = GraphTypes[graphType]
- options = pickle.loads(optionsPickle)
+ options = unpickle.loads(optionsPickle)
image = doImageRender(graphClass, options)
log.rendering("Delegated rendering request took %.6f seconds" % (time() - start))
return buildResponse(image)
diff --git a/webapp/graphite/storage.py b/webapp/graphite/storage.py
index eb641ad..ae3b34b 100644
--- a/webapp/graphite/storage.py
+++ b/webapp/graphite/storage.py
@@ -1,7 +1,9 @@
import os, time, fnmatch, socket, errno
+from django.conf import settings
from os.path import isdir, isfile, join, exists, splitext, basename, realpath
import whisper
from graphite.remote_storage import RemoteStore
+from graphite.util import unpickle
from django.conf import settings
try:
@@ -276,7 +278,7 @@ class WhisperFile(Leaf):
if exists(context_path):
fh = open(context_path, 'rb')
- context_data = pickle.load(fh)
+ context_data = unpickle.load(fh)
fh.close()
else:
context_data = {}
diff --git a/webapp/graphite/util.py b/webapp/graphite/util.py
index ada524d..54f425b 100644
--- a/webapp/graphite/util.py
+++ b/webapp/graphite/util.py
@@ -12,6 +12,18 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License."""
+try:
+ import cPickle as pickle
+ USING_CPICKLE = True
+except:
+ import pickle
+ USING_CPICKLE = False
+
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from StringIO import StringIO
+
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.models import User
from graphite.account.models import Profile
@@ -65,3 +77,52 @@ except Profile.DoesNotExist:
log.info("Default profile does not exist, creating it...")
defaultProfile = Profile(user=defaultUser)
defaultProfile.save()
+
+# This whole song & dance is due to pickle being insecure
+# The SafeUnpickler classes were largely derived from
+# http://nadiana.com/python-pickle-insecure
+# This code also lives in carbon.util
+if USING_CPICKLE:
+ class SafeUnpickler(object):
+ PICKLE_SAFE = {
+ 'copy_reg': set(['_reconstructor']),
+ '__builtin__': set(['object']),
+ }
+
+ @classmethod
+ def find_class(cls, module, name):
+ if not module in cls.PICKLE_SAFE:
+ raise pickle.UnpicklingError('Attempting to unpickle unsafe module %s' % module)
+ __import__(module)
+ mod = sys.modules[module]
+ if not name in cls.PICKLE_SAFE[module]:
+ raise pickle.UnpicklingError('Attempting to unpickle unsafe class %s' % name)
+ return getattr(mod, name)
+
+ @classmethod
+ def loads(cls, pickle_string):
+ pickle_obj = pickle.Unpickler(StringIO(pickle_string))
+ pickle_obj.find_global = cls.find_class
+ return pickle_obj.load()
+
+else:
+ class SafeUnpickler(pickle.Unpickler):
+ PICKLE_SAFE = {
+ 'copy_reg': set(['_reconstructor']),
+ '__builtin__': set(['object']),
+ }
+
+ def find_class(self, module, name):
+ if not module in self.PICKLE_SAFE:
+ raise pickle.UnpicklingError('Attempting to unpickle unsafe module %s' % module)
+ __import__(module)
+ mod = sys.modules[module]
+ if not name in self.PICKLE_SAFE[module]:
+ raise pickle.UnpicklingError('Attempting to unpickle unsafe class %s' % name)
+ return getattr(mod, name)
+
+ @classmethod
+ def loads(cls, pickle_string):
+ return cls(StringIO(pickle_string)).load()
+
+unpickle = SafeUnpickler
diff --git a/webapp/graphite/whitelist/views.py b/webapp/graphite/whitelist/views.py
index 5baec8d..36374d7 100644
--- a/webapp/graphite/whitelist/views.py
+++ b/webapp/graphite/whitelist/views.py
@@ -13,14 +13,12 @@ See the License for the specific language governing permissions and
limitations under the License."""
import os
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
from random import randint
from django.http import HttpResponse
from django.conf import settings
+from graphite.util import unpickle
+
def add(request):
metrics = set( request.POST['metrics'].split() )
@@ -43,7 +41,7 @@ def show(request):
def load_whitelist():
fh = open(settings.WHITELIST_FILE, 'rb')
- whitelist = pickle.load(fh)
+ whitelist = unpickle.load(fh)
fh.close()
return whitelist
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.