Critical severity9.8NVD Advisory· Published Nov 13, 2017· Updated May 13, 2026
CVE-2017-0907
CVE-2017-0907
Description
The Recurly Client .NET Library before 1.0.1, 1.1.10, 1.2.8, 1.3.2, 1.4.14, 1.5.3, 1.6.2, 1.7.1, 1.8.1 is vulnerable to a Server-Side Request Forgery vulnerability due to incorrect use of "Uri.EscapeUriString" that could result in compromise of API keys or other critical resources.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
recurly-api-clientNuGet | < 1.0.1 | 1.0.1 |
recurly-api-clientNuGet | >= 1.1.0, < 1.1.10 | 1.1.10 |
recurly-api-clientNuGet | >= 1.2.0, < 1.2.8 | 1.2.8 |
recurly-api-clientNuGet | >= 1.3.0, < 1.3.2 | 1.3.2 |
recurly-api-clientNuGet | >= 1.4.0, < 1.4.14 | 1.4.14 |
recurly-api-clientNuGet | >= 1.5.0, < 1.5.3 | 1.5.3 |
recurly-api-clientNuGet | >= 1.6.0, < 1.6.2 | 1.6.2 |
recurly-api-clientNuGet | >= 1.7.0, < 1.7.1 | 1.7.1 |
recurly-api-clientNuGet | >= 1.8.0, < 1.8.1 | 1.8.1 |
Affected products
45- Range: Versions before 1.0.1, 1.1.10, 1.2.8, 1.3.2, 1.4.14, 1.5.3, 1.6.2, 1.7.1, 1.8.1
cpe:2.3:a:recurly:recurly_client_.net:1.1.9:*:*:*:*:*:*:*+ 43 more
- cpe:2.3:a:recurly:recurly_client_.net:1.1.9:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.2.0:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.3:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.4:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.5:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.6:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.7:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.8:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.9:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.10:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.11:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.12:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.13:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.5.0:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.0.0:beta1:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.0.0:beta2:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.0.0:beta3:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.0.0:rc1:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.0.0.1:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.0.0.2:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.0.0.3:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.0.0.4:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.1.0:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.1.1:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.1.4:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.1.5:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.1.6:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.1.7:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.1.8:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.2.1:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.2.2:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.2.5:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.2.6:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.2.7:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.3.0:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.3.1:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.0:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.1:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.4.2:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.6.0:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.6.1:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.7.0:*:*:*:*:*:*:*
- cpe:2.3:a:recurly:recurly_client_.net:1.8.0:*:*:*:*:*:*:*
Patches
19eef460c0084SSRF fix: replace EscapeUriString with EscapeDataString
14 files changed · +52 −52
Library/AccountBalance.cs+1 −1 modified@@ -19,7 +19,7 @@ public static AccountBalance Get(string accountCode) var accountBalance = new AccountBalance(); var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - UrlPrefix + Uri.EscapeUriString(accountCode) + "/balance", accountBalance.ReadXml); + UrlPrefix + Uri.EscapeDataString(accountCode) + "/balance", accountBalance.ReadXml); return statusCode == HttpStatusCode.NotFound ? null : accountBalance; }
Library/Account.cs+13 −13 modified@@ -145,7 +145,7 @@ internal Account() public void DeleteBillingInfo() { Client.Instance.PerformRequest(Client.HttpRequestMethod.Delete, - UrlPrefix + Uri.EscapeUriString(AccountCode) + "/billing_info"); + UrlPrefix + Uri.EscapeDataString(AccountCode) + "/billing_info"); _billingInfo = null; } @@ -165,7 +165,7 @@ public void Update() { // PUT /accounts/<account code> Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - UrlPrefix + Uri.EscapeUriString(AccountCode), + UrlPrefix + Uri.EscapeDataString(AccountCode), WriteXml); } @@ -199,7 +199,7 @@ public Invoice InvoicePendingCharges(Invoice invoice = null) { var i = invoice ?? new Invoice(); Client.Instance.PerformRequest(Client.HttpRequestMethod.Post, - UrlPrefix + Uri.EscapeUriString(AccountCode) + "/invoices", + UrlPrefix + Uri.EscapeDataString(AccountCode) + "/invoices", i.WriteXml, i.ReadXml); @@ -213,7 +213,7 @@ public Invoice PreviewInvoicePendingCharges(Invoice invoice = null) { var i = invoice ?? new Invoice(); Client.Instance.PerformRequest(Client.HttpRequestMethod.Post, - UrlPrefix + Uri.EscapeUriString(AccountCode) + "/invoices/preview", + UrlPrefix + Uri.EscapeDataString(AccountCode) + "/invoices/preview", i.WriteXml, i.ReadXml); @@ -231,7 +231,7 @@ public RecurlyList<Adjustment> GetAdjustments(Adjustment.AdjustmentType type = A { var adjustments = new AdjustmentList(); var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - UrlPrefix + Uri.EscapeUriString(AccountCode) + "/adjustments/" + UrlPrefix + Uri.EscapeDataString(AccountCode) + "/adjustments/" + Build.QueryStringWith(Adjustment.AdjustmentState.Any == state ? "" : "state=" + state.ToString().EnumNameToTransportCase()) .AndWith(Adjustment.AdjustmentType.All == type ? "" : "type=" + type.ToString().EnumNameToTransportCase()) , adjustments.ReadXmlList); @@ -247,7 +247,7 @@ public RecurlyList<ShippingAddress> GetShippingAddresses() { var shippingAddresses = new ShippingAddressList(this); var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - UrlPrefix + Uri.EscapeUriString(AccountCode) + "/shipping_addresses/", + UrlPrefix + Uri.EscapeDataString(AccountCode) + "/shipping_addresses/", shippingAddresses.ReadXmlList); return statusCode == HttpStatusCode.NotFound ? null : shippingAddresses; @@ -269,7 +269,7 @@ public RecurlyList<Invoice> GetInvoices() /// <returns></returns> public RecurlyList<Subscription> GetSubscriptions(Subscription.SubscriptionState state = Subscription.SubscriptionState.All) { - return new SubscriptionList(UrlPrefix + Uri.EscapeUriString(AccountCode) + "/subscriptions/" + return new SubscriptionList(UrlPrefix + Uri.EscapeDataString(AccountCode) + "/subscriptions/" + Build.QueryStringWith(state.Equals(Subscription.SubscriptionState.All) ? "" : "state=" + state.ToString().EnumNameToTransportCase())); } @@ -282,14 +282,14 @@ public RecurlyList<Subscription> GetSubscriptions(Subscription.SubscriptionState public RecurlyList<Transaction> GetTransactions(TransactionList.TransactionState state = TransactionList.TransactionState.All, TransactionList.TransactionType type = TransactionList.TransactionType.All) { - return new TransactionList(UrlPrefix + Uri.EscapeUriString(AccountCode) + "/transactions/" + return new TransactionList(UrlPrefix + Uri.EscapeDataString(AccountCode) + "/transactions/" + Build.QueryStringWith(state != TransactionList.TransactionState.All ? "state=" + state.ToString().EnumNameToTransportCase() : "") .AndWith(type != TransactionList.TransactionType.All ? "type=" + type.ToString().EnumNameToTransportCase() : "")); } public RecurlyList<Note> GetNotes() { - return new NoteList(UrlPrefix + Uri.EscapeUriString(AccountCode) + "/notes/"); + return new NoteList(UrlPrefix + Uri.EscapeDataString(AccountCode) + "/notes/"); } /// <summary> @@ -328,7 +328,7 @@ public RecurlyList<CouponRedemption> GetActiveRedemptions() var redemptions = new CouponRedemptionList(); var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - UrlPrefix + Uri.EscapeUriString(AccountCode) + "/redemptions", + UrlPrefix + Uri.EscapeDataString(AccountCode) + "/redemptions", redemptions.ReadXmlList); return statusCode == HttpStatusCode.NotFound ? null : redemptions; @@ -560,7 +560,7 @@ public static Account Get(string accountCode) var account = new Account(); // GET /accounts/<account code> var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - UrlPrefix + Uri.EscapeUriString(accountCode), + UrlPrefix + Uri.EscapeDataString(accountCode), account.ReadXml); return statusCode == HttpStatusCode.NotFound ? null : account; @@ -575,7 +575,7 @@ public static void Close(string accountCode) { // DELETE /accounts/<account code> Client.Instance.PerformRequest(Client.HttpRequestMethod.Delete, - Account.UrlPrefix + Uri.EscapeUriString(accountCode)); + Account.UrlPrefix + Uri.EscapeDataString(accountCode)); } /// <summary> @@ -586,7 +586,7 @@ public static void Reopen(string accountCode) { // PUT /accounts/<account code>/reopen Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - Account.UrlPrefix + Uri.EscapeUriString(accountCode) + "/reopen"); + Account.UrlPrefix + Uri.EscapeDataString(accountCode) + "/reopen"); } /// <summary>
Library/AddOn.cs+3 −3 modified@@ -64,7 +64,7 @@ internal AddOn(string planCode, string addOnCode, string name) public void Create() { Client.Instance.PerformRequest(Client.HttpRequestMethod.Post, - UrlPrefix + Uri.EscapeUriString(PlanCode) + UrlPostfix, + UrlPrefix + Uri.EscapeDataString(PlanCode) + UrlPostfix, WriteXml, ReadXml); } @@ -75,7 +75,7 @@ public void Create() public void Update() { Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - UrlPrefix + Uri.EscapeUriString(PlanCode) + UrlPostfix + Uri.EscapeUriString(AddOnCode), + UrlPrefix + Uri.EscapeDataString(PlanCode) + UrlPostfix + Uri.EscapeDataString(AddOnCode), WriteXml, ReadXml); } @@ -86,7 +86,7 @@ public void Update() public void Delete() { Client.Instance.PerformRequest(Client.HttpRequestMethod.Delete, - UrlPrefix + Uri.EscapeUriString(PlanCode) + UrlPostfix + Uri.EscapeUriString(AddOnCode)); + UrlPrefix + Uri.EscapeDataString(PlanCode) + UrlPostfix + Uri.EscapeDataString(AddOnCode)); }
Library/Adjustment.cs+3 −3 modified@@ -115,7 +115,7 @@ public void Create() { // POST /accounts/<account code>/adjustments Client.Instance.PerformRequest(Client.HttpRequestMethod.Post, - UrlPrefix + Uri.EscapeUriString(AccountCode) + UrlPostfix, + UrlPrefix + Uri.EscapeDataString(AccountCode) + UrlPostfix, WriteXml, ReadXml); } @@ -129,7 +129,7 @@ public void Delete() { // DELETE /adjustments/<uuid> Client.Instance.PerformRequest(Client.HttpRequestMethod.Delete, - UrlPostfix + Uri.EscapeUriString(Uuid)); + UrlPostfix + Uri.EscapeDataString(Uuid)); } @@ -284,7 +284,7 @@ public static Adjustment Get(string uuid) { var adjustment = new Adjustment(); Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - "/adjustments/" + Uri.EscapeUriString(uuid), + "/adjustments/" + Uri.EscapeDataString(uuid), adjustment.ReadXml); return adjustment; }
Library/BillingInfo.cs+1 −1 modified@@ -186,7 +186,7 @@ public void Update() private static string BillingInfoUrl(string accountCode) { - return UrlPrefix + Uri.EscapeUriString(accountCode) + UrlPostfix; + return UrlPrefix + Uri.EscapeDataString(accountCode) + UrlPostfix; } internal override void ReadXml(XmlTextReader reader)
Library/Coupon.cs+4 −4 modified@@ -175,14 +175,14 @@ public void Create() public void Update() { Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - UrlPrefix + Uri.EscapeUriString(CouponCode), + UrlPrefix + Uri.EscapeDataString(CouponCode), WriteXmlUpdate); } public void Restore() { Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - UrlPrefix + Uri.EscapeUriString(CouponCode) + "/restore", + UrlPrefix + Uri.EscapeDataString(CouponCode) + "/restore", WriteXmlUpdate); } @@ -192,7 +192,7 @@ public void Restore() public void Deactivate() { Client.Instance.PerformRequest(Client.HttpRequestMethod.Delete, - UrlPrefix + Uri.EscapeUriString(CouponCode)); + UrlPrefix + Uri.EscapeDataString(CouponCode)); } public RecurlyList<Coupon> GetUniqueCouponCodes() @@ -535,7 +535,7 @@ public static Coupon Get(string couponCode) var coupon = new Coupon(); var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - Coupon.UrlPrefix + Uri.EscapeUriString(couponCode), + Coupon.UrlPrefix + Uri.EscapeDataString(couponCode), coupon.ReadXml); return statusCode == HttpStatusCode.NotFound ? null : coupon;
Library/CouponRedemption.cs+3 −3 modified@@ -46,7 +46,7 @@ internal static CouponRedemption Redeem(string accountCode, string couponCode, s var cr = new CouponRedemption {AccountCode = accountCode, Currency = currency, SubscriptionUuid = subscriptionUuid}; var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Post, - "/coupons/" + Uri.EscapeUriString(couponCode) + "/redeem", + "/coupons/" + Uri.EscapeDataString(couponCode) + "/redeem", cr.WriteXml, cr.ReadXml); @@ -60,8 +60,8 @@ internal static CouponRedemption Redeem(string accountCode, string couponCode, s public void Delete() { var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Delete, - "/accounts/" + Uri.EscapeUriString(AccountCode) + - "/redemptions/" + Uri.EscapeUriString(Uuid)); + "/accounts/" + Uri.EscapeDataString(AccountCode) + + "/redemptions/" + Uri.EscapeDataString(Uuid)); AccountCode = null; CouponCode = null; Currency = null;
Library/Export.cs+1 −1 modified@@ -111,7 +111,7 @@ public static ExportFile DownloadExportFile(DateTime date, string fileName) { var exportFile = new ExportFile(); var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - string.Format(ExportFile.FileUrlPrefix, date.ToString("yyyy-MM-dd"), Uri.EscapeUriString(fileName)), + string.Format(ExportFile.FileUrlPrefix, date.ToString("yyyy-MM-dd"), Uri.EscapeDataString(fileName)), exportFile.ReadXml); return statusCode != HttpStatusCode.NotFound ? exportFile : null;
Library/GiftCard.cs+1 −1 modified@@ -324,7 +324,7 @@ public static GiftCard Get(long id) var giftCard = new GiftCard(); // GET /gift_cards/<id> var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - UrlPrefix + Uri.EscapeUriString(id.ToString()), + UrlPrefix + Uri.EscapeDataString(id.ToString()), giftCard.ReadXml); return statusCode == HttpStatusCode.NotFound ? null : giftCard;
Library/Invoice.cs+4 −4 modified@@ -121,7 +121,7 @@ public byte[] GetPdf(string acceptLanguage = "en-US") public void Create(string accountCode) { Client.Instance.PerformRequest(Client.HttpRequestMethod.Post, - "/accounts/" + Uri.EscapeUriString(accountCode) + Invoice.UrlPrefix, + "/accounts/" + Uri.EscapeDataString(accountCode) + Invoice.UrlPrefix, WriteXml, ReadXml); } @@ -132,7 +132,7 @@ public void Create(string accountCode) public void Preview(string accountCode) { Client.Instance.PerformRequest(Client.HttpRequestMethod.Post, - "/accounts/" + Uri.EscapeUriString(accountCode) + Invoice.UrlPrefix + "preview", + "/accounts/" + Uri.EscapeDataString(accountCode) + Invoice.UrlPrefix + "preview", WriteXml, ReadXml); } @@ -453,7 +453,7 @@ public sealed class Invoices { public static RecurlyList<Invoice> List(string accountCode) { - return new InvoiceList("/accounts/" + Uri.EscapeUriString(accountCode) + "/invoices"); + return new InvoiceList("/accounts/" + Uri.EscapeDataString(accountCode) + "/invoices"); } public static RecurlyList<Invoice> List() @@ -504,7 +504,7 @@ public static Invoice Create(string accountCode) var invoice = new Invoice(); var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Post, - "/accounts/" + Uri.EscapeUriString(accountCode) + Invoice.UrlPrefix, + "/accounts/" + Uri.EscapeDataString(accountCode) + Invoice.UrlPrefix, invoice.ReadXml); return (int)statusCode == ValidationException.HttpStatusCode ? null : invoice;
Library/MeasuredUnit.cs+2 −2 modified@@ -56,7 +56,7 @@ public void Create() public void Update() { Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - UrlPrefix + Uri.EscapeUriString(Id.ToString()), + UrlPrefix + Uri.EscapeDataString(Id.ToString()), WriteXml); } @@ -66,7 +66,7 @@ public void Update() public void Delete() { Client.Instance.PerformRequest(Client.HttpRequestMethod.Delete, - UrlPrefix + Uri.EscapeUriString(Id.ToString())); + UrlPrefix + Uri.EscapeDataString(Id.ToString())); } #region Read and Write XML documents
Library/Plan.cs+5 −5 modified@@ -58,7 +58,7 @@ public RecurlyList<AddOn> AddOns { if (_addOns == null) { - var url = UrlPrefix + Uri.EscapeUriString(PlanCode) + "/add_ons/"; + var url = UrlPrefix + Uri.EscapeDataString(PlanCode) + "/add_ons/"; _addOns = new AddOnList(url); } return _addOns; @@ -120,7 +120,7 @@ public void Create() public void Update() { Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - UrlPrefix + Uri.EscapeUriString(PlanCode), + UrlPrefix + Uri.EscapeDataString(PlanCode), WriteXml); } @@ -129,7 +129,7 @@ public void Update() /// </summary> public void Deactivate() { - Client.Instance.PerformRequest(Client.HttpRequestMethod.Delete, UrlPrefix + Uri.EscapeUriString(PlanCode)); + Client.Instance.PerformRequest(Client.HttpRequestMethod.Delete, UrlPrefix + Uri.EscapeDataString(PlanCode)); } /// <summary> @@ -149,7 +149,7 @@ public AddOn GetAddOn(string addOnCode) var addOn = new AddOn(); var status = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - UrlPrefix + Uri.EscapeUriString(PlanCode) + "/add_ons/" + Uri.EscapeUriString(addOnCode), + UrlPrefix + Uri.EscapeDataString(PlanCode) + "/add_ons/" + Uri.EscapeDataString(addOnCode), addOn.ReadXml); if (status != HttpStatusCode.OK) return null; @@ -445,7 +445,7 @@ public static Plan Get(string planCode) var plan = new Plan(); var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - Plan.UrlPrefix + Uri.EscapeUriString(planCode), + Plan.UrlPrefix + Uri.EscapeDataString(planCode), plan.ReadXml); return statusCode == HttpStatusCode.NotFound ? null : plan;
Library/Subscription.cs+9 −9 modified@@ -372,7 +372,7 @@ public void ChangeSubscription(ChangeTimeframe timeframe) writeXmlDelegate = WriteChangeSubscriptionNowXml; Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - UrlPrefix + Uri.EscapeUriString(Uuid), + UrlPrefix + Uri.EscapeDataString(Uuid), writeXmlDelegate, ReadXml); } @@ -389,7 +389,7 @@ public void ChangeSubscription() public void Cancel() { Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - UrlPrefix + Uri.EscapeUriString(Uuid) + "/cancel", + UrlPrefix + Uri.EscapeDataString(Uuid) + "/cancel", ReadXml); } @@ -399,7 +399,7 @@ public void Cancel() public void Reactivate() { Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - UrlPrefix + Uri.EscapeUriString(Uuid) + "/reactivate", + UrlPrefix + Uri.EscapeDataString(Uuid) + "/reactivate", ReadXml); } @@ -410,7 +410,7 @@ public void Reactivate() public void Terminate(RefundType refund) { Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - UrlPrefix + Uri.EscapeUriString(Uuid) + "/terminate?refund=" + refund.ToString().EnumNameToTransportCase(), + UrlPrefix + Uri.EscapeDataString(Uuid) + "/terminate?refund=" + refund.ToString().EnumNameToTransportCase(), ReadXml); } @@ -460,7 +460,7 @@ public virtual Subscription PreviewChange(ChangeTimeframe timeframe) var previewSubscription = new Subscription(); var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Post, - UrlPrefix + Uri.EscapeUriString(Uuid) + "/preview", + UrlPrefix + Uri.EscapeDataString(Uuid) + "/preview", writeXmlDelegate, previewSubscription.ReadPreviewXml); @@ -480,14 +480,14 @@ public virtual Subscription PreviewChange() public void Postpone(DateTime nextRenewalDate, bool bulk = false) { Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - UrlPrefix + Uri.EscapeUriString(Uuid) + "/postpone?next_renewal_date=" + nextRenewalDate.ToString("s") + "&bulk=" + bulk.ToString().ToLower(), + UrlPrefix + Uri.EscapeDataString(Uuid) + "/postpone?next_renewal_date=" + nextRenewalDate.ToString("s") + "&bulk=" + bulk.ToString().ToLower(), ReadXml); } public bool UpdateNotes(Dictionary<string, string> notes) { Client.Instance.PerformRequest(Client.HttpRequestMethod.Put, - UrlPrefix + Uri.EscapeUriString(Uuid) + "/notes", + UrlPrefix + Uri.EscapeDataString(Uuid) + "/notes", WriteSubscriptionNotesXml(notes), ReadXml); @@ -502,7 +502,7 @@ public RecurlyList<CouponRedemption> GetRedemptions() { var coupons = new CouponRedemptionList(); var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - UrlPrefix + Uri.EscapeUriString(Uuid) + "/redemptions/", + UrlPrefix + Uri.EscapeDataString(Uuid) + "/redemptions/", coupons.ReadXmlList); return statusCode == HttpStatusCode.NotFound ? null : coupons; @@ -968,7 +968,7 @@ public static Subscription Get(string uuid) { var s = new Subscription(); var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - Subscription.UrlPrefix + Uri.EscapeUriString(uuid), + Subscription.UrlPrefix + Uri.EscapeDataString(uuid), s.ReadXml); return statusCode == HttpStatusCode.NotFound ? null : s;
Library/Transaction.cs+2 −2 modified@@ -146,7 +146,7 @@ public void Create() public void Refund(int? refund = null) { Client.Instance.PerformRequest(Client.HttpRequestMethod.Delete, - UrlPrefix + Uri.EscapeUriString(Uuid) + (refund.HasValue ? "?amount_in_cents=" + refund.Value : ""), + UrlPrefix + Uri.EscapeDataString(Uuid) + (refund.HasValue ? "?amount_in_cents=" + refund.Value : ""), ReadXml); } @@ -399,7 +399,7 @@ public static Transaction Get(string transactionId) var transaction = new Transaction(); var statusCode = Client.Instance.PerformRequest(Client.HttpRequestMethod.Get, - Transaction.UrlPrefix + Uri.EscapeUriString(transactionId), + Transaction.UrlPrefix + Uri.EscapeDataString(transactionId), transaction.ReadXml); return statusCode == HttpStatusCode.NotFound ? null : transaction;
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/recurly/recurly-client-net/commit/9eef460c0084afd5c24d66220c8b7a381cf9a1f1nvdPatchThird Party AdvisoryWEB
- dev.recurly.com/page/net-updatesnvdVendor AdvisoryWEB
- github.com/advisories/GHSA-xpwp-rq3x-x6v7ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2017-0907ghsaADVISORY
- hackerone.com/reports/288635nvdPermissions RequiredWEB
News mentions
0No linked articles in our index yet.