Is it possible to create a Uri without a scheme/protocol? - asp.net

I've got a static environment (in the code below refered to as 'staticsite.com') where I store images for my ASP.NET web application and I want to dynamically build up a URI without specifying the scheme.
The following code doesn't work, because it automatically assigns the file:// scheme to the Uri.
Dim baseUri As New Uri("//staticsite.com")
Dim imageUri As New Uri(baseUri, imgUrl.ToString())
After this, baseUri is file://staticsite.com. imageUri becomes file://staticsite.com/someImage.jpg
Is it possible to create a new Uri instance without a scheme/protocol? In the end, I want to have a Uri starting with //staticsite.com and correctly formatted / appended with the imgUrl.
By the way, the reason I'm using Uri is because I don't know if the imgUrl begins with "/" or not and using Uri allegedly was the best option.

Related

Fortify Cross-site scripting: Persistent issue in Response.Binarywrite

In an existing Asp.Net application, we are using Response.BinaryWrite to render image on an aspx page. This is the required functionality, and below is the C# code-
1. byte[] img = getImage();
2. Response.BinaryWrite(img);
The getImage function reads the image from a folder on server and returns byte array. Fortify scan shows cross-site vulnerability on 2nd line.
I did following validations, but fortify still reports it as cross-site issue -
Validated bytearray to check if the file is of correct format (jpeg or bmp), used this link - Determine file type of an image
Response.BinaryWrite(ValidateFileType(img));
Validated the domain in the file path to check if the file is originating from correct domain.
Is there any specific way to pass the fortify cross-site issue with byte array or can i consider it as false positive?
Had to use a workaround to resolve this, below is the old and new code -
Old Code -
1. byte[] byteImage = getImage();
2. Response.BinaryWrite(byteImage);
New Code (Replaced 2nd line in old code with below block) -
byte[] byteImage = getImage();
var msIn = new MemoryStream(byteImage);
System.Drawing.Image img = System.Drawing.Image.FromStream(msIn);
var msOut = new MemoryStream();
img.Save(msOut, img.RawFormat);
Response.BinaryWrite(msOut.ToArray());
msIn.Dispose();
msOut.Dispose();
Response.Flush();
So, basically converting the byteArray to an Image object, and then writing the image object back to the Response.BinaryWrite stream resolved this, and it passed through Fortify scan.
If anyone is looking for a solution, this might help.

HTTP get request won't submit with a URL encoded parameter

I'm currently writing an ASP.NET Core web API that has an action with a encrypted value as a parameter.
I'm trying to test this action and the URL won't even submit in the web browser, at first I thought it could be due to the URL being too long but I've found this answer and my URL is well below the 2000 character limit. I've changed the parameter to a trivial string ("hello") and it submits fine and runs the code. I've tried in both Edge and IE11 whilst debugging my application, in Edge nothing happens at all, in IE11 I get a message saying:
Windows cannot find 'http://localhost:5000/api/...' Check the spelling and try again
In either case the code in the application doesn't execute (I've put a breakpoint on the first line of the controllers constructor which isn't being hit).
I've included an example of one of the URLs that isn't working below, as well as the code I'm using to generate the encrypted string, it uses HttpUtility.UrlEncode to convert the encrypted byte[] array to a string.
Example URL (one that doesn't work):
http://localhost:5000/api/testcontroller/doaction/%95%d6%f8%97%84K%1f%d4%40P%f0%8d%de%27%19%ed%ffAR%9c%c6%d4%b1%83%1e%9fX%ce%9b%ca%0e%d4j%d3Rlz%89%19%96%5dL%b1%16%e9V%14u%c7W%ee%89p%3f%f7%e6d%60%13%e5%ca%00%e9%a2%27%cb%d3J%94%a6%e1%b9%9c%914%06y%7e%0bn%ce%00%e5%7d%98b%85c%fa6m%7d%f7%f1%7b8%26%22%5e%1et%5e%10%0c%05%dd%deFAR%bb%93L%b9-W%e1K%82%d8%cc8%ce%e0%0c%2b%bc%19
Action:
[HttpGet("[action]/{encrypted}")]
public string DoAction(string encrypted)
{
return "Executed";
}
Generate encrypted string:
private string GenerateEncryptedString()
{
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
byte[] data = HttpUtility.UrlDecodeToBytes("AHMW9GMXQZXYL04EYBIW");
byte[] encryptedData = rsaProvider.Encrypt(data, true);
string encryptedString = HttpUtility.UrlEncode(encryptedData);
return encryptedString;
}
Not sure if I'm going wrong in my methodology for converting the encrypted data to a string but I would appreciate any feedback on how to fix this issue.
I think you should try to pass this data in the query string and not in the location (path) part of the url (some characters may be forbidden in paths as a security layer), so add a ?data= before the encoded data.
http://localhost:5000/api/testcontroller/doaction/?data=%95%d6%f8%97%84K%1f%d4%40P%f0%8d%de%27%19%ed%ffAR%9c%c6%d4%b1%83%1e%9fX%ce%9b%ca%0e%d4j%d3Rlz%89%19%96%5dL%b1%16%e9V%14u%c7W%ee%89p%3f%f7%e6d%60%13%e5%ca%00%e9%a2%27%cb%d3J%94%a6%e1%b9%9c%914%06y%7e%0bn%ce%00%e5%7d%98b%85c%fa6m%7d%f7%f1%7b8%26%22%5e%1et%5e%10%0c%05%dd%deFAR%bb%93L%b9-W%e1K%82%d8%cc8%ce%e0%0c%2b%bc%19

UserManager.GenerateEmailConfirmationToken returning tokens unsuitable for URL transmission

I have a ASP.NET MVC 5 website, and I'm implementing an email confirmation process based on the template from Microsoft.
While I'm composing the email body text, first I construct the URL a user will use to "click to verify your address".
To generate the security token I call:
UserManager.GenerateEmailConfirmationTokenAsync(user.Id)
This produces a code such as:
pporPNj6KzdZ3BYG8vQsKJu3dPJMwGgh+ZEGhCNnf9X6F0AS0f6qCowOQwQNfpYkl14bgEsmyPTKya5H6N4n2na2n5PgO+wpoihXxQTA7G8pK/lUYskX3jy2iA/ZM8m4Vm0prTyUuhMgfDlV+wkbR336FBRIAbKJDwOWvHHbJBDQ21gW93hyzca0li66aI1H
Obviously, this wouldn't be valid in a URL, but even URL encoding won't solve IIS's hate of such a URL.
HTTP Error 404.11 - Not Found
The request filtering module is configured to deny a request that contains a double escape sequence.
In my UserManager implementation, I'm using the tutorial boilerplate code for a TokenProvider.
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<SiteUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
How can I make these generated tokens a bit more URL friendly? What did potentially change that would prevent the ASP.NET's tutorial code not work?
It turns out that this token will get mangled by the built in class "UrlHelper" in a MVC controller, or Url in a WebAPI controller IF the target route lists these variables as part of the path, rather than the GET vars of the URL.
Eg: this call, creates a relative URL for the site route called "ConfirmEmail" and fills in the blanks
Url.Route("ConfirmEmail", new { userId = user.Id, code = code });
Before my route was:
[Route("register-email/{code}/{userId}", Name = "ConfirmEmail")]
Changing this to:
[Route("register-email", Name = "ConfirmEmail")]
Generates valid URLS that IIS can chew through. When these are not specified, they get appended after a ? mark as normal GET vars. No idea why IIS is picky like that, but there's the solution.

Comparing URLs in ASP.NET

I have an application that crawls a web site for unique link urls (i.e. hrefs) and then saves the urls to a database. I will ensure that there is url for each page in the site. Below is the code for getting the string that is saved to the database.
'url is the url obtained from the link's href
Dim uriReturn As Uri = New Uri(url, UriKind.RelativeOrAbsolute)
'Make it absolute if it's relative
If Not uriReturn.IsAbsoluteUri Then
Dim baseUri As New Uri(BaseUrl)
uriReturn = New Uri(baseUri, uriReturn)
End If
Return LCase(uriReturn.ToString)
In another part of the application I have section that queries the database with the url of the current page. Below is the code for getting the current page url.
Dim CurrentURL As String = lcase(HttpContext.Current.Request.Url.AbsoluteUri
My question is can I be sure that I will find a match in the database using the current page url? That is could there be differences in the string obtained from the href and the string returned from the current page even through they point to the same page? Is there a way to convert the urls to ensure they will always match?
Since BaseURl is not defined, can't tell if you got it correct. But BaseUrl should be = Request.Url.
And your
Dim CurrentURL As String = lcase(HttpContext.Current.Request.Url.AbsoluteUri
Since you are doing store/retrieve, I suggests you standardize your methods. In store section, you use uriReturn.ToString(), so in the retrieve section, you should also use ToString() instead of AbsoluteUri.

Access the controls from a web page

I want to access the content(controls) on an external web page
http://nccptrai.gov.in/nccpregistry/search.misc
There are a few controls there like the text box, get the value of it,
redirect to http://nccptrai.gov.in/nccpregistry/saveSearchSub.misc
supplying necessary input
You can use this code based on WebClient
System.Net.WebClient wc = new System.Net.WebClient();
byte[] raw = wc.DownloadData("http://nccptrai.gov.in/nccpregistry/saveSearchSub.misc");
//it's also possible to use DownloadString
string webData = System.Text.Encoding.UTF8.GetString(raw);
And so you can parse webData in order to get your wished value

Resources