Flutter macOS dev is fun. Making custom modules for native features that don’t already exist as open source components is the way to go.

Having a lot of fun with macos flutter development. I’ve created two modules so far for making macos specific stuff work. One for drag and drop and one for doing native menu state enabling and disabling stuff dependent on what window and screen is active, like sometimes save is greyed out if not viewing a file that can be saved. It ends up being a pretty complicated system and after awhile debugging I decided to make it into a library. Finally got it working. I think AI works better when appropriately using and creating modules instead of a 3k line appdelegate file. Once I get CodeFrog into the Apple store I plan to open source these modules I created so it takes less time for other devs who want to have mac native features in Flutter like drag and drop and dynamic menus.

Do you have a need for a Flutter macOS expert? I’m open to work!

Happy Thanksgiving from Maryland.

Mailchimp’s Security Issues: Why We Need a Better Newsletter Solution

A B Rating From CodeFrog

While building CodeFrog’s landing page, we integrated Mailchimp for newsletter signups. However, our security scans revealed a critical issue that prevents us from achieving an A rating: Mailchimp’s validation script violates Content Security Policy (CSP) requirements.

The Security Violation

Mailchimp’s mc-validate.js script injects inline styles dynamically, which requires the 'unsafe-inline' directive in our CSP style-src policy. This is a security anti-pattern because:

  1. CSP Bypass Risk: 'unsafe-inline' allows any inline styles, defeating the purpose of CSP protection against XSS attacks
  2. Nonce Incompatibility: Even when using CSP nonces for our own styles, Mailchimp’s dynamically injected styles can’t use nonces, forcing us to allow all inline styles
  3. Security Rating Impact: Security scanners (like our own Mega Report) flag this as a MEDIUM severity issue, preventing an A rating

The Error

When we removed 'unsafe-inline' to improve security, the browser console shows:

Applying inline style violates the following Content Security Policy directive: 
`style-src 'self' 'nonce-...'`. The action has been blocked.

This error originates from mc-validate.js:164, confirming that Mailchimp’s script requires unsafe inline styles to function.

Why This Matters

Content Security Policy is a critical security feature that helps prevent:

  • Cross-Site Scripting (XSS) attacks
  • Data injection attacks
  • Code injection vulnerabilities

By requiring 'unsafe-inline', Mailchimp forces us to weaken our security posture, which is unacceptable for a security-focused tool like CodeFrog.

What We Need

We’re looking for a newsletter service that:

Free tier (or very affordable) for up to 500 subscribers
CSP-compliant – doesn’t require 'unsafe-inline'
Secure by default – supports nonces or external stylesheets
Easy integration – simple embed or API
Reliable – good deliverability and uptime

Call for Recommendations

We’re reaching out to the developer community for recommendations. If you know of a newsletter service that:

  • Respects modern web security standards
  • Works with strict CSP policies
  • Offers a free tier for small lists
  • Provides good deliverability

Please share your suggestions! We’re particularly interested in:

  • Self-hosted solutions (if they’re easy to set up)
  • Modern alternatives that prioritize security
  • Services that use external stylesheets or support CSP nonces
  • Any workarounds for making Mailchimp CSP-compliant (if they exist)

The Solution: CSP Hash Instead of Unsafe-Inline

Good news! We found a solution that doesn’t require 'unsafe-inline'. When we removed 'unsafe-inline' from our CSP, the browser console error message actually provided the answer:

Applying inline style violates the following Content Security Policy directive: 
'style-src 'self' 'nonce-...''. Either the 'unsafe-inline' keyword, a hash 
('sha256-iIHQ0a6ntSSQhfMwBwjvXvp+zrKJldURld+iiblnEKo='), or a nonce 
('nonce-...') is required to enable inline execution.

The browser helpfully suggested using a hash for the specific inline style instead of allowing all inline styles. This is a much better security approach!

What We Changed

Instead of using 'unsafe-inline' in our CSP style-src directive, we now use:

style-src 'self' 'nonce-{style_nonce}' 'sha256-iIHQ0a6ntSSQhfMwBwjvXvp+zrKJldURld+iiblnEKo='

This hash is specific to the inline style that Mailchimp’s mc-validate.js script injects. By using the hash, we:

Allow only that specific style – not arbitrary inline styles
Maintain strict CSP – no 'unsafe-inline' directive
Pass security scans – scanners don’t flag specific hashes
Keep Mailchimp working – the validation script functions correctly

Why This Is Better

Using a hash is more secure than 'unsafe-inline' because:

  • It’s whitelist-based: Only the exact style with that hash is allowed
  • It’s CSP-compliant: Security scanners accept hashes as a valid, secure approach
  • It’s maintainable: If Mailchimp changes their script, we’ll get a new error with a new hash to add

Remaining Issue

While we’ve solved the CSP style-src issue, there’s still one security concern:

⚠️ SRI (Subresource Integrity) Missing: Mailchimp’s script is loaded from their S3 bucket without an integrity attribute. This means we can’t verify the script hasn’t been tampered with. However, this is a known limitation because:

  • Mailchimp’s script is dynamically generated and changes frequently
  • Their S3 bucket doesn’t send CORS headers, which would be required for SRI
  • Adding crossorigin="anonymous" would break script loading due to CORS issues

This is a MEDIUM severity issue that prevents a perfect A+ rating, but it’s an acceptable trade-off given the constraints.

Conclusion

As a security-focused developer tool, CodeFrog needs to maintain the highest security standards. We’ve successfully resolved the CSP 'unsafe-inline' issue by using a hash-based approach, which is more secure and CSP-compliant.

The remaining SRI issue is a known limitation with third-party scripts that don’t support CORS, and we’ve documented it appropriately. We’re now much closer to that A security rating!


Update: We solved the CSP issue using a hash-based approach! The browser’s error message provided the exact hash we needed. Mailchimp now works with strict CSP without requiring 'unsafe-inline'.

Update by Editor: Reviewing this post I found it said it was maintainable to have a hash value that gets updated if MailChimp changes their scripts. This doesn’t seem very maintainable to me. I have to manually check for errors, or build an automated test that checks and then changes(?) the hash. I would still want to review it I think. I may take off the hash value and reduce the codefrog.app mega report rating since it seems dumb to have to keep it updated. Another option is to build an automated test that does it. Or wait for some ideas from someone else? Maybe there’s a way to use a REST api for Mailchimp which would be better. It would be nicer if it was just secure by default though.

Building Inclusive Web Applications: Accessibility Testing with CodeFrog and axe-core

Introduction

Accessibility is not a feature—it’s a fundamental requirement for modern web and mobile applications. Over 1 billion people worldwide live with disabilities, and many rely on assistive technologies to navigate digital products. Beyond the moral imperative, accessible applications reach broader audiences, improve SEO rankings, and help organizations comply with legal standards like WCAG 2.1 and the Americans with Disabilities Act (ADA).

However, accessibility testing remains challenging for many development teams. Manual testing is time-consuming and error-prone, while developers often lack the expertise to identify subtle accessibility violations. This is where automated testing tools become invaluable.

The Challenge: Common Accessibility Issues

Developers frequently encounter accessibility barriers that go unnoticed during standard testing:

  • Missing alt text on images, leaving screen reader users without context
  • Insufficient color contrast making content unreadable for users with low vision
  • Unlabeled form fields confusing users relying on screen readers
  • Broken heading hierarchy disrupting document structure and navigation
  • Missing ARIA attributes preventing assistive technologies from understanding dynamic content
  • Keyboard navigation failures excluding users who cannot use a mouse
  • Missing focus indicators making it impossible to track keyboard position

These issues compound, creating frustrating experiences for users with disabilities while exposing organizations to legal liability.

CodeFrog’s Solution: Automated Accessibility Testing

CodeFrog integrates axe-core, the industry-leading automated accessibility testing engine, directly into your development workflow. This powerful integration enables developers to catch accessibility violations early—during development, not after deployment.

With CodeFrog’s Web Testing feature, you can:

  1. Test multiple sources: Select a local HTML file, enter a URL (localhost, staging, or production), or test a remote server
  2. Test entire sites through sitemap testing: Provide a sitemap URL to automatically test all pages across your entire website, ensuring comprehensive accessibility coverage
  3. Run automated accessibility scans powered by axe-core
  4. View detailed violation reports with severity levels and remediation guidance
  5. Iterate quickly with instant feedback on accessibility improvements

Whether you’re testing a development server running on localhost:3000, a staging environment, a production URL, or an entire site via sitemap, CodeFrog brings accessibility testing directly into your workflow.

What axe-core Detects

axe-core performs comprehensive automated testing across multiple accessibility standards:

Image and Media

  • Missing or empty alt attributes on images
  • Unlabeled buttons and icons
  • Missing captions on video content

Color and Contrast

  • Text with insufficient contrast ratios (WCAG AA/AAA standards)
  • Color-only information without alternative indicators

Forms and Labels

  • Form inputs without associated labels
  • Missing or incorrect for attributes on labels
  • Unlabeled fieldsets and legend elements

Document Structure

  • Improper heading hierarchy (skipping levels like H1 → H3)
  • Missing page landmarks (main, navigation, contentinfo)
  • Duplicate IDs on page elements

ARIA and Semantics

  • Invalid ARIA roles and attributes
  • Missing required ARIA properties
  • Misused semantic HTML elements

Keyboard Navigation

  • Interactive elements not keyboard accessible
  • Missing focus indicators
  • Keyboard traps preventing escape

Benefits for Your Development Team

Shift-Left Testing: Catch accessibility issues before code review, reducing remediation costs and timeline pressure.

Developer Education: Detailed violation reports help your team understand why issues matter and how to fix them, building accessibility expertise across the organization.

Continuous Improvement: Integrate accessibility testing into your CI/CD pipeline to prevent regressions.

Compliance Confidence: Demonstrate accessibility commitment to stakeholders, customers, and regulators.

Inclusive Products: Build applications that work for everyone, expanding your user base and market reach.

Getting Started

CodeFrog makes accessibility testing accessible to developers of all experience levels. Whether you’re building a new feature or auditing an existing application, the Web Testing feature provides actionable insights to improve your digital products.

Start testing today and join the movement toward truly inclusive web development.


CodeFrog: Empowering developers to build accessible, inclusive applications.

Solving Drag-and-Drop in Flutter macOS: A Journey

The Problem

Implementing native drag-and-drop functionality in a Flutter macOS application that works seamlessly with scrolling and file selection proved to be one of the most challenging features we’ve built. The goal was simple: allow users to drag files into and out of CodeFrog, supporting both local and network (SSH) projects, while maintaining smooth scrolling and file selection.

Initial Attempt: super_drag_and_drop

We started with the super_drag_and_drop package, which provides cross-platform drag-and-drop support. While it worked for basic scenarios, we encountered several issues:

  1. Unreliable drag-out for remote files – Files on network/SSH connections needed to be downloaded before dragging, and the async nature of this operation caused frequent failures
  2. Gesture conflicts – The package’s gesture recognizers conflicted with Flutter’s built-in scrolling and selection mechanisms
  3. Limited control – We needed more fine-grained control over the drag-and-drop behavior, especially for handling remote file downloads

After many hours of debugging and attempting workarounds (pre-downloading files, using virtual files, adjusting gesture recognizers, etc.), we decided to build a custom solution using native macOS APIs.

The Custom Solution: flutter_macos_drag

We built a custom Flutter plugin (flutter_macos_drag) that uses native macOS NSDraggingSource and NSDraggingDestination protocols directly. This gave us complete control over the drag-and-drop behavior.

Key Components

  1. MacOSDraggable – A Flutter widget for dragging files out of the app
  2. MacOSDroppable – A Flutter widget for accepting file drops from Finder
  3. DraggableNSView – Native Swift view implementing NSDraggingSource and NSDraggingDestination

The Challenge: Scrolling vs Drag-and-Drop

The biggest challenge was making drag-and-drop work while preserving scrolling functionality. The native AppKitView needed to be in the widget hierarchy to receive drag events, but it was blocking pointer events needed for scrolling.

Failed Approaches:

  • Using IgnorePointer – Blocked drag events
  • Using AbsorbPointer – No effect
  • Using Listener with HitTestBehavior – Still blocked events
  • Reversing Stack order – Drag events didn’t reach the native view

The Solution: hitTest Override

The breakthrough came from understanding how macOS handles drag events vs pointer events:

  1. Drag events work at the NSView level and query all registered views directly, completely bypassing Flutter’s pointer system and hit testing
  2. Pointer events (scrolling, clicking) go through normal hit testing

By overriding hitTest in the native view to return nil for drop zones, we allow pointer events to pass through to Flutter widgets below, while drag events still work because they query registered views directly.

override func hitTest(_ point: NSPoint) -> NSView? {
    // For drop zones, return nil to let pointer events pass through to Flutter
    // Drag events don't use hitTest - they query all registered views directly
    if acceptDrops && filePath == nil {
        return nil
    }
    return super.hitTest(point)
}

Additionally, we made mouse event handlers return early for drop zones:

override func mouseDown(with event: NSEvent) {
    // For drop zones, don't handle mouse events - let them pass through for scrolling
    if acceptDrops && filePath == nil {
        return // Don't call super - allows events to pass through
    }
    // ... handle drag-out logic
}

Widget Structure

The final widget structure uses a Stack with the native view on top:

Stack(
  children: [
    // Native view on top - configured to not block pointer events
    Positioned.fill(
      child: Opacity(
        opacity: 0.01,
        child: AppKitView(...),
      ),
    ),
    // Flutter widgets below - receive pointer events for scrolling
    widget.child,
  ],
)

Features Achieved

Drag files out – Works for both local and network files
Drag files in – Accepts drops from Finder into any directory
Scrolling – File tree pane scrolls smoothly
File selection – Click to select files works normally
Remote file handling – Downloads remote files on-demand during drag
Root directory support – Can drop files at project root (empty path)

Key Technical Insights

  1. macOS drag events bypass Flutter’s pointer system – They query all registered views directly, so IgnorePointer and similar widgets don’t affect them
  2. hitTest controls pointer events, not drag events – Returning nil from hitTest allows pointer events to pass through while drag events still work
  3. View registration is separate from hit testing – Views registered with registerForDraggedTypes receive drag events regardless of hitTest results
  4. Mouse event handlers must return early – For drop zones, don’t call super in mouse event handlers to allow events to pass through

Lessons Learned

  • Sometimes a custom native solution is necessary when cross-platform packages don’t meet specific requirements
  • Understanding the underlying platform APIs (NSDraggingSource/NSDraggingDestination) is crucial
  • The interaction between Flutter’s pointer system and native platform views requires careful consideration
  • Persistence pays off – this took many hours but resulted in a robust, maintainable solution

This solution was developed over many hours of debugging and research. The key was understanding that macOS drag events operate at a different level than pointer events, allowing us to let pointer events pass through while still receiving drag events.

CodeFrog beta available for testing

CodeFrog for Mac Desktop now available for open testing. It’s a tool for developers.

https://testflight.apple.com/join/xz2v1wYq

I’d love it if you take a look if you’re a dev. Accessibility testing, security testing, bulk domain security testing via DNS API, analyze code with static analysis tools, find vulnerabilities with OSV, HTML validation, GitHub PR response automation, connect to servers via ssh and view your cpu, ram, hd usage.

I have a decision to make

Why can’t sandboxed mac app store apps have full disk access available in the system settings for full disk access?

I discovered mac app store apps in release mode cannot access the ai auggie command line program and other command line programs like opengrep on your system. Debug builds fine.

I came up with a workaround: Since I have an ssh client built in for connecting to remote servers, why not connect to ssh on the same local machine… Ask the user for their username and password in a popup.

To do this, you have to enable remote login on your mac in system settings -> sharing.

In addition you must grant full disk access to cli ssh in system settings:  add /usr/libexec/sshd-keygen-wrapper

It all works, but I don’t see the cli program in mac settings. To remove the cli program you must run a command line program to remove all full disk access support from all apps. No way to just undo ssh.

So my question is, even though I got CodeFrog all working for a mac app store release, should I not do it because it’s insecure or too complicated with the system settings? Should I instead sell the app off the store like Panic Nova?

Need some advice. I have not implemented in app purchases yet. Should I just have a reality check and sell the app off the store, or try for app store approval?

Bummer…

Edit: Maybe I’m ahead of my time, but perhaps Apple could review the source code for apps requesting full disk access and make sure there’s nothing fraudulent in them. Then, developer tools app store apps could be in the store with the user’s assurance that nothing is happening behind the scenes that is scary.

Edit2: I asked my question in Apple dev forums.

https://developer.apple.com/forums/thread/807142

CodeFrog uploaded to Testflight

Uploaded my first build of CodeFrog to Testflight today! It is waiting for review.

CodeFrog is a developer tool coming soon for macOS. It helps automate security testing, speeds up pull request reviews by exporting all CodeRabbit comments to an AugmentCode task list, and more.

I still have to build the website for it and add payments and help docs, but the app is mostly done.

CodeFrog: Find & Fix Bugs Fast with macOS and Mobile Apps – Vibe & Verify

CodeFrog is a professional, Flutter‑based mobile and desktop app that brings modern development workflows to your pocket. With API integrations from GitHub, Linode, Hetzner, and Sendgrid, secure SSH server management, GitHub PR review integrations, and a powerful Web Testing and Security Scanning toolkit, CodeFrog helps you diagnose, fix, and ship software faster—from anywhere. You can develop on your phone while connected to a remote server like mac.

CodeFrog is currently in development. I hope to have a macOS release before the end of the year, with mobile apps following soon after.

Ethical and legal use notice: Only run security scans against systems you own or are explicitly authorized to test. Unauthorized scanning may violate laws and terms of service.


Security Scanning Features

CodeFrog’s security scanners focus on high‑signal, read‑only checks inspired by OWASP guidance and industry best practices.

  • Single‑site security scanner with OWASP‑based checks
  • Bulk security scanner connected to Linode API for DNS with concurrent scanning of multiple targets
  • HTTPS/HTTP automatic fallback with clear indicators
  • Real‑time streaming results as scans complete
  • Critical findings popup alerts
  • Severity‑based filtering (Critical, High, Medium, Low, Info)
  • Live findings display while scanning is in progress
  • HTTP fallback indicators throughout the UI
  • Selectable/copyable URLs and findings
  • “Open in browser” buttons for quick access

What this means in practice:

  • CodeFrog performs safe, read‑only HTTP methods (HEAD/GET/OPTIONS)
  • Results stream in as each target finishes—no need to wait for the entire batch
  • If HTTPS fails, CodeFrog retries over HTTP and clearly marks any fallback usage
  • Critical results trigger a blocking alert so you can prioritize remediation immediately

Export & share:

  • Export findings as JSON/Markdown/CSV
  • Copy‑to‑clipboard for single findings or entire result sets
  • Summary chips by severity filtering in bulk mode

Web Testing & Code Analysis Features

A practical suite for validating web experiences and inspecting network characteristics—all in one place.

  • HTML validation

  • Meta tags analysis

  • Page timing metrics

  • Size analysis

  • Accessibility scanning

  • Open Source Vulnerability scanning (OSV.dev)

  • Static analysis with OpenGrep/Semgrep (macOS desktop)

  • Line counting with configurable exclusions (e.g., *.log files)

  • Secrets scanning with Gitleaks (MIT licensed, install with Homebrew)

  • Exclusion of third‑party directories (e.g., Pods) from secrets scans

  • Exclusion of Flutter build artifacts (.dart_tool, build) from scans

  • Selectable/copyable validator results with “Copy All Errors” action

  • Display of zero‑count severities in bulk scanner

  • “Scan first N unscanned” functionality for incremental scanning

Highlights:

  • Accurate timing breakdown (DNS, TCP connect, TLS handshake, TTFB, download)
  • Resource inventory with compressed/uncompressed size insights
  • Meta tags validator for Open Graph and Twitter Card with quick previews

GitHub Integration

Turn PR feedback into action with lightweight, mobile‑friendly workflows.

  • PR comments viewer with CodeRabbit integration
  • Easy export of GitHub PR comments into Augment Code markdown task list format
  • Task titles prefixed with PR number and comment number (e.g., “PR#45 Comment #123: task title”)
  • Bulk selection and delete/re‑import functionality for GitHub tasks
  • Filtering for unresolved comments only
  • Hide/expand first comment by default
  • Import options (first/5/10/all comments)
  • Structured AI suggestion parsing with title and description sections
  • Export/post all remaining raw comment texts when lacking AI summary

Benefits:

  • Create actionable tasks from PR comments in seconds
  • Keep review context portable across devices and sessions
  • Maintain signal by filtering unresolved items and hiding nitpicks by default

Servers Screen Features

Manage and monitor your development infrastructure securely.

  • At‑a‑glance server statistics dashboard showing all servers simultaneously
  • Real‑time disk space monitoring with cron job setup
  • SSH connection pooling (one login per unique server)
  • Server management with RSA 4096‑bit SSH keys
  • Secure private key storage via Flutter Secure Storage

Why it matters:

  • Strong, key‑based authentication by default (RSA‑4096)
  • Minimal re‑authentication thanks to connection pooling
  • Early warning on low‑disk conditions—right inside the app

API Integrations & Automation Value

CodeFrog connects to your ecosystem to eliminate manual tasks and coordinate workflows.

Hetzner API

  • SSH key management
  • Server statistics retrieval

Linode API

  • Automated domain discovery for bulk security scanning
  • DNS record enumeration
  • Website target generation from domain records

SendGrid API

  • Disk space notification service (low-disk alerts via email)

GitHub API

  • PR comments retrieval and parsing
  • Issue/comment status management (resolve/unresolve)
  • Task import automation
  • Integration with Augment Code workflow

Each integration replaces multi‑tool manual steps with streamlined, in‑app actions. The result: fewer context switches and faster cycles from feedback to fix.


Architecture and Privacy at a Glance

  • Flutter + Dart with Riverpod for reactive state
  • Read‑only scanners; no active exploitation or credential use
  • Hybrid data model: local SQLite (drift) for session data; secure storage for secrets
  • HTTPS/HTTP fallback clearly indicated; TLS verification on by default
  • Accessibility and WCAG AA contrast targets across the UI

Getting Started

  1. Open CodeFrog and navigate to Web Testing → Security Scan
  2. Enter a URL or switch to Bulk mode to scan multiple targets
  3. Watch live results stream in; use filters and “Open in browser” to inspect quickly
  4. Export findings and copy summaries directly to issues or tasks

For GitHub PR workflows, open the PR viewer to import comments as tasks, filter unresolved discussions, and keep your reviews moving—wherever you are.


A safer, faster path from feedback to fix

With practical, read‑only checks and tight integrations, CodeFrog turns security scanning and web diagnostics into a fast, mobile‑ready workflow. Combine it with GitHub PR tooling and server management to close the loop—from detection to resolution—without leaving your device.