How to resolve Security code scan SCS0016 in API controller - asp.net-core

We have implemented weather API controller to update weather data and inherited ControllerBase in API controller with APIController action filter like below and enabled security code scan.
using Microsoft.AspNetCore.Mvc;
namespace SampleApiApplication.Controllers
{
[ApiController]
public class WeatherForecastController : ControllerBase
{
[HttpPost]
[Route("UpdateWeatherDetails")]
public IEnumerable<WeatherForecast> PostWeatherDetails(WeatherForecast weatherForecast)
{
// Some lines of code to implement
}
}
}
I can be able to post Json content data, but I Could not able to post data with content type as application/x-www-form-urlencoded in UpdateWeatherDetails API.
To resolve the above issue, I have used [FromForm] attribute to post form data like below, now I am able to post form data and Json data. But I have faced security warning SCS0016.
using Microsoft.AspNetCore.Mvc;
namespace SampleApiApplication.Controllers
{
[ApiController]
public class WeatherForecastController : ControllerBase
{
[HttpPost]
[Route("UpdateWeatherDetails")]
[Consumes("application/json")]
public IEnumerable<WeatherForecast> PostWeather([FromBody] WeatherForecast weatherForecast)
{
return PostMethod(weatherForecast);
}
[HttpPost]
[Route("UpdateWeatherDetails")]
public IEnumerable<WeatherForecast> PostWeatherDetails([FromForm] WeatherForecast weatherForecast)
{
// Some lines of code to implement
}
}
}
I thought after adding FromForm attribute only facing security warning and removed it, now no security warning, but I am unable get data binding to parameter. Now,  I have removed [ApiController] attribute and tried to post form data, Now I am able to post form data.
But I am again getting Security warning** SCS0016 **for that method.
How to resolve the above Security issue and get data send with application/x-www-form-urlencoded working?

Related

Swagger Duplication

I'm using Swagger to document an API.
[ApiController]
[Route("v1/[controller]/[action]")]
[Route("fullrecord/{provider}/{identifier}")]
public class FullRecord : ControllerBase
{
[HttpGet]
public string GetRecordMethod(string provider, string identifier)
{
Swagger then reports both the route, and the method name.
FullRecord
GET
​/v1​/FullRecord​/GetRecordMethod
GET
​/v1​/fullrecord​/{provider}​/{identifier}

Why does not working version in asp.net core controller

I want to use api version in my .net core project.Then search web and find that's solution.
Even though do exactly all solutions,but I can't get desired result.
So if any can help me,Please show me..
I add Microsoft.AspNetCore.Mvc.Versioning 4.0.0 Package in my project and ..
StartUp.cs
Then in my Controller Add Rout Attribute as Shown :
[ApiController]
[Authorize]
[Route("v{version:apiVersion}/[Controller]")]
[ApiVersion("1.0")]
public class SellerController : Controller
{
private readonly IBus _client;
private readonly string AppBaseUrl = MyHttpContext.AppBaseUrl;
//private readonly IGetUrl _globalUrl;
public SellerController(IBus client/*, IGetUrl globalUrl*/)
{
_client = client;
//_globalUrl = globalUrl;
}
[HttpGet("/Sellers/{SellerId}")] // Dashboard
public async Task<IActionResult> Info(long SellerId)
{
...
}
}
With these code I expected that I can send request to 'Info' method by this url :
But that's not working and get 404 error code status.. when I delete "/v1.0" from url and send request, that's working. I will be glad to help me .. Thanks
In your code, we can find that you applied [HttpGet("/Sellers/{SellerId}")] with route
template begin with / to Info action method, which don't get combined with route templates applied to the controller. To make request to 'Info' method, you could use below URL.
https://localhost:5090/sellers/17
I expected that I can send request to 'Info' method by this url : https://localhost:5090/v1.0/sellers/17
To achieve your requirement, you can try to modify the code like below.
[HttpGet("/v{version:apiVersion}/Sellers/{SellerId}")]
public async Task<IActionResult> Info(long SellerId)
{
//...
//for testing purpose
return Ok(SellerId);
}
Test Result
Update:
If you'd like to include v{version:apiVersion} in route template of controller level attribute routing, you can try to apply [HttpGet("{SellerId}")] to Info action method and make request with https://localhost:5090/v1.0/seller/17.
[ApiController]
[Authorize]
[Route("v{version:apiVersion}/[Controller]")]
[ApiVersion("1.0")]
public class SellerController : Controller
{
[HttpGet("{SellerId}")] // Dashboard
public async Task<IActionResult> Info(long SellerId)
{
//...

How do I get Route attribute to work in .net core api?

So I added a controller to a blank asp.net CORE Api.
public class IsAliveController : ControllerBase
{
[HttpPost]
[HttpGet]
[Route("isalive")]
public object Get()
{
return "I'm alive";
}
}
Then I try to access it via https://localhost:44361/isalive
and I get no response. Do I need to make some modifications to my Startup.cs?
First why have you declared your method both as a get and a post request? you can remove the post attribute.
By default your routing must start with your controller name, add this:
[Route("[controller]")]
[ApiController]
public class IsAliveController : ControllerBase
{
[HttpGet]
public object Get()
{
return "I'm alive";
}
}
Now when you call https://localhost:44361/isalive you will receive the expected response.
There are two solutions to your problem:
#1 Your controller Name is IsAlive and you have added a route attribute on your action method as isAlive, so this would work only if you call using this Url
https://localhost:44361/isalive/isalive
#2 Remove the Route attribute from the action method
public class IsAliveController : ControllerBase
{
[HttpGet]
public object Get()
{
return "I'm alive";
}
}
and you will be able to access using Url
https://localhost:44361/isalive
Found the issue. The template I choose (using Visual studio 2019) was:
Asp.net core web app > Web Application
The startup file in this template is missing a line that I needed to add:
app.UseEndpoints(endpoints =>
{
//Add this line
endpoints.MapControllers();
});
After adding that line the endpoint works without any changes to the controller.

Apply [FromBody] attribute to all controller actions in .net core

Having a simple .NET Core API with your models posted as JSON in request body, how to have [FromBody] attribute applied to all controller methods?
[Route("api/simple")]
public class SimpleController : ControllerBase
{
[HttpPost]
public IActionResult Post([FromBody] MyRequest request)
{
return Ok();
}
}
If I remove the [FromBody] attribute, all model properties will be null.
If you POST your model inside the body with Content-Type: application/json then you have to tell the ModelBinder to read the model from body by applying [FromBody] attribute.
But adding [FromBody] to all of your API actions makes you feel bad.
Just apply the [ApiController] to your controller and then you don't need [FromBody] anymore.
Microsoft Doc definition of [ApiController]
Indicates that a type and all derived types are used to serve HTTP API responses.
Controllers decorated with this attribute are configured with features and behavior targeted at improving the developer experience for building APIs.
So this works without [FromBody] in ASP.NET Core 2.1 and above
[Route("api/simple")]
[ApiController]
public class SimpleController : ControllerBase
{
[HttpPost]
public IActionResult Post(OrderRequest request)
{
return Ok();
}
}

Cannot post JSON to an ASP.NET Core RazorPage handler

I'm working with an ASP.NET Core RazorPage as an alternative to an MVC controller, and I want to be able to submit the client side form via XMLHttpRequest. I've already figured out the XSRF token bits so that passes the muster, but the RazorPages framework doesn't seem to process the inbound JSON payload and bind it to the property as expected.
Some code:
The page's model (.cshtml.cs):
public class IndexModel : PageModel
{
private Database database;
private ILogger logger;
[BindProperty]
public AddRequestModel MyRequest { get; set; }
public IndexModel(Database database, ILogger<IndexModel> logger)
{
this.database = database;
this.logger = logger;
}
public void OnGet() {}
public IActionResult OnPostValidate()
{
if (ModelState.IsValid)
{
// ...
}
return new BadRequestObjectResult(ModelState);
}
public async Task<IActionResult> OnPutConfirmAsync()
{
// ...
}
}
And the client side post:
const url = "?handler=validate";
const data = { MyRequest: this.fields };
await axios.post(url, data);
I have verified the data is being submitted correctly:
That X-XSRF-TOKEN header is being added by axios before the request is submitted. The fact that the server responds with a list of errors indicates that it's not the XSRF token causing the problem:
Note the MyRequest object does not contain the values from the request payload - it was not bound as expected (FirstName would not return a required error otherwise). How can I tell RazorPages to accept the JSON request and bind it to my property?
I was able to get the Binding works by adding FromBody similar to how it worked for ASP.NET Web API 2.
[BindProperty, FromBody]
public BroadcastMessageEditingViewModel BindingInfo { get; set; }
Use urlsearchparams with formdata.
In this post you can find more information How do I post form data with fetch api?
You would be better off posting your data to an API endpoint instead of a page controller. Create a class from ControllerBase and it will handle your JSON post correctly.