Procházet zdrojové kódy

fix(api): disallow creation of ALIAS/DNAME records, closes #110

Peter Thomassen před 6 roky
rodič
revize
db122d8ddc

+ 1 - 0
api/desecapi/models.py

@@ -432,6 +432,7 @@ class RRset(models.Model, mixins.SetterMixin):
     ttl = models.PositiveIntegerField(validators=[MinValueValidator(1)])
 
     _dirty = False
+    DEAD_TYPES = ('ALIAS', 'DNAME')
     RESTRICTED_TYPES = ('SOA', 'RRSIG', 'DNSKEY', 'NSEC3PARAM', 'OPT')
 
 

+ 3 - 0
api/desecapi/serializers.py

@@ -184,6 +184,9 @@ class RRsetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
         return self._save(None, validated_data)
 
     def validate_type(self, value):
+        if value in RRset.DEAD_TYPES:
+            raise serializers.ValidationError(
+                "The %s RRset type is currently unsupported." % value)
         if value in RRset.RESTRICTED_TYPES:
             raise serializers.ValidationError(
                 "You cannot tinker with the %s RRset." % value)

+ 8 - 0
api/desecapi/tests/testrrsets.py

@@ -32,6 +32,7 @@ class UnauthenticatedDomainTests(APITestCase):
 
 
 class AuthenticatedRRsetTests(APITestCase):
+    dead_types = ('ALIAS', 'DNAME')
     restricted_types = ('SOA', 'RRSIG', 'DNSKEY', 'NSEC3PARAM')
 
     def setUp(self):
@@ -151,6 +152,13 @@ class AuthenticatedRRsetTests(APITestCase):
         response = self.client.post(url, json.dumps(data), content_type='application/json')
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
 
+    def testCantPostDeadTypes(self):
+        for type_ in self.dead_types:
+            url = reverse('rrsets', args=(self.ownedDomains[1].name,))
+            data = {'records': ['www.example.com.'], 'ttl': 60, 'type': type_}
+            response = self.client.post(url, json.dumps(data), content_type='application/json')
+            self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
+
     def testCantPostRestrictedTypes(self):
         for type_ in self.restricted_types:
             url = reverse('rrsets', args=(self.ownedDomains[1].name,))

+ 6 - 4
docs/rrsets.rst

@@ -430,10 +430,12 @@ explained below.
 Restricted Types
 ````````````````
 
-**Note:**  Some record types are supported by the API, but not currently
-served by our nameservers (such as ``ALIAS`` or ``DNAME``).  If you wish to
-use such record types, shoot us an email.  In most cases, it should not be a
-problem to enable such functionality.
+``ALIAS``, ``DNAME``
+    These record types are used very rarely in the wild.  Due to conflicts with
+    the security guarantees we would like to give, these record types are
+    disabled in our API.  If you attempt to create such RRsets, you will receive
+    a ``400 Bad Request`` response.  In case you have a good reason for using
+    these record types, shoot us an email and we can discuss your case.
 
 ``DNSKEY``, ``NSEC3PARAM``, ``RRSIG``
     These record types are meant to provide DNSSEC-related information in

+ 15 - 0
test/e2e/spec/api_spec.js

@@ -263,6 +263,21 @@ describe("API", function () {
                     itShowsUpInPdnsAs('', domain, 'A', ['127.0.0.1'], 60);
                 });
 
+                describe("cannot create RRsets of restricted or dead type", function () {
+
+                    var rrTypes = ['DNAME', 'ALIAS', 'SOA', 'RRSIG', 'DNSKEY', 'NSEC3PARAM', 'OPT'];
+                    for (var i = 0; i < rrTypes.length; i++) {
+                        var rrType = rrTypes[i];
+                        it(rrType, function () {
+                            return expect(chakram.post(
+                                    '/domains/' + domain + '/rrsets/',
+                                    {'subname': 'not-welcome', 'type': rrType, 'records': ['127.0.0.1'], 'ttl': 60}
+                                )).to.have.status(400);
+                        });
+                    }
+
+                });
+
                 it("cannot update RRSets for nonexistent domain name", function () {
                     return expect(chakram.patch(
                             '/domains/nonexistent.e2e.domain/rrsets/',