summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2012-11-11 20:13:12 -0800
committerAndrew Arnott <andrewarnott@gmail.com>2012-11-11 20:13:12 -0800
commit83d3efa71da483d55900cbd38d17afa4b6403bef (patch)
tree8877888069f2e0b6f5ebe828a6686c5927234b42
parent446371c4c113c23abec15695e756aecedd44e56d (diff)
downloadDotNetOpenAuth-83d3efa71da483d55900cbd38d17afa4b6403bef.zip
DotNetOpenAuth-83d3efa71da483d55900cbd38d17afa4b6403bef.tar.gz
DotNetOpenAuth-83d3efa71da483d55900cbd38d17afa4b6403bef.tar.bz2
Avoids OOM exceptions from ResourceServer
Related to #178
-rw-r--r--src/DotNetOpenAuth.Core/Messaging/DataBagFormatterBase.cs4
-rw-r--r--src/DotNetOpenAuth.Core/Messaging/MessagingStrings.Designer.cs11
-rw-r--r--src/DotNetOpenAuth.Core/Messaging/MessagingStrings.resx7
-rw-r--r--src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs9
-rw-r--r--src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AssociationDataBag.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth2/ResourceServerTests.cs16
6 files changed, 40 insertions, 9 deletions
diff --git a/src/DotNetOpenAuth.Core/Messaging/DataBagFormatterBase.cs b/src/DotNetOpenAuth.Core/Messaging/DataBagFormatterBase.cs
index 69ee8dc..2452502 100644
--- a/src/DotNetOpenAuth.Core/Messaging/DataBagFormatterBase.cs
+++ b/src/DotNetOpenAuth.Core/Messaging/DataBagFormatterBase.cs
@@ -217,8 +217,8 @@ namespace DotNetOpenAuth.Messaging {
if (this.signed) {
using (var dataStream = new MemoryStream(data)) {
var dataReader = new BinaryReader(dataStream);
- signature = dataReader.ReadBuffer();
- data = dataReader.ReadBuffer();
+ signature = dataReader.ReadBuffer(1024);
+ data = dataReader.ReadBuffer(8 * 1024);
}
// Verify that the verification code was issued by message authorization server.
diff --git a/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.Designer.cs b/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.Designer.cs
index 2fe273f..4f89589 100644
--- a/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.Designer.cs
+++ b/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:4.0.30319.239
+// Runtime Version:4.0.30319.18010
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -106,6 +106,15 @@ namespace DotNetOpenAuth.Messaging {
}
/// <summary>
+ /// Looks up a localized string similar to Decoding failed due to data corruption..
+ /// </summary>
+ internal static string DataCorruptionDetected {
+ get {
+ return ResourceManager.GetString("DataCorruptionDetected", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to An instance of type {0} was expected, but received unexpected derived type {1}..
/// </summary>
internal static string DerivedTypeNotExpected {
diff --git a/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.resx b/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.resx
index fbdb63d..15ca046 100644
--- a/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.resx
+++ b/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.resx
@@ -112,10 +112,10 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ArgumentPropertyMissing" xml:space="preserve">
<value>Argument's {0}.{1} property is required but is empty or null.</value>
@@ -333,4 +333,7 @@
<data name="UnexpectedBufferLength" xml:space="preserve">
<value>Unexpected buffer length.</value>
</data>
+ <data name="DataCorruptionDetected" xml:space="preserve">
+ <value>Decoding failed due to data corruption.</value>
+ </data>
</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs
index b266a62..106ded1 100644
--- a/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs
+++ b/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs
@@ -1685,10 +1685,17 @@ namespace DotNetOpenAuth.Messaging {
/// Reads a buffer that is prefixed with its own length.
/// </summary>
/// <param name="reader">The binary reader positioned at the buffer length.</param>
+ /// <param name="maxBufferSize">
+ /// The maximum size of the buffer that should be permitted.
+ /// Although the stream will indicate the size of the buffer, this mitigates data corruption
+ /// or DoS attacks causing the web server to allocate too much memory for a small data packet.
+ /// </param>
/// <returns>The read buffer.</returns>
- internal static byte[] ReadBuffer(this BinaryReader reader) {
+ internal static byte[] ReadBuffer(this BinaryReader reader, int maxBufferSize) {
Requires.NotNull(reader, "reader");
+ Requires.InRange(maxBufferSize > 0 && maxBufferSize < 1024 * 1024, "maxBufferSize");
int length = reader.ReadInt32();
+ ErrorUtilities.VerifyProtocol(length <= maxBufferSize, MessagingStrings.DataCorruptionDetected);
byte[] buffer = new byte[length];
ErrorUtilities.VerifyProtocol(reader.Read(buffer, 0, length) == length, MessagingStrings.UnexpectedBufferLength);
return buffer;
diff --git a/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AssociationDataBag.cs b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AssociationDataBag.cs
index ee48670..f619b76 100644
--- a/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AssociationDataBag.cs
+++ b/src/DotNetOpenAuth.OpenId.Provider/OpenId/Provider/AssociationDataBag.cs
@@ -72,7 +72,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
public void Deserialize(Stream stream) {
var reader = new BinaryReader(stream);
this.IsPrivateAssociation = reader.ReadBoolean();
- this.Secret = reader.ReadBuffer();
+ this.Secret = reader.ReadBuffer(256);
this.ExpiresUtc = TimestampEncoder.Epoch + TimeSpan.FromSeconds(reader.ReadInt32());
}
diff --git a/src/DotNetOpenAuth.Test/OAuth2/ResourceServerTests.cs b/src/DotNetOpenAuth.Test/OAuth2/ResourceServerTests.cs
index e9a5921..0ac31b5 100644
--- a/src/DotNetOpenAuth.Test/OAuth2/ResourceServerTests.cs
+++ b/src/DotNetOpenAuth.Test/OAuth2/ResourceServerTests.cs
@@ -21,7 +21,7 @@ namespace DotNetOpenAuth.Test.OAuth2 {
public class ResourceServerTests : OAuth2TestBase {
[Test]
public void GetAccessTokenWithMissingAccessToken() {
- var rsa = new RSACryptoServiceProvider();
+ var rsa = new RSACryptoServiceProvider(512);
var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(rsa, rsa));
var requestHeaders = new NameValueCollection {
@@ -33,7 +33,7 @@ namespace DotNetOpenAuth.Test.OAuth2 {
[Test]
public void GetPrincipalWithMissingAccessToken() {
- var rsa = new RSACryptoServiceProvider();
+ var rsa = new RSACryptoServiceProvider(512);
var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(rsa, rsa));
var requestHeaders = new NameValueCollection {
@@ -42,5 +42,17 @@ namespace DotNetOpenAuth.Test.OAuth2 {
var request = new HttpRequestInfo("GET", new Uri("http://localhost/resource"), headers: requestHeaders);
Assert.That(() => resourceServer.GetPrincipal(request), Throws.InstanceOf<ProtocolException>());
}
+
+ [Test]
+ public void GetAccessTokenWithCorruptedToken() {
+ var rsa = new RSACryptoServiceProvider(512);
+ var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(rsa, rsa));
+
+ var requestHeaders = new NameValueCollection {
+ { "Authorization", "Bearer foobar" },
+ };
+ var request = new HttpRequestInfo("GET", new Uri("http://localhost/resource"), headers: requestHeaders);
+ Assert.That(() => resourceServer.GetAccessToken(request), Throws.InstanceOf<ProtocolException>());
+ }
}
}