{"id":10081,"date":"2021-05-03T18:25:12","date_gmt":"2021-05-03T17:25:12","guid":{"rendered":"https:\/\/staging-site.42crunch.com\/?p=10081"},"modified":"2024-09-04T15:09:27","modified_gmt":"2024-09-04T14:09:27","slug":"creating-high-quality-oas-definitions-with-net-core","status":"publish","type":"post","link":"https:\/\/staging2022.42crunch.com\/creating-high-quality-oas-definitions-with-net-core\/","title":{"rendered":"Creating High Quality OAS Definitions with .Net Core"},"content":{"rendered":"
This document highlights how code annotations can be used to enhance the quality and the security posture for customers using .<\/span>Net Core<\/b>.<\/span><\/p>\n 42Crunch security recommendations help enterprises discover and remediate vulnerabilities much more quickly (up to 25X more quickly) while saving 90% of manual costs (whether through internal efforts or external pen-testing).<\/span><\/p>\n In order to produce OAS files when developing with .NET core framework, developers can use:\u00a0<\/span><\/p>\n In this document’s example, we have an entity (Person), which will represent the JSON Schema, and a Controller (PersonController), that will expose the API’s operations for us.<\/span><\/p>\n The Swagger-UI looks pretty much like the following image:<\/span><\/p>\n <\/p>\n <\/p>\n Image 1 – Swagger UI presenting the APIs Operations and Schema<\/span><\/em><\/p>\n Based on the Open API Specification file generated by the .net framework with the support of Swashbuckle, we can get this file and add it into our IDE, just to start the process to execute de Security Audit Score, to make sure potential vulnerabilities in our API, please, refer to the following screenshot using Visual Studio Code and 42Crunch’s extension:<\/span><\/p>\n <\/p>\n <\/p>\n Image 2 – Initial Score generated by Swashbuckle<\/span><\/em><\/p>\n The 42Crunch’s extension for Visual Studio Code is presenting us with the following Audit Score: 10 of 100, in the rest of this document, we will cover how we could improve this score, essentially improving the C# code that is responsible for it.<\/span><\/p>\n Most of 42Crunch\u2019s recommendations can be fixed straight from the code to protect your API either from your preferred IDE or through the CI\/CD process. We will always look only and just only at the generated OAS\/Swagger file in order to identify if your API has potential security vulnerabilities.\u00a0<\/span><\/p>\n Note: <\/strong>Please, keep in mind that even having the best code and the whole coverage in the backends components does not necessarily mean that your API is free from potential attacks.<\/span><\/i><\/p>\n Let’s take a look first into the Person entity, which is our Schema:<\/span><\/p>\n Original Code for Entity\/JSON Schema<\/strong><\/p>\n Enhanced Code for Entity\/JSON Schema<\/strong><\/p>\n Let’s see how that slight change had impacted our new Audit Score:\u00a0<\/span><\/p>\n One of the most critical aspects is in the security that is not defined, so we will show how to add it right into the code ad the following:\u00a0<\/span><\/p>\n Now, it’s time to improve our API’s operations, in order to that, for .net, we have to take a look into the Controller component. Please, see the original PersonController:<\/span><\/p>\n Original Code for PersonController.cs<\/strong><\/p>\n Now, let’s add some annotations from annotation for improving our Audit Score, at the same time that we are also incrementing our API protection level. <\/span>We added required annotations into the Objects that will be the foundation for JSON Schema generation.<\/span><\/p>\n Some initial results:<\/p>\n <\/p>\n We could improve your API\u2019s compliance posture from 16% secure to 43% secure if we made these changes. The recommendations do not require changing the generated swagger but leveraging annotations in\u00a0 the C# Code.<\/span><\/p>\n NSwag<\/strong> has similar capabilities to Swashbuckle<\/strong>. Either one can be configured to achieve a high-quality Open API Specification\/Swagger.<\/p>\n For Pipelines and CI\/CD<\/strong><\/p>\n The REST API Security Testing pipeline lets you add our automated tests and validations to your CI\/CD pipelines to test your API at every single CI\/CD invocation. We let our customers use a wide range of tools in order to execute this practice, some of which are: Jenkins, Azure Pipelines, Bitbucket, Bamboo, and others. We can also quickly and easily make a custom integration using our API. Please, check more info here: https:\/\/42crunch.com\/free-tools\/\u00a0\u00a0<\/a><\/p>\n Once the APIs reach an acceptable Audit Score<\/strong>, which our recommendation is at least 70 (of 100), they are good to pass into the CI\/CD pipeline such as Jenkins, GitLab, Azure Pipelines, GitHub, Bamboo, etc. In addition, 42Crunch offers the capacity to integrate with many quality tools, as one of those is SonarQube:<\/p>\n <\/p>\n <\/p>\n <\/p>\n <\/p>\n The 42Crunch platform concentrates on Open API\/Swagger files, it allows our customers to have a fully integrated protection platform that understands the API behavior from its inception\/design to production. To rely on the Spec files is the way to avoid guessing on <\/span>what<\/span><\/i> and <\/span>how<\/span><\/i> to protect your APIs.\u00a0<\/span><\/p>\n For API Security Audit<\/strong> API Conformance Scan<\/strong> API Protection<\/strong> <\/p>\n References<\/strong><\/p>\n This document highlights how code annotations can be used to enhance the quality and the security posture for customers using .Net Core. 42Crunch security recommendations help enterprises discover and remediate vulnerabilities much more quickly (up to 25X more quickly) while saving 90% of manual costs (whether through internal efforts or external pen-testing). Using the Available […]<\/p>\n","protected":false},"author":12,"featured_media":11338,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"none","_seopress_titles_title":"Creating High Quality OAS Definitions with .Net Core","_seopress_titles_desc":"This document highlights how code annotations can be used to enhance the quality and the API security posture for customers using .Net Core.","_seopress_robots_index":"","site-sidebar-layout":"default","site-content-layout":"disabled","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"disabled","ast-hfb-above-header-display":"disabled","ast-hfb-below-header-display":"disabled","ast-hfb-mobile-header-display":"disabled","site-post-title":"disabled","ast-breadcrumbs-content":"disabled","ast-featured-img":"disabled","footer-sml-layout":"disabled","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[6],"tags":[16],"class_list":["post-10081","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-api-security-training"],"_links":{"self":[{"href":"https:\/\/staging2022.42crunch.com\/wp-json\/wp\/v2\/posts\/10081"}],"collection":[{"href":"https:\/\/staging2022.42crunch.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/staging2022.42crunch.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/staging2022.42crunch.com\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/staging2022.42crunch.com\/wp-json\/wp\/v2\/comments?post=10081"}],"version-history":[{"count":2,"href":"https:\/\/staging2022.42crunch.com\/wp-json\/wp\/v2\/posts\/10081\/revisions"}],"predecessor-version":[{"id":19007,"href":"https:\/\/staging2022.42crunch.com\/wp-json\/wp\/v2\/posts\/10081\/revisions\/19007"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/staging2022.42crunch.com\/wp-json\/wp\/v2\/media\/11338"}],"wp:attachment":[{"href":"https:\/\/staging2022.42crunch.com\/wp-json\/wp\/v2\/media?parent=10081"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/staging2022.42crunch.com\/wp-json\/wp\/v2\/categories?post=10081"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/staging2022.42crunch.com\/wp-json\/wp\/v2\/tags?post=10081"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}Using the Available Native Support from .Net<\/strong><\/h2>\n
\n
Using Swashbuckle<\/h4>\n
The 42Crunch IDE Support<\/h4>\n
Recommendations from 42Crunch<\/h4>\n
using System.ComponentModel.DataAnnotations;\n \nnamespace TodoApi.Models\n{\n public class Person\n {\n \n public string firstName { get; set; }\n public string lastName { get; set; }\n public long id { get; set; }\n public int age { get; set; }\n }\n}\n<\/code><\/pre>\n
using System.ComponentModel.DataAnnotations;\nusing System;\n \nnamespace TodoApi.Models\n{\n public class Person\n {\n [Required, RegularExpression("\/^[a-zA-Z ]{2,100}$\/"),MinLength(5), MaxLength(100)]\n public string firstName { get; set; }\n [Required, RegularExpression("\/^[a-zA-Z ]{2,100}$\/"),MinLength(5), MaxLength(100)]\n public string lastName { get; set; }\n [Required, Range(1, long.MaxValue)]\n public long id { get; set; }\n [Required, Range(0, 150)]\n public int age { get; set; }\n }\n}\n<\/code><\/pre>\n
\nImage 3 – Having just small changes, our audit score were considerably improved<\/span><\/em><\/p>\nprivate static void addSec(IServiceCollection services)\n {\n \n \/\/Swaggers with Security\n services.AddSwaggerGen(c =>\n {\n \/\/ configure SwaggerDoc and others\n \n c.SwaggerDoc("v1", new OpenApiInfo\n {\n Version = "v1",\n Title = "42Crunch - some best practices demo API",\n Description = "A simple example ASP.NET Core Web API",\n TermsOfService = new Uri("https:\/\/example.com\/terms"),\n Contact = new OpenApiContact\n {\n Name = "Shayne Boyer",\n Email = string.Empty,\n Url = new Uri("https:\/\/twitter.com\/spboyer"),\n },\n License = new OpenApiLicense\n {\n Name = "Use under LICX",\n Url = new Uri("https:\/\/example.com\/license"),\n }\n });\n \/\/ jwt\n \n \/\/ add JWT Authentication\n var securityScheme = new OpenApiSecurityScheme\n {\n Name = "JWT Authentication",\n Description = "Enter JWT Bearer token **_only_**",\n In = ParameterLocation.Header,\n Type = SecuritySchemeType.Http,\n Scheme = "bearer", \/\/ must be lower case\n BearerFormat = "JWT",\n Reference = new OpenApiReference\n {\n Id = JwtBearerDefaults.AuthenticationScheme,\n Type = ReferenceType.SecurityScheme\n }\n };\n c.AddSecurityDefinition(securityScheme.Reference.Id, securityScheme);\n c.AddSecurityRequirement(new OpenApiSecurityRequirement\n {\n {securityScheme, new string[] { }}\n });\n \n\n \/\/ add Basic Authentication\n var basicSecurityScheme = new OpenApiSecurityScheme\n {\n Type = SecuritySchemeType.Http,\n Scheme = "basic",\n Reference = new OpenApiReference { Id = "BasicAuth", Type = ReferenceType.SecurityScheme }\n };\n c.AddSecurityDefinition(basicSecurityScheme.Reference.Id, basicSecurityScheme);\n c.AddSecurityRequirement(new OpenApiSecurityRequirement\n {\n {basicSecurityScheme, new string[] { }}\n });\n });\n \n }\n<\/code><\/pre>\n
using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.EntityFrameworkCore;\nusing TodoApi.Models;\n \nnamespace TodoApi.Controllers\n{\n [Route("api\/[controller]")]\n [ApiController]\n public class PersonController : ControllerBase\n {\n private readonly PersonContext _context;\n \n public PersonController(PersonContext context)\n {\n _context = context;\n }\n \n \/\/ GET: api\/Person\n [HttpGet]\n public async Task<ActionResult<IEnumerable>> GetPersons()\n {\n return await _context.Persons.ToListAsync();\n }\n \n \/\/ GET: api\/Person\/5\n [HttpGet("{id}")]\n public async Task<ActionResult> GetPerson(long id)\n {\n var person = await _context.Persons.FindAsync(id);\n \n if (person == null)\n {\n return NotFound();\n }\n \n return person;\n }\n \n \/\/ PUT: api\/Person\/5\n \/\/ To protect from overposting attacks, enable the specific properties you want to bind to, for\n \/\/ more details, see https:\/\/go.microsoft.com\/fwlink\/?linkid=2123754.\n [HttpPut("{id}")]\n public async Task PutPerson(long id, Person person)\n {\n if (id != person.id)\n {\n return BadRequest();\n }\n \n _context.Entry(person).State = EntityState.Modified;\n \n try\n {\n await _context.SaveChangesAsync();\n }\n catch (DbUpdateConcurrencyException)\n {\n if (!PersonExists(id))\n {\n return NotFound();\n }\n else\n {\n throw;\n }\n }\n \n return NoContent();\n }\n \n \/\/ POST: api\/Person\n \/\/ To protect from overposting attacks, enable the specific properties you want to bind to, for\n \/\/ more details, see https:\/\/go.microsoft.com\/fwlink\/?linkid=2123754.\n [HttpPost]\n public async Task<ActionResult> PostPerson(Person person)\n {\n _context.Persons.Add(person);\n await _context.SaveChangesAsync();\n \n return CreatedAtAction("GetPerson", new { id = person.id }, person);\n }\n \n \/\/ DELETE: api\/Person\/5\n [HttpDelete("{id}")]\n public async Task<ActionResult> DeletePerson(long id)\n {\n var person = await _context.Persons.FindAsync(id);\n if (person == null)\n {\n return NotFound();\n }\n \n _context.Persons.Remove(person);\n await _context.SaveChangesAsync();\n \n return person;\n }\n \n private bool PersonExists(long id)\n {\n return _context.Persons.Any(e => e.id == id);\n }\n }\n}\n<\/code><\/pre>\n
\n\/\/\/\n\/\/\/ Creates a TodoItem.\n\/\/\/ <\/code><\/pre>\n
\n\/\/\/ \/\/\/ Sample request: \/\/\/ \/\/\/ POST \/Todo \/\/\/ { \/\/\/ "id": 1, \/\/\/ "name": "Item1", \/\/\/ "isComplete": true \/\/\/ } \/\/\/ \/\/\/ \/\/\/ \/\/\/ A newly created TodoItem \/\/\/ Returns the newly created item \/\/\/ If the item is null \/\/\/ Forbidden \/\/\/ Forbidden \/\/\/ Too many responses [HttpPost] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status429TooManyRequests)] public async Task<ActionResult> PostTodoItem(TodoItem todoItem) { _context.TodoItems.Add(todoItem); await _context.SaveChangesAsync(); return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem); }\n<\/code><\/pre>\n
Using NSwag<\/h4>\n
Conclusion<\/h2>\n
\n<\/span>42Crunch executes 200+ security checks against the API contract, provides detailed security scoring for prioritization, and remediation advice to help developers define the best contract possible. Reaching great results in that phase obtaining high-quality <\/span>Open API\/Swagger<\/b> files, we can move to the next component in the platform: Conformance Scanning.\u00a0<\/span><\/p>\n
\n<\/span>42Crunch Conformance Scan is a dynamic runtime testing of your API to ensure that the implementation behind your API matches the <\/span>contract<\/b> set out in the OpenAPI \/ Swagger definition of the API.<\/span><\/p>\n
\n<\/span>42Crunch Platform moves the defense from the network perimeter to in-depth directly in front of your APIs. With API Protection, you can protect each API from malicious intents with a micro-API firewall.\u00a0<\/span><\/p>\n\n
\n<\/span><\/li>\n
\n<\/span><\/li>\n