CVE-2016-15028: Improper Validation of Integrity Check Value (CWE-354)
value: A vulnerability was found in ICEPAY REST-API-NET 0.9. It has been declared as problematic. Affected by this vulnerability is the function RestClient of the file Classes/RestClient.cs of the component Checksum Validation. The manipulation leads to improper validation of integrity check value. The attack can be launched remotely. The complexity of an attack is rather high. The exploitation appears to be difficult. Upgrading to version 1.0 is able to address this issue. The patch is named 61f6b8758e5c971abff5f901cfa9f231052b775f. It is recommended to upgrade the affected component. The associated identifier of this vulnerability is VDB-222847.
CWE description: The product does not validate or incorrectly validates the integrity check values or "checksums" of a message. This may prevent it from detecting if the data has been modified or corrupted in transmission.
CVSS v3 base score: 5.9
Published: 2023-03-12T15:15Z
Repository: https://github.com/ICEPAY/REST-API-NET
Language: C#
Files changed: Classes/Base.cs, Classes/Payment/AutomaticCheckout.cs, Classes/Payment/Checkout.cs, Classes/Payment/GetMyPaymentMethods.cs, Classes/Payment/GetPayment.cs, Classes/Payment/VaultCheckout.cs, Classes/Refund/CancelRefund.cs, Classes/Refund/GetPaymentRefunds.cs, Classes/Refund/RequestRefund.cs, Classes/RestClient.cs, LICENSE, Refund.cs, ServiceBase.cs
Commit date: 2016-04-14 14:53:09 +0200
Commit message: Fixed vulnerability that made a man-in-the-middle attack possible. The checksum header is now always required on responses. If no checksum header is present, it is presumed that the Merchant ID was entered incorrectly.

Diff: diff --git a/Classes/Base.cs b/Classes/Base.cs
index d989ea5..067fc0e 100644
--- a/Classes/Base.cs
+++ b/Classes/Base.cs
@@ -1,10 +1,6 @@
 ﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace IcepayRestClient.Classes
 {
     public abstract class Base
     {
diff --git a/Classes/Payment/AutomaticCheckout.cs b/Classes/Payment/AutomaticCheckout.cs
index 7235403..a53c4a6 100644
--- a/Classes/Payment/AutomaticCheckout.cs
+++ b/Classes/Payment/AutomaticCheckout.cs
@@ -1,11 +1,6 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
+﻿
 namespace IcepayRestClient.Classes.Payment
 {
     public class AutomaticCheckoutRequest : CheckoutRequest { }
 
     public class AutomaticCheckoutResponse : CheckoutResponse { }
diff --git a/Classes/Payment/Checkout.cs b/Classes/Payment/Checkout.cs
index f79f11c..4602ba1 100644
--- a/Classes/Payment/Checkout.cs
+++ b/Classes/Payment/Checkout.cs
@@ -1,11 +1,6 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
+﻿
 namespace IcepayRestClient.Classes.Payment
 {
     public class CheckoutRequest : Base
     {
         public int Amount { get; set; }
diff --git a/Classes/Payment/GetMyPaymentMethods.cs b/Classes/Payment/GetMyPaymentMethods.cs
index 2a2ea71..f38486b 100644
--- a/Classes/Payment/GetMyPaymentMethods.cs
+++ b/Classes/Payment/GetMyPaymentMethods.cs
@@ -1,11 +1,6 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
+﻿
 namespace IcepayRestClient.Classes.Payment
 {
     public class GetMyPaymentMethodsRequest : Base { }
 
     public class GetMyPaymentMethodsResponse : Base
diff --git a/Classes/Payment/GetPayment.cs b/Classes/Payment/GetPayment.cs
index 6ddee2c..de43fd2 100644
--- a/Classes/Payment/GetPayment.cs
+++ b/Classes/Payment/GetPayment.cs
@@ -1,11 +1,6 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
+﻿
 namespace IcepayRestClient.Classes.Payment
 {
     public class GetPaymentRequest :Base
     {
         public int PaymentID { get; set; }
diff --git a/Classes/Payment/VaultCheckout.cs b/Classes/Payment/VaultCheckout.cs
index 77218f1..888e898 100644
--- a/Classes/Payment/VaultCheckout.cs
+++ b/Classes/Payment/VaultCheckout.cs
@@ -1,11 +1,6 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
+﻿
 namespace IcepayRestClient.Classes.Payment
 {
     public class VaultCheckoutRequest:CheckoutRequest
     {
         public string ConsumerID { get; set; }
diff --git a/Classes/Refund/CancelRefund.cs b/Classes/Refund/CancelRefund.cs
index 6640845..cb08911 100644
--- a/Classes/Refund/CancelRefund.cs
+++ b/Classes/Refund/CancelRefund.cs
@@ -1,11 +1,6 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
+﻿
 namespace IcepayRestClient.Classes.Refund
 {
     public class CancelRefundRequest : Base
     {
         public int RefundID { get; set; }
diff --git a/Classes/Refund/GetPaymentRefunds.cs b/Classes/Refund/GetPaymentRefunds.cs
index 0289e5e..9b6dfc3 100644
--- a/Classes/Refund/GetPaymentRefunds.cs
+++ b/Classes/Refund/GetPaymentRefunds.cs
@@ -1,11 +1,6 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
+﻿
 namespace IcepayRestClient.Classes.Refund
 {
     public class GetPaymentRefundsRequest : Base
     {
         public int PaymentID { get; set; }
diff --git a/Classes/Refund/RequestRefund.cs b/Classes/Refund/RequestRefund.cs
index a5ed747..63ef4fc 100644
--- a/Classes/Refund/RequestRefund.cs
+++ b/Classes/Refund/RequestRefund.cs
@@ -1,11 +1,6 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
+﻿
 namespace IcepayRestClient.Classes.Refund
 {
     public class RequestRefundRequest : Base
     {
         public int PaymentID { get; set; }
diff --git a/Classes/RestClient.cs b/Classes/RestClient.cs
index 5c53bb9..8670761 100644
--- a/Classes/RestClient.cs
+++ b/Classes/RestClient.cs
@@ -1,7 +1,6 @@
 ﻿using Newtonsoft.Json;
-using System;
 using System.IO;
 using System.Net;
 using System.Security.Cryptography;
 using System.Text;
 
@@ -57,20 +56,35 @@ namespace IcepayRestClient.Classes
             rawResponse = reader.ReadToEnd();
 
             response = JsonConvert.DeserializeObject<TResponse>(rawResponse);
 
             //verify response checksum
+            //always require presence of a checksum header
             if (!string.IsNullOrWhiteSpace(webresponse.Headers["Checksum"]))
             {
                 var responseChecksum = webresponse.Headers["Checksum"];
                 var responseSignString = webresponse.ResponseUri.AbsoluteUri + "POST" + merchantID.ToString() + merchantSecret + rawResponse;
                 var responseVerificationChecksum = Sha256(responseSignString);
                 if (!responseChecksum.Equals(responseVerificationChecksum, System.StringComparison.InvariantCultureIgnoreCase))
                 {
-                    response = new TResponse { Message = "Response signature invalid." };
+                    if (string.IsNullOrWhiteSpace(response.Message))
+                    {
+                        response = new TResponse { Message = "Authentication error: the checksum was incorrect. Verify your secret code." };
+                    }
+                    response = new TResponse { Message = response.Message };
                 }
             }
+            else
+            {
+                //if no checksum header was present in the response, the most likely cause is that the sender ID was invalid
+                //return only the response message and regard the response as failed
+                if (string.IsNullOrWhiteSpace(response.Message))
+                {
+                    response = new TResponse { Message = "Authentication error: no checksum found. Verify your merchant ID." };
+                }
+                response = new TResponse { Message = response.Message };
+            }
 
             //close streams
             writer.Dispose();
             reader.Dispose();
             webresponse.Dispose();
diff --git a/LICENSE b/LICENSE
index e477fbb..cb8173c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
-Copyright (c) 2015, ICEPAY - Transaction Performance
+Copyright (c) 2015-2016, ICEPAY - Transaction Performance
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 
diff --git a/Refund.cs b/Refund.cs
index 0c1c9e4..69f0f83 100644
--- a/Refund.cs
+++ b/Refund.cs
@@ -1,11 +1,6 @@
 ﻿using IcepayRestClient.Classes.Refund;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace IcepayRestClient
 {
     public class Refund : ServiceBase
     {
diff --git a/ServiceBase.cs b/ServiceBase.cs
index 834052e..6ba0220 100644
--- a/ServiceBase.cs
+++ b/ServiceBase.cs
@@ -1,20 +1,14 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace IcepayRestClient
+﻿namespace IcepayRestClient
 {
     public abstract class ServiceBase
     {
         public int MerchantID { get; set; }
         public string MerchantSecret { get; set; }
 
         public ServiceBase(int merchantID, string merchantSecret)
         {
             this.MerchantID = merchantID;
-            this.MerchantSecret=merchantSecret;
+            this.MerchantSecret = merchantSecret;
         }
     }
 }

Vulnerable code: using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System;
                    response = new TResponse { Message = "Response signature invalid." };
Copyright (c) 2015, ICEPAY - Transaction Performance
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IcepayRestClient
            this.MerchantSecret=merchantSecret;
Fixed code: ﻿
﻿
﻿
﻿
﻿
﻿
﻿
﻿
            //always require presence of a checksum header
                    if (string.IsNullOrWhiteSpace(response.Message))
                    {
                        response = new TResponse { Message = "Authentication error: the checksum was incorrect. Verify your secret code." };
                    }
                    response = new TResponse { Message = response.Message };
            else
            {
                //if no checksum header was present in the response, the most likely cause is that the sender ID was invalid
                //return only the response message and regard the response as failed
                if (string.IsNullOrWhiteSpace(response.Message))
                {
                    response = new TResponse { Message = "Authentication error: no checksum found. Verify your merchant ID." };
                }
                response = new TResponse { Message = response.Message };
            }
Copyright (c) 2015-2016, ICEPAY - Transaction Performance
﻿namespace IcepayRestClient
            this.MerchantSecret = merchantSecret;