| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639 |
- //
- // System.Web.HttpRequestTest.cs - Unit tests for System.Web.HttpRequest
- //
- // Author:
- // Sebastien Pouliot <[email protected]>
- // Miguel de Icaza <[email protected]>
- // Gonzalo Paniagua Javier <[email protected]>
- //
- // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- using System;
- using System.Text;
- using System.Web;
- using System.Collections.Specialized;
- using NUnit.Framework;
- using System.Diagnostics;
- namespace MonoTests.System.Web {
- [TestFixture]
- // Tons of failures on msft here.
- [Category ("NotDotNet")]
- public class HttpRequestTest {
- #if NET_1_1
- [Test]
- [ExpectedException (typeof (HttpRequestValidationException))]
- public void ValidateInput_XSS ()
- {
- string problem = "http://server.com/attack2.aspx?test=<script>alert('vulnerability')</script>";
- string decoded = HttpUtility.UrlDecode (problem);
- int n = decoded.IndexOf ('?');
- HttpRequest request = new HttpRequest (null, decoded.Substring (0,n), decoded.Substring (n+1));
- request.ValidateInput ();
- // the next statement throws
- Assert.AreEqual ("<script>alert('vulnerability')</script>", request.QueryString ["test"], "QueryString");
- }
- // Notes:
- // * this is to avoid a regression that would cause Mono to
- // fail again on item #2 of the XSS vulnerabilities listed at:
- // http://it-project.ru/andir/docs/aspxvuln/aspxvuln.en.xml
- // * The author notes that Microsoft has decided not to fix
- // this issue (hence the NotDotNet category).
- [Test]
- [Category ("NotDotNet")]
- [ExpectedException (typeof (HttpRequestValidationException))]
- public void ValidateInput_XSS_Unicode ()
- {
- string problem = "http://server.com/attack2.aspx?test=%uff1cscript%uff1ealert('vulnerability')%uff1c/script%uff1e";
- string decoded = HttpUtility.UrlDecode (problem);
- int n = decoded.IndexOf ('?');
- HttpRequest request = new HttpRequest (null, decoded.Substring (0,n), decoded.Substring (n+1));
- request.ValidateInput ();
- // the next statement throws
- Assert.AreEqual ("\xff1cscript\xff1ealert('vulnerability')\xff1c/script\xff1e", request.QueryString ["test"], "QueryString");
- }
- // This has affected ASP.NET 1.1 but it seems fixed now
- // http://secunia.com/advisories/9716/
- // http://weblogs.asp.net/kaevans/archive/2003/11/12/37169.aspx
- [Test]
- [ExpectedException (typeof (HttpRequestValidationException))]
- public void ValidateInput_XSS_Null ()
- {
- string problem = "http://secunia.com/?test=<%00SCRIPT>alert(document.cookie)</SCRIPT>";
- string decoded = HttpUtility.UrlDecode (problem);
- int n = decoded.IndexOf ('?');
- HttpRequest request = new HttpRequest (null, decoded.Substring (0,n), decoded.Substring (n+1));
- request.ValidateInput ();
- // the next statement throws
- Assert.AreEqual ("<SCRIPT>alert(document.cookie)</SCRIPT>", request.QueryString ["test"], "QueryString");
- }
- //
- // Tests the properties from the simple constructor.
- [Test]
- public void Test_PropertiesSimpleConstructor ()
- {
- string url = "http://www.gnome.org/";
- string qs = "key=value&key2=value%32second";
-
- HttpRequest r = new HttpRequest ("file", url, qs);
- Assert.AreEqual ("/?" + qs, r.RawUrl, "U1");
- Assert.AreEqual (url, r.Url.ToString (), "U2");
- r = new HttpRequest ("file", "http://www.gnome.org", qs);
- Assert.AreEqual (url, r.Url.ToString (), "U3");
- qs = "a&b=1&c=d&e&b=2&d=";
- r = new HttpRequest ("file", url, qs);
- NameValueCollection nvc = r.QueryString;
- Assert.AreEqual ("a,e", nvc [null], "U4");
- Assert.AreEqual ("1,2", nvc ["b"], "U5");
- Assert.AreEqual ("d", nvc ["c"], "U5");
- Assert.AreEqual ("", nvc ["d"], "U6");
- Assert.AreEqual (4, nvc.Count, "U6");
- Assert.AreEqual (null, r.ApplicationPath, "U7");
- }
- [Test][ExpectedException(typeof(NullReferenceException))]
- public void Test_AccessToVars ()
- {
- string url = "http://www.gnome.org/";
- string qs = "key=value&key2=value%32second";
-
- HttpRequest r = new HttpRequest ("file", url, qs);
- string s = r.PhysicalApplicationPath;
- }
- }
- [TestFixture]
- [Category ("NotDotNet")]
- public class Test_HttpFakeRequest {
- class FakeHttpWorkerRequest : HttpWorkerRequest {
- public int return_kind;
- [Conditional ("REQUEST_TEST_VERY_VERBOSE")]
- void WhereAmI ()
- {
- Console.WriteLine (Environment.StackTrace);
- }
-
- public FakeHttpWorkerRequest (int re)
- {
- return_kind = re;
- }
-
- public override string GetUriPath()
- {
- WhereAmI ();
- return "/uri.aspx";
- }
-
- public override string GetQueryString()
- {
- WhereAmI ();
- switch (return_kind) {
- case 20:
- return null;
- case 16:
- return "key1=value1&key2=value2";
- case 25: // HEAD
- case 30: // POST
- return "mapa.x=10&mapa.y=20";
- case 26: // HEAD
- case 31: // POST
- return "mapa.x=10&mapa=20";
- case 27: // GET
- return "mapa.x=10&mapa.y=20";
- case 28: // GET
- return "mapa.x=10";
- case 29: // GET
- return "mapa=10";
- case 32: // GET
- return "mapa.x=pi&mapa.y=20";
- default:
- return "GetQueryString";
- }
- }
-
- public override string GetRawUrl()
- {
- WhereAmI ();
- return "/bb.aspx";
- }
-
- public override string GetHttpVerbName()
- {
- WhereAmI ();
- if (return_kind == 25 || return_kind == 26)
- return "HEAD";
- if (return_kind == 30 || return_kind == 31)
- return "POST";
- return "GET";
- }
-
- public override string GetHttpVersion()
- {
- WhereAmI ();
- return "HTTP/1.1";
- }
-
- public override byte [] GetPreloadedEntityBody ()
- {
- if (return_kind != 30 && return_kind != 31)
- return base.GetPreloadedEntityBody ();
- return Encoding.UTF8.GetBytes (GetQueryString ());
- }
- public override bool IsEntireEntityBodyIsPreloaded ()
- {
- if (return_kind != 30 && return_kind != 31)
- return base.IsEntireEntityBodyIsPreloaded ();
- return true;
- }
- public override int GetRemotePort()
- {
- return 1010;
- }
-
- public override string GetLocalAddress()
- {
- return "localhost";
- }
- public override string GetAppPath ()
- {
- return "AppPath";
- }
- public override string GetRemoteName ()
- {
- return "RemoteName";
- }
- public override string GetRemoteAddress ()
- {
- return "RemoteAddress";
- }
- public override string GetServerName ()
- {
- return "localhost";
- }
-
- public override int GetLocalPort()
- {
- return 2020;
- }
-
- public override void SendStatus(int s, string x)
- {
- }
-
- public override void SendKnownResponseHeader(int x, string j)
- {
- }
-
- public override void SendUnknownResponseHeader(string a, string b)
- {
- }
-
- public override void SendResponseFromMemory(byte[] arr, int x)
- {
- }
-
- public override void SendResponseFromFile(string a, long b , long c)
- {
- WhereAmI ();
- }
-
- public override void SendResponseFromFile (IntPtr a, long b, long c)
- {
- }
-
- public override void FlushResponse(bool x)
- {
- }
-
- public override void EndOfRequest() {
- }
- public override string GetKnownRequestHeader (int index)
- {
- switch (index){
- case HttpWorkerRequest.HeaderContentType:
- switch (return_kind){
- case 1: return "text/plain";
- case 2: return "text/plain; charset=latin1";
- case 3: return "text/plain; charset=iso-8859-1";
- case 4: return "text/plain; charset=\"iso-8859-1\"";
- case 5: return "text/plain; charset=\"iso-8859-1\" ; other";
- case 30:
- case 31:
- return "application/x-www-form-urlencoded";
- }
- break;
-
- case HttpWorkerRequest.HeaderContentLength:
- switch (return_kind){
- case 0: return "1024";
- case 1: return "-1024";
- case 30:
- case 31:
- return GetQueryString ().Length.ToString ();
- case -1: return "Blah";
- case -2: return "";
- }
- break;
- case HttpWorkerRequest.HeaderCookie:
- switch (return_kind){
- case 10: return "Key=Value";
- case 11: return "Key=<value>";
- case 12: return "Key=>";
- case 13: return "Key=\xff1c";
- case 14: return "Key=\xff1e";
- }
- break;
- case HttpWorkerRequest.HeaderReferer:
- switch (return_kind){
- case 15: return "http://www.mono-project.com";
- }
- break;
- case HttpWorkerRequest.HeaderUserAgent:
- switch (return_kind){
- case 15: return "Mozilla/5.0 (X11; U; Linux i686; rv:1.7.3) Gecko/20040913 Firefox/0.10";
- }
- break;
- case HttpWorkerRequest.HeaderAccept:
- switch (return_kind){
- case 21: return "text/xml,application/xml, application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
- }
- break;
- case HttpWorkerRequest.HeaderAcceptLanguage:
- switch (return_kind){
- case 21: return "en-us, en;q=0.5";
- }
- break;
- }
- return "";
- }
- public override string [][] GetUnknownRequestHeaders ()
- {
- if (return_kind == 0)
- return new string [0][];
- if (return_kind == 3){
- string [][] x = new string [4][];
- x [0] = new string [] { "k1", "v1" };
- x [1] = new string [] { "k2", "v2" };
- x [2] = new string [] { "k3", "v3" };
- x [3] = new string [] { "k4", "v4" };
- return x;
- }
- if (return_kind == 4){
- //
- // This tests the bad values and the extra row with an error
- //
- string [][] x = new string [3][];
- x [0] = new string [] { "k1", "" };
- x [1] = new string [] { "k2", null };
- x [2] = new string [] { "k3", " " };
- return x;
- }
- if (return_kind == 2){
- string [][] x = new string [2][];
- x [0] = new string [] { "k1", "" };
- // Returns an empty row.
- return x;
- }
- return null;
- }
- }
- HttpContext Cook (int re)
- {
- FakeHttpWorkerRequest f = new FakeHttpWorkerRequest (re);
- HttpContext c = new HttpContext (f);
- return c;
- }
-
- [Test] public void Test_BrokenContentLength ()
- {
- HttpContext c = Cook (-1);
- Assert.AreEqual (0, c.Request.ContentLength, "C1");
- c = Cook (-2);
- Assert.AreEqual (0, c.Request.ContentLength, "C2");
- }
- [Test][ExpectedException(typeof(NullReferenceException))]
- public void Test_EmptyUnknownRow ()
- {
- HttpContext c = Cook (2);
- NameValueCollection x = c.Request.Headers;
- }
-
- [Test] public void Test_RequestFields ()
- {
- HttpContext c = Cook (1);
- Assert.AreEqual ("AppPath", c.Request.ApplicationPath, "A1");
- Assert.AreEqual ("text/plain", c.Request.ContentType, "A2");
- c = Cook (0);
- Assert.AreEqual (1024, c.Request.ContentLength, "A3");
-
- c = Cook (3);
- Assert.AreEqual ("iso-8859-1", c.Request.ContentEncoding.WebName, "A4");
- NameValueCollection x = c.Request.Headers;
-
- Assert.AreEqual ("v1", x ["k1"], "K1");
- Assert.AreEqual ("v2", x ["k2"], "K2");
- Assert.AreEqual ("v3", x ["k3"], "K3");
- Assert.AreEqual ("v4", x ["k4"], "K4");
- Assert.AreEqual ("text/plain; charset=iso-8859-1", x ["Content-Type"], "K4");
- Assert.AreEqual (5, x.Count, "K5");
- c = Cook (2);
- Assert.AreEqual ("iso-8859-1", c.Request.ContentEncoding.WebName, "A5");
- Assert.AreEqual ("text/plain; charset=latin1", c.Request.ContentType, "A5-1");
- c = Cook (4);
- Assert.AreEqual ("iso-8859-1", c.Request.ContentEncoding.WebName, "A6");
- x = c.Request.Headers;
- Assert.AreEqual ("", x ["k1"], "K6");
- Assert.AreEqual (null, x ["k2"], "K7");
- Assert.AreEqual (" ", x ["k3"], "K8");
- Assert.AreEqual (4, x.Count, "K9");
- c = Cook (5);
- Assert.AreEqual ("iso-8859-1", c.Request.ContentEncoding.WebName, "A7");
- Assert.AreEqual ("RemoteName", c.Request.UserHostName, "A8");
- Assert.AreEqual ("RemoteAddress", c.Request.UserHostAddress, "A9");
- // Difference between Url property and RawUrl one: one is resolved, the other is not
- Assert.AreEqual ("/bb.aspx", c.Request.RawUrl, "A10");
- Assert.AreEqual ("http://localhost:2020/uri.aspx?GetQueryString", c.Request.Url.ToString (), "A11");
- }
-
- [Test] public void Test_Cookies ()
- {
- HttpContext c;
- c = Cook (10);
- c.Request.ValidateInput ();
- Assert.AreEqual ("Value", c.Request.Cookies ["Key"].Value, "cookie1");
- }
- [Test][ExpectedException(typeof (HttpRequestValidationException))]
- public void Test_DangerousCookie ()
- {
- HttpContext c;
- c = Cook (11);
- c.Request.ValidateInput ();
- object a = c.Request.Cookies;
- }
-
- [Test][ExpectedException(typeof(HttpRequestValidationException))]
- public void Test_DangerousCookie2 ()
- {
- HttpContext c;
- c = Cook (12);
- c.Request.ValidateInput ();
- object a = c.Request.Cookies;
- }
-
- [Test][ExpectedException(typeof(HttpRequestValidationException))]
- public void Test_DangerousCookie3 ()
- {
- HttpContext c;
- c = Cook (13);
- c.Request.ValidateInput ();
- object a = c.Request.Cookies;
- }
-
- [Test][ExpectedException(typeof(HttpRequestValidationException))]
- public void Test_DangerousCookie4 ()
- {
- HttpContext c;
- c = Cook (14);
- c.Request.ValidateInput ();
- object a = c.Request.Cookies;
- }
- [Test]
- public void Test_MiscHeaders ()
- {
- HttpContext c = Cook (15);
- // The uri ToString contains the trailing slash.
- Assert.AreEqual ("http://www.mono-project.com/", c.Request.UrlReferrer.ToString (), "ref1");
-
- Assert.AreEqual ("Mozilla/5.0 (X11; U; Linux i686; rv:1.7.3) Gecko/20040913 Firefox/0.10", c.Request.UserAgent, "ref2");
- // All the AcceptTypes and UserLanguages tests below here pass under MS
- c = Cook (20);
- string [] at = c.Request.AcceptTypes;
- string [] ul = c.Request.UserLanguages;
- Assert.IsNull (at, "AT1");
- Assert.IsNull (ul, "UL1");
- c = Cook (21);
- at = c.Request.AcceptTypes;
- Assert.IsNotNull (at, "AT2");
- string [] expected = { "text/xml", "application/xml", "application/xhtml+xml", "text/html;q=0.9",
- "text/plain;q=0.8", "image/png", "*/*;q=0.5" };
- Assert.AreEqual (expected.Length, at.Length, "AT3");
- for (int i = expected.Length - 1; i >= 0; i--)
- Assert.AreEqual (expected [i], at [i], "AT" + (3 + i));
- ul = c.Request.UserLanguages;
- Assert.IsNotNull (ul, "UL2");
- expected = new string [] { "en-us", "en;q=0.5" };
- Assert.AreEqual (expected.Length, ul.Length, "UL3");
- for (int i = expected.Length - 1; i >= 0; i--)
- Assert.AreEqual (expected [i], ul [i], "UL" + (3 + i));
- }
- [Test]
- public void Empty_WorkerRequest_QueryString ()
- {
- HttpContext c = Cook (20);
- //
- // Checks that the following line does not throw an exception if
- // the querystring returned by the HttpWorkerRequest is null.
- //
- NameValueCollection nvc = c.Request.QueryString;
- }
-
- [Test]
- public void Leading_qm_in_QueryString ()
- {
- HttpContext c = Cook (16);
- NameValueCollection nvc = c.Request.QueryString;
- foreach (string id in nvc.AllKeys) {
- if (id.StartsWith ("?"))
- Assert.Fail (id);
- }
- }
- [Test]
- public void TestPath ()
- {
- HttpContext c = Cook (16);
- // This used to crash, ifolder exposed this
- string x = c.Request.Path;
- }
-
- [Test]
- public void MapImageCoordinatesHEAD ()
- {
- HttpContext c = Cook (25);
- int [] coords = c.Request.MapImageCoordinates ("mapa");
- Assert.IsNotNull (coords, "A1");
- Assert.AreEqual (10, coords [0], "X");
- Assert.AreEqual (20, coords [1], "Y");
- c = Cook (26);
- coords = c.Request.MapImageCoordinates ("mapa");
- Assert.AreEqual (null, coords, "coords");
- }
- [Test]
- public void MapImageCoordinatesGET ()
- {
- HttpContext c = Cook (27);
- int [] coords = c.Request.MapImageCoordinates ("mapa");
- Assert.AreEqual (10, coords [0], "X");
- Assert.AreEqual (20, coords [1], "Y");
- coords = c.Request.MapImageCoordinates ("m");
- Assert.AreEqual (null, coords, "coords1");
- c = Cook (28);
- coords = c.Request.MapImageCoordinates ("mapa");
- Assert.AreEqual (null, coords, "coords2");
- c = Cook (29);
- coords = c.Request.MapImageCoordinates ("mapa");
- Assert.AreEqual (null, coords, "coords3");
- c = Cook (32);
- coords = c.Request.MapImageCoordinates ("mapa");
- Assert.AreEqual (null, coords, "coords4");
- }
- [Test]
- public void MapImageCoordinatesPOST ()
- {
- HttpContext c = Cook (30);
- int [] coords = c.Request.MapImageCoordinates ("mapa");
- Assert.IsNotNull (coords, "A1");
- Assert.AreEqual (10, coords [0], "X");
- Assert.AreEqual (20, coords [1], "Y");
- c = Cook (31);
- coords = c.Request.MapImageCoordinates ("mapa");
- Assert.AreEqual (null, coords, "coords2");
- }
- [Test]
- public void NegativeContentLength ()
- {
- HttpContext c = Cook (1);
- HttpRequest req = c.Request;
- Assert.AreEqual (0, req.ContentLength, "#01");
- }
- }
- #endif
- }
|