Skip to content

Commit 35f305e

Browse files
committed
Fixed a bug where overage handler could be bypassed.
1 parent 4af9be8 commit 35f305e

File tree

9 files changed

+56
-30
lines changed

9 files changed

+56
-30
lines changed

Source/Api/AppBuilder.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public static void Build(IAppBuilder app, Container container = null) {
8585

8686
if (Settings.Current.WebsiteMode == WebsiteMode.Dev)
8787
Task.Run(async () => await CreateSampleDataAsync(container));
88-
88+
8989
var context = new OwinContext(app.Properties);
9090
var token = context.Get<CancellationToken>("host.OnAppDisposing");
9191
RunMessageBusBroker(container, logger, token);
@@ -97,7 +97,7 @@ public static void Build(IAppBuilder app, Container container = null) {
9797
private static void RunMessageBusBroker(Container container, ILogger logger, CancellationToken token = default(CancellationToken)) {
9898
var workItemQueue = container.GetInstance<IQueue<WorkItemData>>();
9999
var subscriber = container.GetInstance<IMessageSubscriber>();
100-
100+
101101
subscriber.Subscribe<PlanOverage>(async overage => {
102102
logger.Info("Enqueueing plan overage work item for organization: {0} IsOverHourlyLimit: {1} IsOverMonthlyLimit: {2}", overage.OrganizationId, overage.IsHourly, !overage.IsHourly);
103103
await workItemQueue.EnqueueAsync(new OrganizationNotificationWorkItem {
@@ -212,7 +212,7 @@ public static Container CreateContainer(ILoggerFactory loggerFactory, ILogger lo
212212

213213
Core.Bootstrapper.RegisterServices(container, loggerFactory);
214214
Bootstrapper.RegisterServices(container, loggerFactory);
215-
215+
216216
if (!includeInsulation)
217217
return container;
218218

Source/Api/Controllers/EventController.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -769,18 +769,6 @@ await _eventPostQueue.EnqueueAsync(new EventPostInfo {
769769
// Set the project for the configuration response filter.
770770
Request.SetProject(project);
771771

772-
if (data.LongLength > Settings.Current.MaximumEventPostSize) {
773-
_logger.Error().Critical()
774-
.Message("Attempting to enqueue events greater than the maxiumum queue size")
775-
.Project(projectId)
776-
.Identity(ExceptionlessUser?.EmailAddress)
777-
.Property("User", ExceptionlessUser)
778-
.Property("Headers", Request.Content.Headers)
779-
.Property("Size", data.LongLength)
780-
.Property("MaximumEventPostSize", Settings.Current.MaximumEventPostSize)
781-
.SetActionContext(ActionContext);
782-
}
783-
784772
string contentEncoding = Request.Content.Headers.ContentEncoding.ToString();
785773
bool isCompressed = contentEncoding == "gzip" || contentEncoding == "deflate";
786774
if (!isCompressed && data.Length > 1000) {

Source/Api/Utility/Handlers/OverageHandler.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ private bool IsEventPost(HttpRequestMessage request) {
2929
if (request.Method != HttpMethod.Post)
3030
return false;
3131

32-
return request.RequestUri.AbsolutePath.EndsWith("/events", StringComparison.OrdinalIgnoreCase)
33-
|| String.Equals(request.RequestUri.AbsolutePath, "/api/v1/error", StringComparison.OrdinalIgnoreCase);
32+
string absolutePath = request.RequestUri.AbsolutePath;
33+
if (absolutePath.EndsWith("/"))
34+
absolutePath = absolutePath.Substring(0, absolutePath.Length - 1);
35+
36+
return absolutePath.EndsWith("/events", StringComparison.OrdinalIgnoreCase)
37+
|| String.Equals(absolutePath, "/api/v1/error", StringComparison.OrdinalIgnoreCase);
3438
}
3539

3640
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {

Source/Api/Utility/Handlers/ThrottlingHandler.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public ThrottlingHandler(ICacheClient cacheClient, IMetricsClient metricsClient,
2626
_period = period;
2727
_message = message;
2828
}
29-
29+
3030
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
3131
if (IsUnthrottledRoute(request))
3232
return await base.SendAsync(request, cancellationToken);
@@ -96,9 +96,13 @@ private bool IsUnthrottledRoute(HttpRequestMessage request) {
9696
if (request.Method != HttpMethod.Get)
9797
return false;
9898

99-
return request.RequestUri.AbsolutePath.EndsWith("/events/session/heartbeat", StringComparison.OrdinalIgnoreCase)
100-
|| request.RequestUri.AbsolutePath.EndsWith("/projects/config", StringComparison.OrdinalIgnoreCase)
101-
|| request.RequestUri.AbsolutePath.StartsWith("/api/v2/push", StringComparison.OrdinalIgnoreCase);
99+
string absolutePath = request.RequestUri.AbsolutePath;
100+
if (absolutePath.EndsWith("/"))
101+
absolutePath = absolutePath.Substring(0, absolutePath.Length - 1);
102+
103+
return absolutePath.EndsWith("/events/session/heartbeat", StringComparison.OrdinalIgnoreCase)
104+
|| absolutePath.EndsWith("/projects/config", StringComparison.OrdinalIgnoreCase)
105+
|| absolutePath.StartsWith("/api/v2/push", StringComparison.OrdinalIgnoreCase);
102106
}
103107
}
104108
}

Source/Api/Web.config

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
<system.web>
4242
<authentication mode="None" />
4343
<compilation targetFramework="4.6" debug="false" />
44-
<httpRuntime targetFramework="4.6" maxUrlLength="1024" />
44+
<httpRuntime targetFramework="4.6" maxRequestLength="10000" maxUrlLength="1024" />
4545
<customErrors mode="RemoteOnly" defaultRedirect="~/error.html" />
4646
</system.web>
4747
<system.webServer>
@@ -80,7 +80,9 @@
8080
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
8181
</handlers>
8282
<security>
83-
<requestFiltering allowDoubleEscaping="true" />
83+
<requestFiltering allowDoubleEscaping="true">
84+
<requestLimits maxAllowedContentLength="10000000" />
85+
</requestFiltering>
8486
</security>
8587
</system.webServer>
8688
<location path="error.html">

Source/Core/Extensions/NameValueCollectionExtensions.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,22 @@ public static int GetInt(this NameValueCollection collection, string name, int d
2727
return GetInt(collection, name) ?? defaultValue;
2828
}
2929

30+
public static long GetInt64(this NameValueCollection collection, string name, long defaultValue) {
31+
return GetInt64(collection, name) ?? defaultValue;
32+
}
33+
34+
public static long? GetInt64(this NameValueCollection collection, string name) {
35+
var value = collection[name];
36+
if (value == null)
37+
return null;
38+
39+
long number;
40+
if (Int64.TryParse(value, out number))
41+
return number;
42+
43+
return null;
44+
}
45+
3046
public static bool? GetBool(this NameValueCollection collection, string name) {
3147
string value = collection[name];
3248
if (value == null)

Source/Core/Mail/Mailer.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public Task SendInviteAsync(User sender, Organization organization, Invite invit
6060
BaseUrl = Settings.Current.BaseURL
6161
}, "Invite");
6262
msg.To.Add(invite.EmailAddress);
63-
63+
6464
return QueueMessageAsync(msg, "invite");
6565
}
6666

@@ -71,7 +71,7 @@ public Task SendPaymentFailedAsync(User owner, Organization organization) {
7171
BaseUrl = Settings.Current.BaseURL
7272
}, "PaymentFailed");
7373
msg.To.Add(owner.EmailAddress);
74-
74+
7575
return QueueMessageAsync(msg, "paymentfailed");
7676
}
7777

@@ -83,7 +83,7 @@ public Task SendAddedToOrganizationAsync(User sender, Organization organization,
8383
BaseUrl = Settings.Current.BaseURL
8484
}, "AddedToOrganization");
8585
msg.To.Add(user.EmailAddress);
86-
86+
8787
return QueueMessageAsync(msg, "addedtoorganization");
8888
}
8989

@@ -97,21 +97,21 @@ public Task SendEventNoticeAsync(string emailAddress, EventNotification model) {
9797
msg.To = emailAddress;
9898
return QueueMessageAsync(msg.ToMailMessage(), "eventnotice");
9999
}
100-
100+
101101
public Task SendOrganizationNoticeAsync(string emailAddress, OrganizationNotificationModel model) {
102102
model.BaseUrl = Settings.Current.BaseURL;
103103

104104
System.Net.Mail.MailMessage msg = _emailGenerator.GenerateMessage(model, "OrganizationNotice");
105105
msg.To.Add(emailAddress);
106-
106+
107107
return QueueMessageAsync(msg, "organizationnotice");
108108
}
109109

110110
public Task SendDailySummaryAsync(string emailAddress, DailySummaryModel notification) {
111111
notification.BaseUrl = Settings.Current.BaseURL;
112112
System.Net.Mail.MailMessage msg = _emailGenerator.GenerateMessage(notification, "DailySummary");
113113
msg.To.Add(emailAddress);
114-
114+
115115
return QueueMessageAsync(msg, "dailysummary");
116116
}
117117

Source/Core/Settings.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ public class Settings : SettingsBase<Settings> {
3636

3737
public bool EventSubmissionDisabled { get; private set; }
3838

39+
/// <summary>
40+
/// In bytes
41+
/// </summary>
3942
public long MaximumEventPostSize { get; private set; }
4043

4144
public int MaximumRetentionDays { get; private set; }
@@ -143,7 +146,7 @@ public override void Initialize() {
143146
BotThrottleLimit = GetInt(nameof(BotThrottleLimit), 25);
144147
ApiThrottleLimit = GetInt(nameof(ApiThrottleLimit), Int32.MaxValue);
145148
EventSubmissionDisabled = GetBool(nameof(EventSubmissionDisabled));
146-
MaximumEventPostSize = GetInt(nameof(MaximumEventPostSize), Int32.MaxValue);
149+
MaximumEventPostSize = GetInt64(nameof(MaximumEventPostSize), Int64.MaxValue);
147150
MaximumRetentionDays = GetInt(nameof(MaximumRetentionDays), -1);
148151
EnableDailySummary = GetBool(nameof(EnableDailySummary));
149152
MetricsServerName = GetString(nameof(MetricsServerName)) ?? "127.0.0.1";

Source/Core/Utility/SettingsBase.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ protected static int GetInt(string name, int defaultValue = 0) {
5454
return Int32.TryParse(value, out number) ? number : defaultValue;
5555
}
5656

57+
protected static long GetInt64(string name, long defaultValue = 0) {
58+
string value = GetEnvironmentVariable(name) ?? GetConfigVariable(name);
59+
if (String.IsNullOrEmpty(value))
60+
return ConfigurationManager.AppSettings.GetInt64(name, defaultValue);
61+
62+
long number;
63+
return Int64.TryParse(value, out number) ? number : defaultValue;
64+
}
65+
5766
protected static string GetString(string name, string defaultValue = null) {
5867
return GetEnvironmentVariable(name) ?? GetConfigVariable(name) ?? ConfigurationManager.AppSettings[name] ?? defaultValue;
5968
}

0 commit comments

Comments
 (0)