diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2012-11-11 20:13:12 -0800 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2012-11-11 20:13:12 -0800 |
commit | 83d3efa71da483d55900cbd38d17afa4b6403bef (patch) | |
tree | 8877888069f2e0b6f5ebe828a6686c5927234b42 | |
parent | 446371c4c113c23abec15695e756aecedd44e56d (diff) | |
download | DotNetOpenAuth-83d3efa71da483d55900cbd38d17afa4b6403bef.zip DotNetOpenAuth-83d3efa71da483d55900cbd38d17afa4b6403bef.tar.gz DotNetOpenAuth-83d3efa71da483d55900cbd38d17afa4b6403bef.tar.bz2 |
Avoids OOM exceptions from ResourceServer
Related to #178
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>()); + } } } |