CVE-2021-4248: Use of Insufficiently Random Values (CWE-330)
value: A vulnerability was found in kapetan dns up to 6.1.0. It has been rated as problematic. Affected by this issue is some unknown functionality of the file DNS/Protocol/Request.cs. The manipulation leads to insufficient entropy in prng. The attack may be launched remotely. Upgrading to version 7.0.0 is able to address this issue. The name of the patch is cf7105aa2aae90d6656088fe5a8ee1d5730773b6. It is recommended to upgrade the affected component. The identifier of this vulnerability is VDB-216188.
CWE description: The product uses insufficiently random numbers or values in a security context that depends on unpredictable numbers.
CVSS v3 base score: 9.8
Published: 2022-12-18T11:15Z
Repository: https://github.com/kapetan/dns
Language: C#
Files changed: DNS/Protocol/Request.cs
Commit date: 2021-11-24 13:29:48 +0100
Commit message: Using a crypto random number generator in `Request` (#88)

* Using a crypto random number generator in `Request`

This changes `Request` to use cryptographically secure
random numbers.
It prevents possible spoofing of DNS responses.

* Fix style

Co-authored-by: Mirza Kapetanovic <mirza.kapetanovic@gmail.com>
Diff: diff --git a/DNS/Protocol/Request.cs b/DNS/Protocol/Request.cs
index 86661b8..9bdf8b7 100644
--- a/DNS/Protocol/Request.cs
+++ b/DNS/Protocol/Request.cs
@@ -1,14 +1,15 @@
 ﻿using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Security.Cryptography;
 using DNS.Protocol.Utils;
 using DNS.Protocol.ResourceRecords;
 
 namespace DNS.Protocol {
     public class Request : IRequest {
-        private static readonly Random RANDOM = new Random();
+        private static readonly RandomNumberGenerator RANDOM = new RNGCryptoServiceProvider();
 
         private IList<Question> questions;
         private Header header;
         private IList<IResourceRecord> additional;
 
@@ -39,11 +40,11 @@ public class Request : IRequest {
             this.header = new Header();
             this.additional = new List<IResourceRecord>();
 
             this.header.OperationCode = OperationCode.Query;
             this.header.Response = false;
-            this.header.Id = RANDOM.Next(UInt16.MaxValue);
+            this.header.Id = NextRandomId();
         }
 
         public Request(IRequest request) {
             this.header = new Header();
             this.questions = new List<Question>(request.Questions);
@@ -110,7 +111,13 @@ public class Request : IRequest {
 
         private void UpdateHeader() {
             header.QuestionCount = questions.Count;
             header.AdditionalRecordCount = additional.Count;
         }
+
+        private ushort NextRandomId() {
+            byte[] buffer = new byte[sizeof(ushort)];
+            RANDOM.GetBytes(buffer);
+            return BitConverter.ToUInt16(buffer, 0);
+        }
     }
 }

Vulnerable code:         private static readonly Random RANDOM = new Random();
            this.header.Id = RANDOM.Next(UInt16.MaxValue);
Fixed code: using System.Security.Cryptography;
        private static readonly RandomNumberGenerator RANDOM = new RNGCryptoServiceProvider();
            this.header.Id = NextRandomId();

        private ushort NextRandomId() {
            byte[] buffer = new byte[sizeof(ushort)];
            RANDOM.GetBytes(buffer);
            return BitConverter.ToUInt16(buffer, 0);
        }