Start with Security, End with Confidence

1 Share

How McDonald’s is transforming application security from a reactive blocker into a proactive enabler — without slowing developers down.

by: Samantha De Mont, Senior Manager Application Security

Quick Bytes:

  • Security used to be seen as a blocker — reactive, siloed, and often an afterthought in development
  • Embedding security champions and layered tools empowers developers to build secure code from the start
  • Security is now a proactive partner, enabling faster releases and a stronger, security-first culture at McDonald’s

When people think of application security, most picture the “bad cop” team; dropping vulnerability reports into developers’ inboxes, slowing releases, and generally makes life harder. At least, that’s the perception.

The reality? Security isn’t the villain — it’s the enabler. When integrated early, it empowers developers to build confidently and securely. But understanding it requires a peek behind the curtain. At McDonald’s, security has evolved significantly, shifting toward a collaborative approach to working with developers, not against them — navigating the nuances to build secure-by-design applications.

From outsourcing to embedding security
In the past, much of our code was developed externally, and performing third-party Application Security Testing was a standard part of that process. When reports landed internally, they were passed from person to person, making it difficult to drive timely fixes because security was still seen as someone else’s job. This decentralized approach sometimes reinforced a perception that security was an afterthought.

Today, we’ve embedded security throughout the product development lifecycle — with the Application Security Champions Program at its core. This program meets developers where they are and empowers them to write secure code at speed.

Lunch and learn session with Global Tech Application Security Champions

Shifting left without shifting blame
Early integration into the development cycle revealed a key challenge: developers often didn’t have the resources or guidance at their fingertips to confidently address security issues.

Add to that McDonald’s complex organizational matrix — where multiple teams and systems influence how applications are designed and deployed — and even a small remediation effort became anything but simple.

To better understand the challenges developers faced, the Application Security team invited developers to share their pain points. They highlighted silos, limited access to security upskilling resources, and a lack of guidance. One key takeaway emerged: our solution should empower developers, not assign blame.

Application Security’s approach to shifting left

Developer-focused, full-coverage security
It became clear that developers needed solutions built for the realities of the McDonald’s organizational matrix.

Modern applications are too intricate for a single tool to catch every vulnerability. So, we built a layered, developer-focused approach to protect code from multiple angles.

Think of it like visiting a doctor. When you have a health concern, doctors rarely rely on a single test. Instead, different specialists run various exams, each providing unique insight into your overall health. One test might reveal something unexpected, and fixing one issue can often improve other areas of your system.

Application security works the same way. Different tools target different layers — code-level flaws, runtime vulnerabilities, insecure dependencies, and misconfigured infrastructure — giving developers a complete view of an application’s “health” and helping them build securely from the inside out.

Application Security Life Cycle — Secure by Design with Ongoing Protection

But coverage alone isn’t enough. Beyond layered checks, our tools work alongside developers providing:

  • Integrated development environment (IDE) assistance: Vulnerabilities are detected as code is written in an IDE, with real-time recommendations on how to fix them.
  • Auto-fixing of pull requests: Simple misconfigurations can be automatically resolved, reducing manual effort of developers.
  • Seamless continuous integration/continuous delivery (CI/CD): Automated security checks are conducted allowing developers to push code confidently and without delays.
  • Hands-on security training: Gamified, practical exercises that mirror developers’ day-to-day environments, helping them upskill in secure development and deployment best practices.

By combining layered coverage with these developer-focused enhancements, security becomes practical and proactive — addressing issues without passing the blame or leaving developers to figure everything out on their own.

Security reframed
At the end of the day, security works best as a partner. No one wants to push insecure code or explain to leadership how a breach could have been prevented.

By building a security-first culture at McDonald’s, we aim to adapt to the evolving tech landscape and establish a new normal where secure practices are embedded from the start.

Start with security, end with confidence.


Start with Security, End with Confidence was originally published in McDonald’s Technical Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.

Read the whole story
alvinashcraft
14 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Top Agentic AI Tools for VS Code, According to Installs

1 Share
A roundup of the six most-installed "agentic" AI extensions in the VS Code Marketplace reveals how tools like Cline, BLACKBOXAI Agent, Continue, Codex, Roo Code, and Qodo Gen are transforming code editors into autonomous, context-aware development partners.
Read the whole story
alvinashcraft
15 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Developer and AI Code Reviewer: Reviewing AI-Generated Code in .NET

1 Share

Enhancing the role of the developer with the responsibility of reviewing AI-generated code is a transformative step for developers. You become a critical gatekeeper for the quality, reliability, and maintainability of code produced by advanced AI tools like GitHub Copilot. While the volume of code reviews may increase, so does the opportunity to raise the bar for your team’s output. This post explores how reviewing AI-generated code can make you more productive and effective and provides practical tips for navigating common review challenges.

How Reviewing AI-Generated Code Boosts Productivity

Data from recent development teams shows that integrating AI code generation can increase feature delivery speed by 20–40%. However, this gain is only sustainable if code reviewers ensure the produced code meets the highest standards. By adopting consistent review practices, developers spend less time debugging and refactoring later, resulting in a net productivity gain even with the extra reviews required. Moreover, reviewers report a deeper understanding of the codebase and technologies as they regularly encounter new patterns and solutions presented by AI.

Key Areas for Reviewing AI-Generated Code

When faced with code from AI assistants, code reviewers should pay special attention to the following areas:

1. API Design & Interface Architecture

Interface Abstraction: AI often introduces unnecessary abstraction layers; scrutinize interfaces for simplicity and directness.

@copilot TokenCredential is already abstract, we don't need an interface for it.

Method Naming: Naming conventions can be inconsistent (e.g., WithHostPort vs WithBrowserPort); ensure adherence to project standards.

Public vs Internal APIs: AI may expose more methods as public than needed—be deliberate about API surface.

Extension Method Patterns: Confirm builder extensions follow established conventions.

2. Testing & Testability

Unit Test Coverage: AI-generated methods may lack comprehensive tests for new public methods—insist on full coverage.

@copilot add unit tests for GetOrCreateResourceAsync

Test Organization: Prefer snapshot testing (e.g., Verify) over generic assertions, which are common in AI-generated tests.

Concrete Assertions: Review for tests that assert specific values, not just general outcomes.

Preserve Existing Tests: Guard against unnecessary changes to existing tests when integrating new code.

3. File Organization & Architecture

Auto-generated Files: AI may inadvertently modify auto-generated API surface files (/api/.cs)—review for accidental changes.

Layer Separation: Confirm code is placed within the correct architectural context (Infrastructure vs Publishing).

Namespace Organization: Check that new classes and interfaces are organized in the appropriate assemblies.

@copilot Move the tests for BicepUtilities to a BicepUtilitiesTest class

4. Error Handling & Edge Cases

Null Checking: Validate that null-checking patterns are applied consistently.

@copilot This should never be null.

Exception Handling: Ensure the use of proper exception types and handling strategies; AI might use generic exceptions.

Edge Case Coverage: Be thorough in considering error scenarios and defensive programming, especially as AI may overlook rare cases.

5. Configuration & Resource Management

Resource Lifecycle: Inspect resource creation, configuration, and cleanup, as AI code may neglect disposal patterns.

@copilot We should see if the DockerComposeEnvironmentResource already has a dashboard resource and this should noop if it does.

Configuration Patterns: Confirm adherence to established callbacks and resource configuration approaches.

Environment-Specific Logic: Ensure correct behavior in different contexts (e.g., publish vs run modes).

6. Code Quality & Standards

Documentation: AI-generated code often lacks comprehensive XML documentation for public APIs.

Code Style: Watch for formatting and style inconsistencies that AI can introduce.

Performance Considerations: Critically assess the performance implications of AI-generated designs.

Key Insights for Reviewing AI-Generated Pull Requests

  • Iterative Refinement: Expect Copilot PRs to go through more rounds of feedback and incremental edits than human-authored code.
  • Architectural Guidance: Provide strong architectural support to ensure new features mesh with existing patterns and conventions.
  • Standards Enforcement: Maintain rigorous standards, as AI often defaults to generic practices unless explicitly guided.
  • Quality Focus: Devote attention to maintainability and test coverage; AI may solve the immediate task but miss long-term concerns.
  • Incremental Changes: Encourage smaller, focused pull requests to simplify review and integration.

Conclusion: Elevate Your Impact as an AI Code Reviewer

Embracing the role of reviewing AI-generated code allows you to steer your team’s adoption of new technologies toward success. By applying deliberate review strategies, enforcing standards, and guiding iterative refinement, you ensure that the promise of AI productivity is realized without compromising quality. Step up as a reviewer, help make every AI-generated contribution robust and maintainable, and lead the way for excellence in .NET development.

The post Developer and AI Code Reviewer: Reviewing AI-Generated Code in .NET appeared first on .NET Blog.

Read the whole story
alvinashcraft
15 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Natural consequences

1 Share

We all make mistakes, all the time, every day. Often there aren’t any consequences, or the impact is so minor that we don’t even notice. Perhaps not noticing mistakes is good for our self-confidence and well-being, but it’s also a lost opportunity to learn.

Losing growth opportunities is particularly regrettable when the mistake could have been costly. Getting lucky is nice, but luck runs out. It’s far better to learn when the cost is low rather than pay dearly later.

When you are in a position to mentor or lead, it’s your responsibility to point out mistakes, help people improve, hold them accountable, and avoid future catastrophes. However, if your response to the mistake is too harsh, it could seem unfair and disproportionate, causing the recipient to push back. If your response is too gentle, it could seem superfluous, causing the recipient to ignore it.

What response gets people’s attention, ensures they understand the significance of their mistake, and helps them to avoid that mistake going forward? If you stop reading, you’ll never know.

Eric Aside

For more about dealing with mistakes, read I messed up and Crisis management. For more about setting expectations, read I expect you to read this. For more on fair responses, read Fairness rules.

Sliding doors

When someone makes a mistake, particularly one that might have been harmful or costly, it’s critical to take steps to avoid that mistake in the future. However, if the harm was quietly rectified or luckily the impact was minimal this time, there’s a good chance that they won’t recognize the issue or feel motivated to correct it. That’s when a leader or mentor needs to point out what went wrong, describe the consequences, and ensure it doesn’t happen again.

The leader or mentor might berate the person who made the mistake, embarrass them in front of their peers, or punish them in some way. Fear and intimidation can be effective, but they curtail growth and innovation because people become afraid to take risks.

Instead, the leader or mentor can invoke natural consequences. If the mistake had caused harm or been costly, what natural consequences would have occurred? Not the worst possible outcome—simply outcomes that would naturally follow had the person not been so lucky. Those natural consequences will seem reasonable and proportionate to the error, not too harsh or too gentle. They will make the harm and costs clear, make the person realize how lucky they were, and motivate them to avoid future related mishaps.

When the leader or mentor invokes natural consequences, the person must address them as if they had occurred. The person sees what can go wrong, learns how best to deal with it, and feels sufficient pain and accountability to avoid the mistake going forward, all without the actual external harm or cost. Since each situation has its own natural consequences, there’s no magic recipe. Instead, let’s go through a few examples.

Eric Aside

Natural consequences are also useful in parenting. For example, say your child whines and cries when they don’t get what they want. You could give them what they want, but that only encourages more whining and crying. You could smack them or yell at them, but that’s awful. Instead, you could focus on a natural consequence of their whining and crying: You can’t easily understand them. Say, “I’m sorry, I can’t understand you. Take a couple of slow breaths and calm down. Talk quietly and clearly so I can understand you.” As a result, your child will learn to calm themself and express their needs in words. Those are wonderful skills, and they reduce the whining.

For more about the pitfalls of fear and intimidation, read What’s my motivation? and Is it safe?

AI made me do it

Say an engineer on your team takes shortcuts with their assignments. Perhaps they use AI to write their code without carefully checking the results. Maybe they don’t adequately test their work or ensure it’s secure, accessible, and world-ready. These issues might be caught during code review, pull request (PR) validation, or production testing, but the engineer should be submitting quality code from the start.

The natural consequences of submitting poor, unchecked, or incomplete code are harm to customers and bugs that must be fixed. If you are the leader or mentor of this engineer, you can invoke these natural consequences. After noticing the engineer’s shortcuts, tell them that their PR won’t be approved until they successfully predict at least half of the errors found during code review and PR validation before their PR is submitted. Each time they fail, they fix the issues found, re-predict, and resubmit. (You could raise the bar to as much as 80% predicted, depending on their capability.) Discuss the impact these errors would have on customers and insist that all errors be resolved before PR approval. As a result, the engineer will discover how to find coding errors before they submit PRs, learn to fix the issues they find in advance, and better appreciate the negative impact of taking shortcuts.

Eric Aside

For more about writing quality code, read Nailing the nominals and A software odyssey—From craft to engineering. For more on security, accessibility, and world readiness, read Are you secure about your security?, Better for everyone, and Stupid in any language.

This is fine

Say an engineer on your team hides problems. Maybe work items are running late. Maybe there are problems with partners or coworkers. Maybe there are security or reliability issues. The engineer wants to avoid conflict, so they try to fix problems quietly or hope they go away before anyone notices. Unfortunately, the problems eventually surface in far worse situations than if the engineer had alerted people earlier.

When the problems surface, the natural consequences are felt by all involved, but the engineer who knew about the problems early on may quietly experience the fallout alongside bystanders or even avoid the consequences entirely. If you are the leader or mentor of this engineer, you can ensure the engineer fixes the issues (along with other coworkers involved). Tell the engineer what would have happened if you had known about the problems earlier—how they wouldn’t have had as much work, how more people would have been able to help, and how you could have negotiated fewer requirements or extended deadlines. As a result, the engineer will learn that withholding information doesn’t help and sharing information helps tremendously.

Eric Aside

For more about dealing with common problems, read You’re late, You can depend on me, and Bring out your dead: Postmortems.

No one is indispensable

Say an engineer always works alone. No one else on the team understands the engineer’s areas or codebase. The engineer might be doing a great job, but if they get sick or go on vacation, it’s a potential disaster.

The natural consequences of being the only person who knows an area or codebase are that the engineer can never get sick, go on vacation, or leave the team. If you are the leader or mentor of this engineer, you can insist that they not take sick leave or go on vacation until they’ve trained a backup for their area who reviews all their PRs and helps them fix bugs and make code improvements. As a result, the engineer will share information about their area, be able to take sick leave and vacation as needed, and understand the risks involved in being a single point of failure.

Say the engineer refuses to train a backup or let others touch their codebase. The engineer is willfully putting their product, customers, and team at risk, thereby failing to meet the expectations of their role. If this behavior persists, the natural consequence is disciplinary action. You should inform the engineer that they are falling short of expectations and that continuing to do so will lead to their dismissal. As a result, the engineer will understand the seriousness of their isolation and correct it, or they will eventually be replaced by someone more responsible.

Eric Aside

For more about avoiding single points of failure, read Knowledge loss.

Naturally better

People make mistakes all the time, but often they don’t learn from those mistakes because the consequences are delayed or avoided by chance. If you are a leader or mentor, you can ensure people learn from critical mistakes by invoking their natural consequences.

If an engineer takes shortcuts with their pull requests, insist that the engineer successfully predict at least half of the errors found during code review and PR validation. If an engineer hides problems, insist that they help resolve the problems even if they weren’t the cause, and inform them of all the ways the problem would have been minimized if the engineer had mentioned the issues earlier. If an engineer always works alone, insist that they train a backup before they ever take another sick day or vacation.

Invoking natural consequences feels fair and justified because the consequences are natural and the lessons learned help people avoid future mistakes. That’s an outcome we all can appreciate.

Eric Aside

Special thanks to James Waletzky for reviewing the first draft of this month’s column.

Want personalized coaching on this topic or any other challenge? Schedule a free, confidential call. I provide one-on-one career coaching with an emphasis on underrepresented, midcareer software professionals. Find out more at Ally for Onlys in Tech.

Read the whole story
alvinashcraft
15 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

.NET Core vs. .NET Framework: Key Differences and Best Use Cases

1 Share

.NET Core vs. .NET Framework Key Differences and Best Use Cases

TL;DR: .NET Core vs .NET Framework, which one should you choose in 2025? If you’re building modern, scalable, and cloud-ready applications, modern .NET (formerly .NET Core) is the clear winner. With blazing-fast performance, cross-platform flexibility, and continuous innovation, it’s built for the future. Meanwhile, .NET Framework still holds value for legacy Windows apps, but lacks the agility and updates needed for today’s development demands. For most forward-looking projects, modern .NET is your best bet.

The .NET ecosystem has powered software development for over two decades. While the .NET Framework was the default for Windows-based applications, the rise of cloud-native, microservices, and cross-platform development led to the birth of .NET Core, now unified as modern .NET. In 2025, developers face a strategic choice: maintain legacy systems or embrace the future with modern .NET.

.NET Framework

  • Release year: 2002
  • Latest version: 4.8.1 (August 2022)
  • Platform support: Windows only
  • Use cases: Enterprise desktop apps, ASP.NET Web Forms, WPF, WinForms, WCF
  • UI frameworks: WPF, Windows Forms

The .NET Framework is tightly integrated with Windows, offering features like COM interop, registry access, and Windows Authentication. It’s ideal for legacy systems but lacks modern deployment flexibility.

Modern .NET (.NET Core and Unified .NET)

  • Release year: 2016
  • Current version: .NET 9 (released November 12, 2024)
  • Platform support: Windows, macOS, Linux
  • Use cases: Cross-platform apps, cloud-native systems, microservices, .NET MAUI, IoT
  • UI frameworks: .NET MAUI, Blazor, WinUI 3, Windows Forms, and WPF

Modern .NET is modular, open-source, and optimized for containers, serverless environments, and scalable architectures.

Key difference between .NET Framework vs Modern .NET

Feature .NET Framework Modern .NET (Core and Unified)
Platform support Windows only Cross platform (Windows, macOS, Linux)
Deployment options Framework dependent only Self-contained and flexible
Performance Slower startup, limited optimization Faster startup, tiered JIT, AOT, optimized GC
Modularity Monolithic Modular via NuGet
Cloud-native Limited Built-in support
UI frameworks WinForms, WPF .NET MAUI, WinUI 3, and Blazor
Web development ASP.NET Web Forms, MVC ASP.NET Core, Blazor
Language features Supports older C# versions Latest C# features (e.g., C# 13)
Security updates Tied to Windows lifecycle Independent updates
Memory and async programming Basic memory management and limited async support. Developers rely on traditional threading and synchronous patterns. Efficient memory handling with Span and ValueTask. Supports async-first programming with AsyncEnumerable and improved task scheduling.
Networking and Security Uses legacy networking APIs and synchronous communication. Security features are tightly coupled with Windows. Supports HTTP/2 and a modern networking stack; modular security with built-in support for OAuth, OpenID Connect, and certificate-based authentication.
Background processing and observability Requires Windows Services or manual threading for background tasks. Limited diagnostics and monitoring tools Built-in support for hosted services and Channels for scalable background processing. Offers dotnet-trace, EventPipe, and OpenTelemetry for production diagnostics.
Community Closed source,Microsoft-led Open-source via GitHub and .NET foundation
Tooling support Visual Studio Visual Studio, VS Code, CLI tools (cross-platform)

Performance, modularity, and cloud readiness

Modern .NET offers:

  • Smaller footprint via modular packages.
  • Faster startup and high throughput with features such as tiered JIT compilation, optimized garbage collection, and ahead-of-time (AOT) compilation in .NET 8 and .NET 9.
  • Cloud-native support with gRPC, minimal APIs, and serverless optimization.
  • Containerization with Docker and Kubernetes.

Use cases: When to choose Which

Choose .NET Framework if:

  • App is Windows-only.
  • Uses unsupported legacy tech (e.g., Web Forms, WCF).
  • Stable and doesn’t need new features.

Choose Modern .NET if:

  • Starting a new project.
  • Need cross-platform compatibility.
  • Targeting cloud-native or microservices architecture.
  • Want ongoing performance and feature improvements.

Summary

.NET Framework

Pros:

  • Stable for enterprise Windows apps.
  • Support rich legacy technologies like COM, WCF, and Web Forms.
  • Deep Windows integration.

Cons:

  • No cross-platform support.
  • No new features.
  • Limited cloud-native capabilities.
  • Closed source.

Modern .NET

Pros:

  • Cross-platform and cloud-ready.
  • Modular and lightweight.
  • Active open-source community.
  • Frequent updates and innovation.

Cons:

  • Migration complexity.
  • Some legacy APIs are unsupported.
  • Requires learning new paradigms and tools.

FAQs

Q1: Is .NET Framework still supported in 2025?

Yes, but only with security updates tied to Windows lifecycle. No new features.

Q2: Can I run .NET Framework apps on Linux/macOS?

No. It’s Windows-only.

Q3: What’s the difference between .NET Core and modern .NET?

Modern .NET evolved from .NET Core and is now unified under the “.NET” branding.

Q4: Is .NET MAUI a replacement for WPF/WinForms?

Not directly. It’s for cross-platform apps. WPF/WinForms are still supported on Windows.

Q5: Should I migrate my legacy app to modern .NET?

Depends on business needs. If stable and Windows-only, staying may be a practical option. Otherwise, consider migration for future-proofing.

Conclusion

In 2025, the choice between .NET Framework and modern .NET is strategic. While the Framework serves legacy apps well, modern .NET is the future, offering performance, scalability, and cross-platform flexibility. For new development, modern .NET is the clear choice. For existing systems, evaluate the feasibility of migration and long-term goals.

Are you still working with the .NET Framework, or have you made the leap to modern .NET? What challenges or wins have you experienced? Drop your thoughts, questions, or insights in the comments below; we’re listening!

Read the whole story
alvinashcraft
15 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

VSCode SQL Extension Gets Schema Designer

1 Share
Read the whole story
alvinashcraft
15 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories