So basically I have an ajax call which hits a method which returns a partial view and to display the data I use jQuery.html().
We are running our code through a veracode security tool and it's raising a XSS vulnerability.
Here is the jquery:
$.ajax({
url: "ReturnTransNoInformation",
data: { __RequestVerificationToken: ReturnAntiForgeryToken(), TransNo: $("[data-trans-no]").val() },
type: "POST",
beforeSend: function () {
TransNoInfoAjaxBegin("[data-view-trans-no-container]");
},
success: function (data) {
if (data.Success === false) {
if (data.ErrorMessage !== undefined && data.ErrorMessage !== null && data.ErrorMessage !== "") {
Error(data.ErrorMessage);
}
else {
Error("Something went wrong while loading the TransNo info, please refresh the page and try again.")
}
$("[data-transno-partial]").html(null); //Potential XSS
}
else {
$("[data-transno-partial]").html(data); //Potential XSS
}
},
error: function () {
Error("Something went wrong while loading the TransNo info, please refresh the page and try again.")
},
complete: function () {
AjaxComplete("[data-view-trans-no-container]");
}
});
My C# code:
[AuthorizeUsers(new UserLevel[] { UserLevel.SubRepMaster, UserLevel.Regional })]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ReturnTransNoInformation(string transNo) {
if (string.IsNullOrWhiteSpace(transNo)) return Json(new { Success = false, ErrorMessage = "Error: TransNo cannot be empty" });
var info = await _iAccountingManager.ReturnTransNoInfoAsync(transNo, SessionInfo.CIDs);
if (info == null) return Json(new { Success = false, ErrorMessage = "Error: TransNo does not exist" });
return PartialView("~/Views/Accounting/Partials/_TransNoInfo.cshtml", new TransNoInfoViewModel(info));
}
My partial view is entirely controller by me with no JS in the partial view. Is this an actual XSS vulnerability?
If you are under control of the code being displayed, then no.
XSS relies on a malicious third party inputting code into your website.
If there are no third parties which can change the input to their desired input, then there is no problem with XSS on your site.
Related
I have a simple LogIn form, which on LogIn button clicked performs ajax call to ActionResult LogIn(LogInRequest request) in AccountController that returns JsonResult. I have CustomHandleErrorAtribute that inherits from HandleErrorAttribute and redirects to CustomErrorPage.cshtml.
Somwhere in the ActionResult exception is thrown, that should be handled by CustomHandleErrorAtribute and it is handled. Then the CustomErrorPage action is executed but it doesnt actualy return the view. It stays on same LogInPage.
My LogIn action in AccountsController
[AllowAnonymous]
[HttpPost]
[CustomAttributes.CustomHandleError]
public ActionResult Login(LogInRequest request)
{
StandartResponse finalResult = new StandartResponse();
//some code that trows exception
return new JsonResult() { Data = finalResult.Result};
}
My Ajax call on LogIn button clicked:
function LogInUser(s, e) {
var example = { username: UserName.GetValue(), password: Password.GetValue() };
$.ajax({
contentType: "application/json; charset=utf-8",
dataType: 'json',
type: "POST",
url: "/Account/LogIn",
data: JSON.stringify({ request: example }),
success: function (data) {
jQuery.ajaxSettings.traditional = true;
if (data.Status == InfoType.Success) {
alert('success');
var url = "/Home/Index";
window.location.href = url;
}
else {
alert('here');
var result = JSON.stringify(data.Infoes);
popUpErrorMessagePartial.PerformCallback({ message: result });
popUpErrorMessagePartial.Show();
}
},
error: function(){
alert('error');
}
});
}
CustomHandleErrorAttribute:
public override void OnException(ExceptionContext filterContext)
{
filterContext.ExceptionHandled = true;
filterContext.Result =
new RedirectToRouteResult(new RouteValueDictionary
{
{ "action", "ErrorUnauthorised" },
{ "controller", "CustomErrorPages" },
{ "Area", String.Empty }
});
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
}
After debugging the Action of CustomErrorPage is executed, but then the error in the ajax call is executed, the allert is displayed and no redirection is performed. Do you know how to handle this?
Because you do get an exception, the ajax call itself fails, which is why you get the alert, but you can't redirect to another page inside the server side of an ajax call. Instead you can put the redirect inside the fail block of your ajax call. Something like....
error: function(){
window.location = <put error page url here>
alert('error');
}
I am making a json request and i want a specific div to appear if the result from the request is true.
Currently I am getting the error bellow , could you please help me with the solution ?
Microsoft JScript runtime error: Object doesn't support property or
method 'val'
p.s : I have checked through console that json returns correctly "true" and the issue is on success.
I am attaching the code bellow.
Script :
<script type='text/javascript'>
$(document).ready(function () {
$('#ComputerLocation').hide();
$('#typeddl').on('change', function () {
$.ajax({
type: 'POST',
url: '#Url.Action("GetItemTypeForm")',
data: { itemTypeId: $('#typeddl').val() },
success: function (result) {
if (result != null && result.val(this.Value) == 'true') {
$('#ComputerLocation').show();
};
}
});
});
});
</script>
Controller:
[HttpPost]
public JsonResult GetItemTypeForm(int itemTypeId)
{
//pseudo code
var data = from s in db.ItemTypes
where s.ItemTypeId == itemTypeId
select new { Value = s.IsComputer };
return Json(data);
}
if I understood correctly :
When you try to get val() in this line
(ifresult != null && result.val(this.Value) == 'true') {
you are assuming result has a function called val, but in json you cant send function and you are trying to send this function this.Value and that really don't make any sense at all.
I assume you want to :
if (result != null && result.val == 'true') {
and in this line also you are using this I think that might also be wrong. You should set this to another field before using in ajax callback.
<script type='text/javascript'>
$(document).ready(function () {
$('#ComputerLocation').hide();
$('#typeddl').on('change', function () {
var that = this; // now this is an jquery object
$.ajax({
type: 'POST',
url: '#Url.Action("GetItemTypeForm")',
data: { itemTypeId: $('#typeddl').val() },
success: function (result) {
if (result != null && result.val == 'true') { // maybe you want to check that.val()
$('#ComputerLocation').show();
};
}
});
});
});
I have a MVC4 single page website with a form. The loading of the contents is achieve with ajax. I do not know how to get the data out from JSON in C#? Here is my code:
JavaScript:
$("#subnt").click(function (event) {
event.preventDefault();
var url = "/Home/Submit";
$.post(url, $('form[name="cnt_us-frm"]').serialize(), function (data) {
if (data.Success === true) {
$("#min-content").hide().load("/Home/PartialSubmit").fadeIn('normal'); // loads the page into 'min-content' section
}
else {
// display error message
}
})
});
});
C#:
[HttpPost]
public JsonResult Submit()
{
return Json(new { Success = true, SomeOtherData = "testing" });
}
Please check below working code -
I have used exactly your working code -
[HttpPost]
public JsonResult Submit()
{
return Json(new { Success = true, SomeOtherData = "testing" });
}
Then I used following JQuery to hit the above action -
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
$(function () {
$('#click').click(function (e) {
$.ajax({
url: "#Url.Action("Submit")",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
error: function (response) {
alert(response);
},
success: function (data) {
if (data.Success == true)
alert(data.SomeOtherData);
}
});
});
});
</script>
<input type="submit" value="click" id="click" />
And as the output I was able to get an alert as shown below -
Easiest thing to do is use the superior json.net
[HttpPost]
public string Submit()
{
var result = new { success = true, someOtherDate = "testing"};
var json = JsonConvert.SerializeObject(result);
return json;
}
Your code is ok bu you can add debugger.and open developer tools check your data .
$.post(url, $('form[name="cnt_us-frm"]').serialize(), function (data) {
debugger;
if (data.Success === true) {
$("#min-content").hide().load("/Home/PartialSubmit").fadeIn('normal'); // loads the page into 'min-content' section
}
else {
// display error message
}
No, the other way around. How to retrieve the data from the form (json).
I know this is duplicate but I could not get reliable solution(for asp.net web).
I just want to redirect to the login page if session expires.
I have tried following:
1. using jquery status code
$.ajax({
type: "POST",
url: "stream.asmx/SomeMethod",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
//success msg
},
error: function (request, status, error) {
if (status = 403) {
location.href = 'login.aspx';
}
}
});
Problem: this returns same status code(403) for other errors too, which I only expect for session timeout.
2. Sending json message whether session expired
code behind:
if (!object.Equals(HttpContext.Current.Session["User"], null))
{
Id = int.Parse(HttpContext.Current.Session["User"].ToString());
}
else
{
result = from row in dtscrab.AsEnumerable()
select new
{
redirectUrl = "login.aspx",
isRedirect = true
};
}
on $.ajax success:
success: function (msg) {
if (msg.d[0].isRedirect) {
window.location.href = msg.d[0].redirectUrl;
}
else {
//load containt
}
}
Problem: It's somehow desn't invoke ajax success line if session expires(it does return correct json). And even this is not a proper way if I have many number of ajax request in the page(should be handled globally).
However, I saw this post which is really good soltion but it's for mvc using AuthorizeAttribute: handling-session-timeout-in-ajax-calls
So, Is there I can use same concept used in mvc using AuthorizeAttribute in asp.net web api? If not, how I can troubleshoot those issue which I'm facing (any of above two mentioned)?
A 403 status code is going to cause jQuery to call the failure method. Keep the same code behind from your second try, but move the redirect handler to the failure method instead of the success method. In the success method, treat it as you normally would.
Problem:
I had same problem in my Razor MVC Application throwing exceptions while ajax calls made when session timed out.
The way I have managed to get this issue sorted is by monitoring each ajax requests by using a simple light weight Action Method (RAZOR MVC) returning a bool variable whether the Request is Authenticated or not. Please find the code below..
Layout/Master Page / Script file:
<script>
var AuthenticationUrl = '/Home/GetRequestAuthentication';
var RedirectUrl = '/Account/Logon';
function SetAuthenticationURL(url) {
AuthenticationUrl = url;
}
function RedirectToLoginPage() {
window.location = RedirectUrl;
}
$(document).ajaxStart(function () {
$.ajax({
url: AuthenticationUrl,
type: "GET",
success: function (result) {
if (result == false) {
alert("Your Session has expired.Please wait while redirecting you to login page.");
setTimeout('RedirectToLoginPage()', 1000);
}
},
error: function (data) { debugger; }
});
})
Then in Home Controller/Server side you need a method to verify the request and return the boolean variable..
public ActionResult GetAuthentication ( )
{
return Json(Request.IsAuthenticated, JsonRequestBehavior.AllowGet);
}
This will validate each ajax request and if the session got expired for any ajax request, it will alert the user with a message and redirect the user to the login page.
I would also suggest not to use standard Alert to Alert. User some Tool tip kind of formatted div Alerts. Standard JS Alerts might force the user to click OK before redirection.
Hope it helps.. :)
Thanks,
Riyaz
Finally, I ended up following.
public class IsAuthorizedAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
var sessions = filterContext.HttpContext.Session;
if (sessions["User"] != null)
{
return;
}
else
{
filterContext.Result = new JsonResult
{
Data = new
{
status = "401"
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
//xhr status code 401 to redirect
filterContext.HttpContext.Response.StatusCode = 401;
return;
}
}
var session = filterContext.HttpContext.Session;
if (session["User"] != null)
return;
//Redirect to login page.
var redirectTarget = new RouteValueDictionary { { "action", "LogOn" }, { "controller", "Account" } };
filterContext.Result = new RedirectToRouteResult(redirectTarget);
}
}
Handling client side
<script type="text/javascript">
$(document).ajaxComplete(
function (event, xhr, settings) {
if (xhr.status == 401) {
window.location.href = "/Account/LogOn";
}
});
</script>
you can set session time out expire warning some thing like ....
<script type="text/javascript">
//get a hold of the timers
var iddleTimeoutWarning = null;
var iddleTimeout = null;
//this function will automatically be called by ASP.NET AJAX when page is loaded and partial postbacks complete
function pageLoad() {
//clear out any old timers from previous postbacks
if (iddleTimeoutWarning != null)
clearTimeout(iddleTimeoutWarning);
if (iddleTimeout != null)
clearTimeout(iddleTimeout);
//read time from web.config
var millisecTimeOutWarning = <%= int.Parse(System.Configuration.ConfigurationManager.AppSettings["SessionTimeoutWarning"]) * 60 * 1000 %>;
var millisecTimeOut = <%= int.Parse(System.Configuration.ConfigurationManager.AppSettings["SessionTimeout"]) * 60 * 1000 %>;
//set a timeout to display warning if user has been inactive
iddleTimeoutWarning = setTimeout("DisplayIddleWarning()", millisecTimeOutWarning);
iddleTimeout = setTimeout("TimeoutPage()", millisecTimeOut);
}
function DisplayIddleWarning() {
alert("Your session is about to expire due to inactivity.");
}
function TimeoutPage() {
//refresh page for this sample, we could redirect to another page that has code to clear out session variables
location.reload();
}
4xx are HTTP error status codes and would cause jquery to execute the onFailure callback.
Also, beware of using 3xx for redirects when you want to process the payload. Internet Explorer, in my experience, just does a redirect (without looking at the payload) when a 3xx status code is returned.
I'd say, throw a 403 and handle the situation. To the client 403 implies the resource access is forbidden. There can be multiple reasons, which is OK I guess.
For those using a ScriptManager, you can easily check for ajax request and then redirect with the following code:
private void AjaxRedirect(string url)
{
Response.StatusCode = 200;
Response.RedirectLocation = url;
Response.Write("<html></html>");
Response.End();
}
Then check for request type and redirect accordingly (using routes here):
if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
{
var redirectUrl = RouteTable.Routes.GetVirtualPath(null, "Default", null).VirtualPath;
AjaxRedirect(redirectUrl);
}
else
{
Response.RedirectToRoute("Default");
}
The "Default" route is a route defined in the routes collection:
routes.MapPageRouteWithName("Default", "", "~/default.aspx");
If you prefer, instead of using ScriptManager for ajax request check, you can use:
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest") {
code here...
}
As mentioned in the title, i cannot login everytime for the first time, but subsequent time I can login, where is wrong?Any Help will be appreciated! Or any new ways to implement the code? I'm new to it, it will also serve as a learning experience to me :)
Also is there any way in Razor to make Url.Action to string url instead of Object?
jQuery Client Side:
//To be submitted to the server for authentication
<script>
$(".btn").click(function () {
login();
});
function login() {
var username = $("#username").val();
var password = $("#password").val();
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
//url: "/member_control.asmx/Login",
url: '#Url.Action("Index", "Home")',
dataType: 'json',
data: '{"username": "' + username + '","password": "' + password + '" }',
success: function(result) {
if (result.Success) {
window.location.href = result.redirectToUrl;
} else {
alert(result.Message);
}
}
});
}
</script>
Json Server Side:
//json will be returning back to the jquery request
[AllowAnonymous]
[HttpPost]
public JsonResult Index(LoginModel1 model, Object redirectToUrl){
//set default
redirectToUrl = Url.Action("Test", "Home");
if (ModelState.IsValid)
{
if (DataAccess.DAL.UserIsValid(model.Username, model.Password))//Authentication
{
FormsAuthentication.SetAuthCookie(model.Username, false);
return Json(new { Success = true, redirectToUrl = Url.Action("Test", "Home") });
}
{
return Json(new { Success = false, Message = "Login failed, invalid username or password." });
}
}
return Json(new { Success = false, Message = "Login failed" });
}
Well this is not recommended to logged in via ajax but in your case the problem might be because of caching. Add an option cache : false in your current jquery ajax request and problem will be resolved.
Example :
$.ajax({
cache : false,
// existing stuff
});