Browse Source

Added checksums util for markup

Rafał Pitoń 11 years ago
parent
commit
b79af19607
2 changed files with 54 additions and 0 deletions
  1. 37 0
      misago/markup/checksums.py
  2. 17 0
      misago/markup/tests.py

+ 37 - 0
misago/markup/checksums.py

@@ -0,0 +1,37 @@
+"""
+Misago saves parsed strings in database.
+
+Those strings are "trusted" and contain HTML that is rendered by templates
+without additional sanitization step.
+
+While this greatly improves speed, it also means that SQLInjections may
+escalate to Code Injection vulnerabilities.
+
+Because of this you should use this module to generate checksum for each model
+that contains parsed strings. Each checksum should be generated from markup as
+well as additional unique values that are specific for that model, like its PK,
+post date, etc ect.
+
+That way even if few items will contain the same content, they will have
+different checksums, and as long as attacker has no access to filesystem,
+he'll wont know SECRET_KEY and thus won't be able to generate valid checksums
+for injected content
+
+Because SHA256 is used for checksum generation, make sure you are storing them
+in char fields with max_length=64
+"""
+from hashlib import sha256
+
+from django.conf import settings
+
+
+def make_checksum(parsed, unique_values=None):
+    unique_values = unique_values or []
+    seeds = [parsed, settings.SECRET_KEY]
+    seeds.extend([unicode(v) for v in unique_values])
+
+    return sha256('+'.join(seeds)).hexdigest()
+
+
+def is_checksum_valid(parsed, checksum, unique_values=None):
+    return checksum == make_checksum(parsed, unique_values)

+ 17 - 0
misago/markup/tests.py

@@ -1,5 +1,6 @@
 from django.test import TestCase
 from django.test import TestCase
 from misago.markup.parser import parse
 from misago.markup.parser import parse
+from misago.markup import checksums
 
 
 
 
 class ParserTests(TestCase):
 class ParserTests(TestCase):
@@ -53,3 +54,19 @@ Dolor met.
 
 
         result = parse(test_text)
         result = parse(test_text)
         self.assertEqual(expected_result, result['parsed_text'])
         self.assertEqual(expected_result, result['parsed_text'])
+
+
+class ChecksupTests(TestCase):
+    def test_checksums(self):
+        fake_message = "<p>Woow, thats awesome!</p>"
+        post_pk = 231
+
+        checksum = checksums.make_checksum(fake_message, [post_pk])
+
+        self.assertTrue(
+            checksums.is_checksum_valid(fake_message, checksum, [post_pk]))
+        self.assertFalse(
+            checksums.is_checksum_valid(fake_message, checksum, [3]))
+
+
+