I have a simple post method in a MVC controller that checks whether the ModelState is valid then calls another method passing an instance of the model as a paramter. This model contains sensitive data that is easily obtained by looking at Fiddler. My goal is to somehow mask or encrypt this data so that it cannot be seen in an http trace.
I have seen posts suggesting to use Session or Temp variables but that is not an option in my case.
This is what the code looks like:
[HttpPost]
[ActionName("Search")]
[AccessControl(Xri)]
public ActionResult SearchPost(string string1, ViewModel model)
{
model.NoResults = false;
if (ModelState.IsValid)
{
if (ModelState.IsValid) return RedirectToAction("TargetAction", model);
}
}
[AccessControl(Xri)]
public ActionResult TargetAction(string arg, ViewModel viewModel)
{
.
.
.
}
Fiddler shows the following:
/TargetAction?id=01010101&date=08%2F14%2F2013%2000%3A00%3A00&To=08%2F21%2F2013%2000%3A00%3A00¶m1=somevalue¶m2=somevalue2
Is there a way to mask the url parameters shown here?
You're going to need to get SSL running on your server.
Without a server certificate from a trusted authority, there is very little you can do to encrypt the data over the wire. Why? Because you'd need to send encryption/decryption details in clear text before you start sending the data so that your client (likely JavaScript) could decode it.
Using a certificate and operating on 443 gives you built-in functionality from the server/browser that is hard to beat in a custom implementation.
If you just want to obscure the data (and put it beyond the level of most web users) you could always base64 encode the data, rather than encrypting it. Just be clear that you are NOT encrypting data and it is still possible to decode it. This approach is not a form of encryption.
If you decide to take that approach regardless, here are a few resources:
Client-side Encoding/Decoding
MSDN Reference on Encoding to Base64
Cheers.
You have two options for doing this:
Store the data on the server and give the user a token (e.g. a GUID) to pass along to retrieve the data. Since using the Session or TempData is not an option, you could store the viewmodel in the database, and then redirect the user with the token in the URL to retrieve it on the next request.
The other option would be to have the user pass the viewmodel in the URL as you're currently doing, but pass it in an encrypted format. For example, you could
serialize the model to JSON, encrypt it using one of .NET's built in encryption algorithms, and then redirect to the next action passing the encrypted string as your view model. Then you could change the target action to something like:
[AccessControl(Xri)]
public ActionResult TargetAction(string arg, string encryptedViewModel)
{
var decryptedString = Decrypt(encryptedViewModel) ; // supply the decrypt function to match your encryption
var viewModel = JsonConvert.DeserializeObject(decryptedString);
}
Related
I have 2 controllers: a Subscriptions controller and a PaypalExplress controller. First handles all subsription data, second handles paypal transactions.
The problem is a have to path somehow a price amount (#subscription.price) from Subscriptions to paypal controller. I thought about session[] and params[] hashes, but I assume it's not a secure way to do this.
Try this...
You can encrypt and decrypt your session parameter.
Encode(Session["price"].ToString());
public string Encode(string encodeMe)
{
byte[] encoded = System.Text.Encoding.UTF8.GetBytes(encodeMe);
return Convert.ToBase64String(encoded);
}
public static string Decode(string decodeMe)
{
byte[] encoded = Convert.FromBase64String(decodeMe);
return System.Text.Encoding.UTF8.GetString(encoded);
}
Is #subscription not an instanced model? If you have a row in a database just redirect to the appropriate URL passing along the subscription ID and retrieve the data on the other side.
You need to understand routing and it wouldn't hurt to read some getting started guides on the MVC principle.
This is driving me crazy. I'm using ASP.NET MVC. I have a controller with an HttpPost action that acts as a callback URL that is called by another server (not under my control). I want to dynamically read JSON posted to it without using WebAPI or Model Binding. The URL also has a query string parameter passed to it.
The callback URL looks something like this:
http://domain.com/callback?secret=1234
I've tried reading the posted input using:
[HttpPost]
public ActionResult Callback( String secret )
{
String jsonData = new StreamReader(this.Request.InputStream).ReadToEnd();
// ...
}
However "jsonData" is always null or empty.
I just want to get the posted input and stick it into JsonFx so I can dynamically access the contents. Any ideas on how to do this the easiest possible way?
UPDATE
I've discovered the following ...
While the above DOES NOT work (jsonData will be null or empty), the following DOES if I configure what little options I have on the calling server so as to omit the "secret" query string parameter, which is about all I can do on that end since it is not my server. In this case, jsonData will have the correct posted JSON string:
[HttpPost]
public ActionResult Callback( /* String secret */ )
{
String jsonData = new StreamReader(this.Request.InputStream).ReadToEnd();
// ...
}
This is very frustrating to work around and I don't know an easy way to accept both a query string and posted JSON data on a standard MVC controller.
I have a "callback controller" with Action methods that accept various data (via GET, via form POST, via JSON POST, via JSON POST w/ a Query String, etc.) from different third-party servers. These are merchant-type callbacks where I have no control over the formats or methods used to convey information. I just need to accept the callbacks and process the information that should be there.
All of it works fine in my Controller, except the case of "JSON POST w/ a Query String".
This appears (at least to me) to be a shortcoming in standard ASP.NET MVC controllers. ???
Can anyone suggest a solution to this that can be used in a standard ASP.NET MVC controller?
Your initial approach should work if you take into consideration the fact, that ASP.NET MVC model binding has already read the stream, so you should rewind it:
[HttpPost]
public ActionResult Callback(string secret)
{
Request.InputStream.Seek(0, SeekOrigin.Begin);
string jsonData = new StreamReader(Request.InputStream).ReadToEnd();
// ...
}
Reset the position to Zero before reading the stream.
Request.InputStream.Position = 0
For ASP.NET Core 2,this works for me.
[HttpPost]
public ActionResult RawTest() {
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
{
string content = reader.ReadToEndAsync().Result;
//...
}
//...
}
If I have a controller:
[HttpPost]
public ReturnType ControllerMethod(CustomModel c)
{
...
}
A third party is posting data to this method:
abc-xyz=testdata
One way, would be to use:
Request.Params["abc-xyz"]
However, in the case where the Request could contain malicious code, if any Request Parameter contained some problematic code, IIS would throw an HttpRequestValidationException as soon as Request.Params[""] is called.
Now, rather than turn off that validation everywhere, I'd like to map the posted data to my model. That way, if the "potentially malicious code" is contained in any parameter that isn't "abc-xyz", my application won't throw a HttpRequestValidationException. It will however, check the used paramaters, and throw a HttpRequestValidationException if the accessed data is potentially malicious.
How do I do that if the posted data has a dash/hyphen in the name?
I've tried a few variations including:
public class CustomModel
{
[Required]
public string abc_xyz
}
You should write your own ModelBinder in this case that transforms the values from the request into the ones needed for CustomModel.
To over come the request validation, you can turn it off with the ValidateInputAttribute on your controller action.
I have a simple web app that has a login page, the front end domain has a simple model with:
string username {get;set;}
string password {get;set;}
However it is encrypted with sha256 before it is sent over to the data domain object, originally the data domain was:
string username {get;set;}
string password {get;set;}
So I would take the password from the ui, encrypt it then using the Encoding.GetString() method, get back a string for persisting. However when I try to persist the data it just seems to give an exception, which I believe to be down to the characters in the string not being valid.
After looking around some people have recommended storing it as a varbinary(32) and using a byte[] password {get;set;} within the data layer, however I couldn't get Nhibernate to map it correctly.
So can anyone tell me the best practise on storing hashed passwords with Nhibernate and SqlServer or MySql. (The app supports both dbs)
You shouldn't use Encoding.GetString() on a SHA value since it will produce text that may not store correctly, or worse, give an exception. Rather use something like Convert.ToBase64String.
I understand that IIS logs parts of http request which I can access. I would like to log the whole http request for a short period of time. This means I would like to store the data being posted in its raw form. Is this possible using ISS’s logging facility or do I have to install another tool?
I have the following problem. I expose a ‘restful web service’ via asp.net mvc which stores posted data in a relational database. I tested the service via javascript. I url encoded some data and post them using jquery. The data is stored url encoded in the database as expected. Some clients also post data using unix and wget to the same web service. Unfortunately, the data is not stored url encoded (so we lose some data if it contains special characters like &). They claim that they send the data url encoded. Can this be a case true? Is the mechanics of wget post different to that of a javascript post? Is there a layer I overlook? I would like to double check whether the data send via wget is actually url encoded.
Thanks!
Best wishes,
Christian
You could create an MVC action filter, you could then have access to the Request object and pull out the interesting bits. You could then store this information in a text file or logging database. I've used this approach before and it works well if you thread the saving to database operation to not slow down the general request operation.
public class LogRequest : ActionFilterAttribute, IActionFilter
{
#region IActionFilter Members
void IActionFilter.OnActionExecuting(ActionExecutingContext var)
{
//code goes here
}
#endregion
}
[AcceptVerbs(HttpVerbs.Get)]
[LogRequest()]
public ActionResult Index()
{
return View();
}
You've kind of asked two questions here, I don't know about the second part.