DevSecOps

Feature Flags Security Implications

Understanding the security risks of feature flag systems and how to prevent unauthorized flag manipulation, data exposure, and configuration drift.

Alex
Cloud Security Architect
6 min read

Feature flags are everywhere. LaunchDarkly, Split, Flagsmith, Unleash, and homegrown systems give teams the ability to toggle features in production without deploying new code. This capability is powerful — and security teams consistently underestimate its risk.

A feature flag is a runtime configuration that changes application behavior. In security terms, it is an attack surface. An attacker who can manipulate feature flags can enable debug modes, bypass authentication checks, expose internal APIs, grant admin access, or disable security controls — all without touching a single line of code.

The Threat Model

Feature flag systems introduce several threat vectors:

Unauthorized Flag Manipulation

If an attacker gains access to your feature flag management interface (or API), they can:

  • Enable features that bypass authentication or authorization.
  • Disable rate limiting, WAF rules, or other security controls implemented behind flags.
  • Enable debug or admin features in production.
  • Gradually roll out malicious configurations to targeted user segments.

Flag Data Exposure

Feature flag SDKs often evaluate flags client-side in web and mobile applications. The flag configuration — including targeting rules — is sent to the client. This can expose:

  • Internal feature names that reveal development roadmaps.
  • Targeting rules that reveal business logic (e.g., "users with role admin get feature X").
  • User segment definitions that map to internal identifiers.

Configuration Drift

Feature flags that were supposed to be temporary become permanent. A flag that disables a security control "for testing" stays enabled for months because nobody tracks its lifecycle. The development team forgets the flag exists. The security control remains disabled.

Dependency Chain Risk

Your feature flag service is now a critical dependency. If it goes down, what happens? If the SDK fails to load flags, does the application use safe defaults? Many applications use the flag SDK's default values, which may be insecure.

Access Control

The most important security measure for feature flags is strict access control on who can create, modify, and delete flags.

Role-Based Permissions

Flag Reader: View flags and their current state.
Flag Manager: Create and modify flags for non-production environments.
Production Flag Manager: Modify flags in production (requires approval).
Flag Administrator: Delete flags, manage environments, configure integrations.

Most feature flag platforms support environment-level permissions. A developer should be able to toggle flags in development and staging environments freely, but production flag changes should require a review process.

Approval Workflows

For production flag changes, implement an approval workflow:

  1. Developer requests a flag change.
  2. Change is reviewed by a peer or security team member.
  3. Approved change is applied.
  4. Change is logged and auditable.

LaunchDarkly, Split, and Flagsmith all support approval workflows. If your homegrown system does not have this, build it before someone accidentally enables a debug endpoint in production.

API Key Management

Feature flag SDKs authenticate with API keys. These keys typically come in two varieties:

  • Server-side keys: Full access, used in backend services. Never expose these client-side.
  • Client-side keys: Limited access, used in browsers and mobile apps. These are inherently public.

Treat server-side flag keys with the same care as database credentials. Rotate them regularly. Scope them per environment.

Secure Flag Evaluation

Server-Side vs. Client-Side Evaluation

Client-side evaluation sends flag configurations to the client, where the SDK evaluates targeting rules locally. This is fast but exposes your flag data.

Server-side evaluation happens on your backend. The client sends context (user ID, attributes) to your server, which queries the flag service and returns only the evaluated result (true/false, variant name). No flag configuration is exposed.

For security-sensitive flags, always use server-side evaluation:

// Client-side: flag config exposed to browser
const showAdminPanel = ldClient.variation('admin-panel', false);

// Server-side: only the boolean result reaches the client
app.get('/api/features', async (req, res) => {
  const flags = await ldClient.allFlagsState(req.user);
  res.json(flags);  // Only evaluated values, not rules
});

Default Values

When the flag SDK cannot reach the flag service, it falls back to default values. These defaults must be secure:

// Insecure default: feature enabled when service is down
const bypassAuth = ldClient.variation('bypass-auth', true);  // BAD

// Secure default: feature disabled when service is down
const bypassAuth = ldClient.variation('bypass-auth', false);  // GOOD

Every flag's default value should be the secure option. If the flag service goes down, your application should become more restrictive, not less.

Flag Lifecycle Management

Feature flags have a lifecycle: they are created, used, and should eventually be removed. Without lifecycle management, flags accumulate and become security debt.

Flag Expiration

Set expiration dates on flags when they are created. A flag for a gradual rollout should expire 30 days after full rollout. A flag for a time-limited promotion should expire when the promotion ends.

Stale Flag Detection

Monitor for flags that have not changed state in months. If a flag has been true for all users for six months, it is no longer a flag — it is dead code wrapped in indirection. Remove it.

Security-Critical Flag Tagging

Tag flags that control security-sensitive behavior:

  • Authentication and authorization bypasses.
  • Rate limiting and abuse prevention.
  • Data encryption and privacy controls.
  • Logging and audit trail features.

These flags should have stricter access controls, required approval workflows, and mandatory review before state changes.

Audit and Monitoring

Flag Change Audit Trail

Log every flag change with:

  • Who made the change.
  • What changed (old value, new value, targeting rules).
  • When the change was made.
  • Why (require a change reason).

Runtime Monitoring

Monitor flag evaluation patterns for anomalies:

  • A flag that suddenly changes evaluation ratio (e.g., from 50/50 to 100/0) when no change was made could indicate SDK misconfiguration or targeting rule manipulation.
  • A spike in flag evaluations for a specific user could indicate someone testing attack vectors.
  • Flag evaluations from unexpected geographic locations or IP ranges.

Incident Response Integration

Include feature flags in your incident response playbook. When investigating a security incident, check:

  • Were any flags changed around the time of the incident?
  • Are any security-critical flags in an unexpected state?
  • Did the flag service experience any outages that caused fallback to defaults?

How Safeguard.sh Helps

Safeguard.sh monitors your application's security configuration holistically, including feature flag state. It tracks security-critical flags across environments, alerts when flags controlling security features change state, and maintains an audit trail that correlates flag changes with security events. When investigating an incident, Safeguard.sh provides a timeline view that shows flag state changes alongside vulnerability discoveries, deployment events, and security scan results — giving your team the full context needed to understand what happened and why.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.