[tor-commits] [tor/maint-0.2.3] Limit hidden service descriptors to at most 10 guard nodes.

nickm at torproject.org nickm at torproject.org
Tue Jun 18 14:18:26 UTC 2013


commit dc516a543604e081583cbe725bc4b0a89768fc78
Author: Nick Mathewson <nickm at torproject.org>
Date:   Sun Jun 16 20:23:33 2013 -0400

    Limit hidden service descriptors to at most 10 guard nodes.
    
    Fixes bug 9002; bugfix on 0.1.1.11-alpha (which introduced guard
    nodes), or on 0.0.6pre1 (which introduced hidden services).
---
 changes/bug9002     |    4 ++++
 src/or/rendcommon.c |   25 +++++++++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/changes/bug9002 b/changes/bug9002
new file mode 100644
index 0000000..c41ace3
--- /dev/null
+++ b/changes/bug9002
@@ -0,0 +1,4 @@
+  o Major bugfixes:
+    - Limit hidden service descriptors to at most ten introduction
+      points, to slow one kind of guard enumeration. Fixes bug 9002;
+      bugfix on 0.1.1.11-alpha.
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index 4722690..812fce9 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -1002,6 +1002,10 @@ rend_cache_lookup_v2_desc_as_dir(const char *desc_id, const char **desc)
   return 0;
 }
 
+/* Do not allow more than this many introduction points in a hidden service
+ * descriptor */
+#define MAX_INTRO_POINTS 10
+
 /** Parse *desc, calculate its service id, and store it in the cache.
  * If we have a newer v0 descriptor with the same ID, ignore this one.
  * If we have an older descriptor with the same ID, replace it.
@@ -1070,6 +1074,15 @@ rend_cache_store(const char *desc, size_t desc_len, int published,
     rend_service_descriptor_free(parsed);
     return -1;
   }
+  if (parsed->intro_nodes &&
+      smartlist_len(parsed->intro_nodes) > MAX_INTRO_POINTS) {
+    log_warn(LD_REND, "Found too many introduction points on a hidden "
+             "service descriptor for %s. This is probably a (misguided) "
+             "attempt to improve reliability, but it could also be an "
+             "attempt to do a guard enumeration attack. Rejecting.",
+             safe_str_client(query));
+    return -2;
+  }
   tor_snprintf(key, sizeof(key), "0%s", query);
   e = (rend_cache_entry_t*) strmap_get_lc(rend_cache, key);
   if (e && e->parsed->timestamp > parsed->timestamp) {
@@ -1288,6 +1301,7 @@ rend_cache_store_v2_desc_as_client(const char *desc,
   }
   /* Decode/decrypt introduction points. */
   if (intro_content) {
+    int n_intro_points;
     if (rend_query->auth_type != REND_NO_AUTH &&
         !tor_mem_is_zero(rend_query->descriptor_cookie,
                          sizeof(rend_query->descriptor_cookie))) {
@@ -1308,13 +1322,20 @@ rend_cache_store_v2_desc_as_client(const char *desc,
         intro_size = ipos_decrypted_size;
       }
     }
-    if (rend_parse_introduction_points(parsed, intro_content,
-                                       intro_size) <= 0) {
+    n_intro_points = rend_parse_introduction_points(parsed, intro_content,
+                                                    intro_size);
+    if (n_intro_points <= 0) {
       log_warn(LD_REND, "Failed to parse introduction points. Either the "
                "service has published a corrupt descriptor or you have "
                "provided invalid authorization data.");
       retval = -2;
       goto err;
+    } else if (n_intro_points > MAX_INTRO_POINTS) {
+      log_warn(LD_REND, "Found too many introduction points on a hidden "
+               "service descriptor for %s. This is probably a (misguided) "
+               "attempt to improve reliability, but it could also be an "
+               "attempt to do a guard enumeration attack. Rejecting.",
+               safe_str_client(rend_query->onion_address));
     }
   } else {
     log_info(LD_REND, "Descriptor does not contain any introduction points.");





More information about the tor-commits mailing list