Reputation: 21
On a C# ASP.NET application, I've managed to bypass basic authentication (by sending the username/password through "Authorization" headers on a HTTPWebRequest) and I finally got the unlocked the target page that is protected by htaccess (located on a different server, basic auth) and sent the stream back to the browser.
The issue appears as soon as the user clicks on a link, the basic auth logon box pops up again. We don't want the user to enter to username/password again.
It seems that I need to be sending something back in the headers to tell the browser what username/password it's using for authorization.
I've tried:
Considerations:
Is there a way to achieve this? (It can be done in JavaScript as well).
This is my function for the HttpRequest:
public void DoWebRequest(String email, String psw, String hostname,
int port, String req_method, String webpage)
{
String path = hostname + ":" + port + "/" + webpage;
String userdata = email + ":" + psw;
System.Text.ASCIIEncoding encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(path);
byte[] authBytes = Encoding.UTF8.GetBytes(userdata.ToCharArray());
String req_short_host_temp = hostname;
String req_short_host = req_short_host_temp.Replace("http://", "");
Uri uri = new Uri(path);
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri) as HttpWebRequest;
req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705;)";
req.Method = req_method;
req.PreAuthenticate = false;
req.Headers["Authorization"] = "Basic " + Convert.ToBase64String(authBytes);
req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
req.Headers.Add("Accept-Language: en-us,en;q=0.5");
req.Headers.Add("Accept-Encoding: gzip,deflate");
req.Headers.Add("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7");
req.KeepAlive = true;
req.Headers.Add("Keep-Alive: 1000");
req.ReadWriteTimeout = 320000;
req.Timeout = 320000;
req.Host = req_short_host;
req.AllowAutoRedirect = true;
req.ContentType = "application/x-www-form-urlencoded";
req.Headers.GetType().InvokeMember("ChangeInternal", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, req.Headers, new object[] { "Host", req_short_host });
var headers = new MyHeaderCollection();
req.Headers = headers;
headers.Set("Host", req_short_host);
StreamWriter sw = new StreamWriter(req.GetRequestStream());
sw.Write("/" + "?user=" + email + "&password=" + psw);
sw.Close();
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string tmp = reader.ReadToEnd();
foreach (Cookie cook in response.Cookies)
{
tmp += "\n" + cook.Name + ": " + cook.Value;
}
Response.Write(tmp);
Response.End();
}
Upvotes: 2
Views: 4407
Reputation: 3701
Don't know about javascript, but there is no way in c# to do this I believe. You may filter all user interaction so the browser never accesses the other server directly. To do this, rewrite all urls in content to point to your script (reverse proxy).
Upvotes: 0