Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# Testing for Feature Flag Security Bypass
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order for the PDFs etc to generate and link internally properly the file name text needs to be the same as this (or vice versa). So either they both need to be "Testing" or they both need to be "Test"... "Test" seems to be the current file convention.


|ID |
|------------|
|WSTG-CONF-15|
Comment on lines +3 to +5
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ID table at the top uses double pipes (||) which renders as an empty leading column in Markdown. Other WSTG test cases in this section use a standard 1-column table (e.g., | ID |), so this should be converted to the same format for consistent rendering.

Copilot uses AI. Check for mistakes.

## Summary

Feature flags (also known as feature toggles, feature switches, or feature gates) are a software development technique that allows teams to enable or disable functionality without fully deploying (or exposing) new code. While feature flags provide significant benefits for progressive delivery and A/B testing, they can introduce security vulnerabilities when improperly implemented.

Common security issues with feature flags include:

- **Client-side manipulation**: Flags evaluated in the browser can be modified by attackers to enable restricted features.
- **Authorization bypass**: Hidden UI elements may still have accessible backend endpoints.
- **Information disclosure**: Flag configurations may leak unreleased features or internal logic.
- **Insecure defaults**: Fallback values when the flag service is unavailable may fail open.
- **Stale flag vulnerabilities**: Unused flags referencing deprecated code paths may contain unpatched vulnerabilities.

Modern applications increasingly rely on feature flag services (such as: LaunchDarkly, Split, Flagsmith, ConfigCat) or custom implementations for control roll-outs, making security testing of these mechanisms essential.

## Test Objectives

- Identify feature flags that gate security-relevant functionality.
- Assess whether feature flag states can be manipulated client-side.
- Verify that backend authorization is independent of flag state.
- Determine if flag configurations expose sensitive information.
- Evaluate fail-safe behavior when the flag service is unavailable.

## How to Test

### Identify Feature Flags in the Application

Search for evidence of feature flag implementations:

1. **Inspect JavaScript bundles** for references to feature flag services or configuration objects:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be better for these to be level 4 headings, with an intro sentence.


```javascript
// Common patterns to search for:
Comment on lines +35 to +38
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fenced code block under this ordered-list item is not indented, so it will break the list structure in CommonMark/GitHub rendering (the code block becomes “outside” the list and numbering restarts later). Indent the fenced blocks (or switch these to bullet points) so the steps and their examples stay grouped correctly; this pattern repeats in later sections too.

Copilot uses AI. Check for mistakes.
featureFlags
featureToggles
flags.isEnabled
LaunchDarkly
splitio
flagsmith
```

1. **Monitor network traffic** for requests to feature flag endpoints:

```http
GET /api/features HTTP/1.1
Host: example.com

HTTP/1.1 200 OK
Content-Type: application/json

{
"features": {
"new_checkout_flow": true,
"admin_panel_v2": false,
"beta_api": false
}
}
```

1. **Examine localStorage and cookies** for cached flag values.

### Test Client-Side Flag Manipulation

Attempt to modify flag values to enable restricted features:

1. **Intercept and modify responses**: Use a proxy tool to change flag values from `false` to `true` in API responses.

```http
# Original response
{"admin_mode": false}

# Modified response
{"admin_mode": true}
```

1. **Modify localStorage**: If flags are cached client-side, change the values directly.

```javascript
// In browser console
localStorage.setItem('featureFlags', JSON.stringify({
...JSON.parse(localStorage.getItem('featureFlags')),
restricted_feature: true
}));
```

1. **Observe application behavior**: Determine if the application grants access to functionality that should be restricted.

### Verify Backend Authorization Independence

Ensure backend endpoints enforce authorization independently of flag state:

1. **Identify hidden endpoints**: Extract API endpoints from JavaScript bundles that are associated with disabled features.

```bash
# Search for API patterns in JS files
grep -oE '/api/v[0-9]+/[a-zA-Z_]+' bundle.js
```

1. **Send direct requests**: Attempt to access endpoints for disabled features.

```http
POST /api/admin/users/delete HTTP/1.1
Host: example.com
Authorization: Bearer <user_token>
Content-Type: application/json

{"user_id": "12345"}
```

1. **Expected result**: The server should return `403 Forbidden` if the feature is disabled, not just hide the UI.
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This expected result is phrased as “return 403 if the feature is disabled”, which conflicts with the goal of verifying authorization is independent of flag state. Consider rewording to focus on access control (e.g., unauthorized users must get 403/401 regardless of client-side flag manipulation; if the feature is globally disabled, the endpoint should remain inaccessible regardless of role per the app’s design).

Suggested change
1. **Expected result**: The server should return `403 Forbidden` if the feature is disabled, not just hide the UI.
1. **Expected result**: The server must enforce authorization independently of client-side flag state: unauthorized users receive `401 Unauthorized` or `403 Forbidden` for this endpoint even if they manipulate flags client-side. If the feature is globally disabled by design, the endpoint should remain inaccessible (for example, `404 Not Found` or `403 Forbidden` for all users), rather than only hiding the UI.

Copilot uses AI. Check for mistakes.

### Test Fallback Behavior

Evaluate what happens when the feature flag service is unavailable:

1. **Block connectivity** to the flag provider using browser DevTools network blocking or hosts file modification.

```bash
# Add to /etc/hosts (testing only)
127.0.0.1 sdk.launchdarkly.com
127.0.0.1 app.split.io
```

1. **Observe fallback behavior**: Determine if the application fails open (enables features) or fails closed (disables features).
1. **Security-critical result**: Features gating security controls should default to disabled when the flag service is unreachable.
Comment thread
kingthorin marked this conversation as resolved.

### Analyze Flag Configuration for Information Leakage

Examine flag payloads for sensitive information:

1. **Capture flag configuration responses** and look for:
- Unreleased feature names revealing roadmap
- Internal tool references
- Targeting rules containing email domains or user identifiers
- Environment-specific configurations

1. **Example of information leakage**:

```json
{
"flags": {
"internal_admin_tool_q1_2025": false,
"bypass_rate_limit_for_enterprise": false,
"show_feature_if_email_contains_@internal.company.com": true
}
}
```

### Test for Stale Feature Flags

Identify and test unused flags that may expose deprecated functionality:

1. **Map all flags** and their creation dates if available.
1. **Force-enable old flags** and observe if deprecated code paths are accessible.
1. **Assess deprecated code** for known vulnerabilities or security weaknesses.

## Remediation

To prevent feature flag security bypass vulnerabilities:

- **Server-side evaluation**: Evaluate security-critical flags on the server, never trust client-provided values.
- **Authorization independence**: Backend authorization checks must not depend on flag state.
- **Fail-secure defaults**: Configure security-relevant flags to default to disabled if the flag service fails.
- **Minimal client exposure**: Only send flag evaluation results to clients, not targeting rules or full configurations.
- **Flag hygiene**: Implement policies to remove flags after their purpose is complete (typically 30-90 days post-launch).
- **Audit logging**: Log flag evaluations for security-critical features.

For more details, see:

- [OWASP Application Security Verification Standard (ASVS)](https://owasp.org/www-project-application-security-verification-standard/)
- [OWASP Top Ten - A01:2021 Broken Access Control](https://owasp.org/Top10/A01_2021-Broken_Access_Control/)

## Tools

- [Burp Suite](https://portswigger.net/burp) - Intercept and modify HTTP traffic
- [ZAP](https://www.zaproxy.org/) - Web application security testing
- Browser Developer Tools - Network inspection and localStorage modification

## References

- [Feature Toggles (aka Feature Flags) - Martin Fowler](https://martinfowler.com/articles/feature-toggles.html)
- [LaunchDarkly Account Security](https://launchdarkly.com/docs/home/account/secure)
- [OWASP Testing Guide](https://owasp.org/www-project-web-security-testing-guide/)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The guide doesn't need to link to itself as a ref 😀

Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@
4.2.13 [Test for Path Confusion](13-Test_for_Path_Confusion.md)

4.2.14 [Test for Other HTTP Security Header Misconfigurations](14-Test_Other_HTTP_Security_Header_Misconfigurations.md)

4.2.15 [Test for Feature Flag Security Bypass](15-Test_for_Feature_Flag_Security_Bypass.md)