Skip to main content
Review and revision metadata
Review Date: 2026-06-16
Reviewer: Operations Manager

previous version on gdrive

Secure Coding Checklist

Condensed Secure Development Checklistst

Applies To: .NET Core (C#), React(TypeScript), PowerShell/Bash, Azure ARM/Bicep

Compliance: NIS 2, NIST, ISO 27001:2023, OWASP Top 10 Principles

Core Secure Coding Principles

  • [ ] Input Validation & Sanitization (Server-Side): Validate all input (type, length, format, range). Use allow-lists. Sanitize for context (DB, HTML, OS, LDAP). Specifically validate URLs/hosts (SSRF).
  • [ ] Output Encoding: Encode data correctly for its destination (HTML, JSX, etc.) to prevent injection (XSS, LDAP Injection). Use framework features.
  • [ ] Authentication (Server-Side): Use standard protocols (Azure AD/Entra ID, OIDC/SAML). Securely hash/store passwords. Implement MFA. Secure session management (timeouts, secure flags/storage) (Broken Authentication).
  • [ ] Authorization (Server-Side): Enforce checks on every request. Use Least Privilege & RBAC. Prevent IDOR (Broken Access Control).
  • [ ] Cryptography: Use strong, standard algorithms (AES, SHA-256+). Never roll your own crypto. Use Azure Key Vault for keys/secrets. Enforce TLS 1.2+ for transit. Encrypt sensitive data at rest (Cryptographic Failures, Sensitive Data Exposure).
  • [ ] Dependency Management: Use SCA tools (Dependabot, etc.) to scan for vulnerable dependencies (NuGet, npm). Keep libraries updated.
  • [ ] Secure Configuration: Use secure defaults. Externalize config. Protect secrets (Azure Key Vault). Set security headers (CSP, HSTS, etc.).
  • [ ] Error Handling & Logging: Log security-relevant events. Do not log sensitive data. Show generic errors to users; log details server-side (Azure Monitor) (Sensitive Data Exposure).

Technology & Environment Specifics

  • [ ] .NET Core: Use parameterized queries/EF Core (prevent SQLi). Securely configure XML parsers (XXE). Validate input to Process.Start or OS commands (OS Injection).
  • [ ] React + Typescript: Leverage React build-in XSS protection (automatic JSX escaping) . Do not store sensitive info in localStorage. Rely on server-side validation/auth/authz.
  • [ ] PowerShell / Bash: Validate/sanitize inputs used in commands (OS Injection). Use secure methods for secrets (Key Vault, environment variables).
  • [ ] Azure ARM / Bicep: Parameterize templates. Use Azure Key Vault references for secrets. Define RBAC with Least Privilege. Use Managed Identities. Secure networking (NSGs, Private Endpoints). Enable Azure security features & logging.

Process & Verification

  • [ ] Secure Code Review: Participate in/request security-focused code reviews.
  • [ ] Automated Testing: Ensure code passes SAST & SCA scans in CI/CD pipeline.

Detailed Secure Development Checklist

Purpose: To ensure features developed using .NET Core, React (Typescript), PowerShell/Bash, and Azure IaC (ARM/Bicep) adhere to organizational security policies and best practices aligned with NIS 2, NIST, ISO 27001:2023, and OWASP Top 10.

Scope: Covers the development lifecycle from coding through IaC definition. Assumes supporting organizational processes (threat modeling, vulnerability management program, incident response plan) exist.

Phase 1: Secure Coding Principles (Applicable Across Technologies)**

  • [ ] Input Validation & Sanitization:

    • [ ] Validate all input (user-supplied, APIs, files, environment variables, database queries) for type, length, format, and range.
    • [ ] Use allow-lists (whitelisting) for validation whenever possible, reject known bad (blacklisting) as a secondary defense.
    • [ ] Sanitize data appropriately based on the context where it will be used (e.g., HTML encoding for web display, parameterization for DB queries, escaping for OS commands).
    • [ ] Specifically validate URLs and hostnames received as input to prevent Server-Side Request Forgery (SSRF). Ensure requests are only made to expected, trusted destinations.
    • [ ] Treat data from internal systems or APIs with the same scrutiny as external user input.
  • [ ] Output Encoding:

    • [ ] Encode data correctly for the context where it is rendered (HTML, JSX, CSS, XML, LDAP DNs) to prevent injection attacks (XSS, LDAP Injection).
    • [ ] Use framework-provided, context-aware auto-escaping features where available and verify their effectiveness.
  • [ ] Authentication & Session Management (Addresses: Broken Authentication):

    • [ ] Implement authentication logic server-side (.NET Core).
    • [ ] Use standard, secure, and well-vetted authentication mechanisms (e.g., OpenID Connect, SAML 2.0 via Azure AD B2C/Entra ID).
    • [ ] Implement Multi-Factor Authentication (MFA) where required/appropriate.
    • [ ] Protect session identifiers (e.g., use HttpOnly, Secure flags on cookies; secure storage for tokens).
    • [ ] Implement proper session timeout (inactivity and absolute) and secure logout (invalidate session server-side).
  • [ ] Access Control (Addresses: Broken Access Control):

    • [ ] Enforce authorization checks server-side (.NET Core) for every request requiring access to protected resources or functions. Do not rely on client-side checks for security enforcement.
    • [ ] Implement the principle of Least Privilege: Users/processes should only have the minimum permissions necessary.
    • [ ] Use Role-Based Access Control (RBAC) or Attribute-Based Access Control (ABAC) mechanisms consistently.
    • [ ] Verify access rights on each request, not just at login.
    • [ ] Prevent Insecure Direct Object References (IDOR) by using indirect references mapped to the user or checking ownership/permissions for every accessed object.
    • [ ] Ensure administrative functions have distinct, robust access controls.
    • [ ] Deny by default: Access should only be granted explicitly.
  • [ ] Cryptographic Practices (Addresses: Cryptographic Failures, Sensitive Data Exposure):

    • [ ] Use strong, industry-standard cryptographic algorithms and libraries (e.g., AES-256 for symmetric encryption, RSA-3072+/ECC for asymmetric, SHA-256+ for hashing). Avoid deprecated/weak algorithms (MD5, SHA1, DES).
    • [ ] Do not attempt to create custom cryptographic algorithms or protocols.
    • [ ] Manage cryptographic keys securely (e.g., use Azure Key Vault). Do not hardcode keys in source code, configuration files, or IaC templates.
    • [ ] Use Azure Managed Identities to access Key Vault where possible.
    • [ ] Protect data in transit using TLS 1.2+ with strong cipher suites. Configure applications and infrastructure to enforce this.
    • [ ] Encrypt sensitive data at rest (e.g., using Azure Storage encryption, Azure SQL TDE, application-level encryption where necessary).
    • [ ] Understand what constitutes sensitive data (PII, credentials, financial info, business secrets) and apply protections accordingly.
  • [ ] Security Configuration:

    • [ ] Use secure defaults for all configurations.
    • [ ] Remove or disable unused features, components, ports, and services.
    • [ ] Externalize configuration from code (e.g., appsettings.json, environment variables, Azure App Configuration).
    • [ ] Prevent committing configuration files (e.g. appsettings.json with sample or actual values.
    • [ ] Protect configuration files containing sensitive information (e.g., connection strings) using mechanisms like Azure Key Vault references or appropriate file system permissions.
    • [ ] Ensure security headers are set correctly in web applications (e.g., Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, Referrer-Policy).
  • [ ] Error Handling & Logging:

    • [ ] Implement detailed logging for security events (auth success/failure, access control failures, input validation failures, server errors, admin actions).
    • [ ] Ensure logs do not contain sensitive data (passwords, keys, tokens, PII) unless specifically required and secured (Addresses: Sensitive Data Exposure). Use masking/redaction if necessary.
    • [ ] Configure logging to integrate with central monitoring systems (e.g., Azure Monitor / Log Analytics).
    • [ ] Handle errors gracefully. Do not reveal excessive technical details (stack traces, database errors) to end-users (Addresses: Sensitive Data Exposure). Provide generic error messages and log detailed information server-side.
  • [ ] Dependency Management (Supply Chain Security - NIS 2 / A.05.21 - Managing information security in the information and communication technology (ICT) supply chain):

    • [ ] Use a Software Composition Analysis (SCA) tool (e.g., GitHub Dependabot, SonarQube Cloudto scan dependencies (.NET NuGet, JS npm/yarn) for known vulnerabilities.
    • [ ] Keep dependencies updated to patched versions.
    • [ ] Understand the licenses of dependencies.
    • [ ] Use packages only from trusted, official repositories. Verify package integrity, if possible.
    • [ ] Remove unused dependencies.

Phase 2: Technology-Specific Checks

  • .NET Core (C#) Specific:

    • Startup Layer - Configuration, Dependency Injection, Middleware

      • [ ] Avoid hardcoding secrets. Use Azure Key Vault with managed identity integration
      • [ ] Register services with only required scopes / permissions
      • [ ] Enforce HTTPS redirection, HSTS and set secure headers. Enable and Use an allow-list for Cross Origin Resource Sharing
      • [ ] Ensure Authentication and Authorization middlewares are executed before custom middlewares
      • [ ] Ensure environment is set and decided by app configuration and not hard-coded
      • [ ] Ensure HttpClientFactory is initialized if required for external calls and the same does not have a Certificate validation bypassed
      • [ ] Ensure Telemetry has been configured
    • API / Function - Controllers, HTTP Endpoints

      • [ ] Ensure controller, function or every API endpoint has [Authorize] attribute set with specific Authorization policies
      • [ ] Use model validation attributes on DTOs; avoid overposting attacks by binding only specific properties
      • [ ] Ensure any MS Graph API invocations OR Azure Management Service invocations are performed using On-Behalf-Of (OBO) flow (unless the initiator is a background service or the intended action requires otherwise)
      • [ ] Ensure Try-Catch is in place to catch known exceptions and return relevant response status codes without exposing any system / code specific information / stack trace
    • Business / Services Layer

      • [ ] Use parameterized queries or ORMs (like Entity Framework Core) correctly to prevent SQL injection. Avoid dynamic query concatenation.
      • [ ] Use Entity Framework for Database interaction as much as possible
      • [ ] Ensure dependent calls to other apps or external entities are invoked via HttpClientFactory and have an exponential back-off retry mechanism in place for the same
      • [ ] Ensure Business critical events are logged without exposing any PII
      • [ ] Ensure logging is done to the appropriate store i.e. any events relevant to the customer’s business should be logged within the customer’s Log Analytics Workspace. Ensure sensitive data is not logged.
    • Miscellaneous

      • [ ] When adding dependent libraries / packages, ensure that the packages are MIT Licensed or issued by Microsoft. Ensure the latest package which does not have any vulnerabilities is referred.
      • [ ] Use built-in framework features for security (e.g., Anti-Forgery Tokens for CSRF, Identity framework for auth, Data Protection API for encryption).
      • [ ] Be cautious with Process.Start or similar functions that execute external commands (Addresses: OS Injection). Validate and sanitize any user-controlled input used in commands. Use APIs designed for specific tasks where possible instead of shelling out.
      • [ ] If interacting with LDAP, use libraries that properly handle escaping of special characters in DNs and filters (Addresses: LDAP Injection).
      • [ ] When processing XML, disable external entity resolution and DTD processing by default to prevent XML External Entities (XXE) attacks. Use secure XML parser configurations.
      • [ ] Implement proper resource management (using statements for IDisposable) to prevent resource leaks.
      • [ ] Ensure all cryptographic operations use industry-standard algorithms, protocols, and libraries, with secure key management practices and regular updates to mitigate emerging threats.
    • React (TypeScript) Specific:

      • [ ] Use React’s default JSX escaping to preventCross-Site Scripting (XSS) (e.g., React's default JSX encoding. Avoid dangerouslySetInnerHTML / [innerHTML] unless absolutely necessary and the input is properly sanitized. If absolutely required, sanitize input with trusted libraries like DOMPurify. Implement CSP headers to further mitigate XSS risks.
      • [ ] Do not store sensitive data (e.g., access tokens, secrets) in localStorage due to XSS risks. Prefer sessionStorage only for ephemeral, non-critical data. For authentication, use secure, HttpOnly, SameSite, and Secure cookies set and managed by the backend..
      • [ ] Implement client-side validation as a usability feature, but always rely on server-side validation for security.
      • [ ] Do not expose secrets in frontend code. If a key must be used client-side (e.g., for public APIs), ensure it's restricted by origin or rate-limited. Prefer using a BFF (Backend-for-Frontend) or token vending approach to securely access protected services. .
      • [ ] Protect against Cross-Site Request Forgery (CSRF) using standard patterns (e.g., Anti-Forgery Tokens checked server-side). Also configure cookies with SameSite=Lax/Strict and Secure flags to mitigate CSRF risks
      • [ ] Keep React, Redux Toolkit, Chakra UI, and dependencies updated. Use tools like npm audit, Snyk, or GitHub Dependabot to detect and remediate vulnerabilities. Pin dependency versions and review changelogs before major upgrades.
      • [ ] Implement and enforce a strict CSP to prevent XSS by controlling which scripts are allowed to execute.
      • [ ] Ensure the app serves key headers: X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Strict-Transport-Security.
      • [ ] Do not expose internal error messages, stack traces, or debugging tools in production builds.
      • [ ] Minify and obfuscate code in production. Disable source maps unless absolutely required for diagnostics (and never serve them publicly).
  • PowerShell / Bash Specific:

    • [ ] Validate and sanitize any parameters or inputs used in commands, especially if they originate from external sources. Avoid Invoke-Expression in PowerShell and eval in Bash as they can lead to OS command injection. (Addresses: OS Injection).
    • [ ] Prefer dedicated cmdlets (e.g., Start-Process, Test-Path) over dynamically building and executing command stringsif possible.
    • [ ] Avoid running scripts with elevated privileges unless absolutely necessary. Apply least privilege to script execution context.
    • [ ] Handle secrets securely. Use environment variables, secure parameter inputs, or credential management systems (like Azure Key Vault secrets via Azure PowerShell/CLI) instead of hardcoding credentials.
    • [ ] Be cautious with file operations (path traversal). Always validate file paths using Resolve-Path, Test-Path, or regex validation to prevent path traversal. .
    • [ ] Enable sufficient logging within scripts for auditing and troubleshooting.
    • [ ] Sign PowerShell scripts where appropriate/required by policy. Set appropriate execution policies.
    • [ ] Be cautious with downloading scripts or files from the internet. Verify source integrity (e.g., checksums, digital signatures).
    • [ ] Do not assume defaults are secure. Explicitly define parameters like encoding (e.g., -Encoding UTF8) and access controls for files.
    • [ ] Secure your automation pipelines. Avoid passing secrets in plain text, ensure scripts in pipelines are reviewed, signed, and version-controlled.
    • [ ] In Bash scripts, avoid unsanitized use of environment variables and ensure they are not executed unintentionally. Patch systems against known vulnerabilities like Shellshock.
  • Azure ARM / Bicep Specific (Infrastructure as Code):

    • [ ] Parameterize templates. Avoid hardcoding values, especially sensitive ones (use Key Vault references).
    • [ ] Use Azure Key Vault to store secrets, certificates, and keys referenced in templates.
    • [ ] Apply the principle of Least Privilege when defining Azure RBAC roles for deployed resources and for the identity deploying the template (Managed Identity, Service Principal). Use built-in roles where possible; create custom roles with minimal permissions if needed.
    • [ ] Use Managed Identities for Azure resources to authenticate to other Azure services (Key Vault, Storage, SQL DB) instead of storing credentials.
    • [ ] Configure Network Security Groups (NSGs) or Azure Firewall rules to allow only necessary traffic to/from resources. Deny all by default.
    • [ ] Disable public access to resources (Storage Accounts, SQL DB, App Service) where not explicitly required. Use Private Endpoints or Service Endpoints. Avoid * rules in firewall or SAS token configurations.
    • [ ] Enable diagnostic settings/logging for Azure resources (e.g., Azure Activity Log, resource-specific diagnostics) sending data to Azure Monitor / Log Analytics.
    • [ ] Enable security features on Azure services (e.g., Microsoft Defender for Cloud recommendations, SQL Auditing, Storage access tiers/immutability, App Service HTTPS Only).
    • [ ] Use template validation and linting tools (e.g., az deployment validate, bicep build --stdout | arm-ttk, bicep lint).
    • [ ] Store IaC code in version control (Git) and apply review processes.
    • [ ] Use tools like What-If (az deployment what-if) to detect drift from a declared state.
    • [ ] Break large templates into modules and reuse components (e.g., networking, identity) for consistency and manageability.
    • [ ] Enforce resource tagging via policy (e.g., Environment, Owner, CostCenter) for visibility, governance, and cost tracking.
    • [ ] Use Azure Policy definitions to enforce organizational standards (e.g., deny public IPs, require diagnostics, enforce allowed SKUs).

Phase 3: Process Integration & Verification

  • [ ] Code Reviews: Participate in peer code reviews with focus on aspects outlined in this checklist.
  • [ ] Security Testing:
  • [ ] Ensure code passes Static Application Security Testing (SAST) scans integrated into the CI pipeline. Remediate findings.
  • [ ] Ensure internal Security Impact Analysis (SIA) is performed on applicationwhere applicable.
  • [ ] Remediate vulnerabilities identified bythe above scans.
  • [ ] Documentation: Document relevant decisions, configurations, and data handling practices.
  • [ ] Threat Modeling Awareness: Understand the threat model for the feature/application being developed.
  • [ ] Incident Response Awareness: Know how to report a suspected security incident according to the organization's Incident Response Plan.
  • [ ] Continuous Learning: Stay updated on new vulnerabilities, threats, and secure coding practices relevant to the technology stack.
  • [ ] Regular Updates: Ensure dependencies are checked periodically for vulnerabilities and required upgrades.

OWASP Top 10 Vulnerability Mapping (Checklist Coverage)

  • Server-Side Request Forgery (SSRF): Covered under "Input Validation & Sanitization" (URL validation).
  • OS Injection: Covered under ".NET Core Specific" (Process.Start caution), "PowerShell / Bash Specific" (command input validation).
  • LDAP Injection: Covered under "Output Encoding" (LDAP DNs), ".NET Core Specific" (LDAP library usage).
  • Broken Authentication: Covered extensively under "Authentication & Session Management".
  • Sensitive Data Exposure: Covered under "Cryptographic Practices", "Error Handling & Logging", ".NET Core Specific" (secure credential storage), "JavaScript Specific" (client-side storage), "Azure ARM/Bicep Specific" (Key Vault usage).
  • XML External Entities (XXE): Covered under ".NET Core Specific" (secure XML parser config).
  • Broken Access Control: Covered extensively under "Access Control".
  • Cryptographic Failures: Covered extensively under "Cryptographic Practices".

Open Source Packages

When referencing or adding new open-source packages, developers must ensure**:**

  1. License Compliance Only use libraries with licenses approved by the Open Source Initiative (OSI). Commonly accepted licenses include (but are not limited to):

    • MIT License
    • Apache License 2.0
    • BSD 2-Clause / 3-Clause
    • GPL and LGPL (any version)*
    • Mozilla Public License 2.0
    • Eclipse Public License 2.0
    • Common Development and Distribution License (CDDL)
    • ISC License
    • Python License, Version 2
  2. Security Verification

    • Perform vulnerability scans with tools like GitHub Dependabot, Snyk, or OWASP Dependency-Check after using any package.
    • Ensure the package is actively maintained and has a history of prompt security updates.
    • Avoid packages with critical or unpatched CVEs.
  3. Source Validation

    • Refer packages from official repositories only (e.g., NuGet, npm, PyPI).
    • Validate package authorship and download counts when choosing lesser-known libraries.
  4. Minimal Use Principle

    • Only include open-source packages that are strictly necessary for your application's functionality.
    • Regularly review and remove unused dependencies.

Integration of the guidelines into way-of-working

To ensure the secure coding guidelines are consistently applied and verified, the Developer Secure Coding & Deployment Checklist has been integrated directly into the peer review process for Pull Requests (PRs). This systematic approach mandates a security review for every code change, promoting a "security by design" culture.

Steps Taken:

  1. Default PR Template Creation: A default Pull Request template has been configured in GitHub repositories. This template automatically populates the PR description with the "Condensed Secure Development Checklist" whenever a new PR is created.

  2. Developer Checklist Population: Developers are required to review each item in the checklist within the PR description.

    • For applicable items, developers must mark the corresponding checkbox as checked (e.g., `[x]`).
    • For items not applicable to the specific code change, developers must explicitly mark them as not-applicable (e.g., `[NA]`). This ensures conscious consideration of each item.
  3. "Validate Secure Coding Checklist" GitHub Action: A GitHub Action named "Validate Secure Coding Checklist" has been implemented and configured to run automatically on every PR creation and update.

    • This action parses the PR description to identify the status of each item in the secure coding checklist.
    • It verifies that every checklist item is either checked (`[x]`) or explicitly marked as not-applicable (`[NA]`).
  4. PR Merge Blocking/Enabling: The "Validate Secure Coding Checklist" GitHub Action is set as a required status check for merging PRs.

    • Blocking: If the action detects that one or more checklist items are neither checked nor marked as not-applicable, the PR merge will be blocked. This provides immediate feedback to the developer and prevents merging insecure code.
    • Enabling: Once all checklist items are appropriately addressed (checked or marked `[NA]`), the GitHub Action will pass, and the PR merge functionality will be enabled.

This process ensures that every Pull Request undergoes a mandatory secure coding checklist validation, significantly enhancing the security posture of the codebase.