Skip to content

AD5009: DoNotUseWeakDylib

Summary

Property Value
ID AD5009
Name DoNotUseWeakDylib
Category Security
Severity Warning
Applies to Mach-O (macOS)

Description

Weak dylibs (LC_LOAD_WEAK_DYLIB) are optional at load time. If a weak dylib is not found, the loader continues anyway. This can be exploited by attackers who place a malicious library at the expected location, leading to "dylib hijacking" attacks.

How It Works

The rule checks for LC_LOAD_WEAK_DYLIB load commands in the Mach-O binary. These are created when linking with -weak_library or -weak-l flags.

Why This Matters

Weak dylibs create a race condition for code execution. If the library doesn't exist at the expected path, an attacker who can write to that location gains automatic code execution with the application's privilegesβ€”a critical vulnerability.

The Dylib Hijacking Attack Chain

1. Discovery:
   Attacker examines app with otool:
   otool -L /Applications/VulnerableApp.app/Contents/MacOS/VulnerableApp

   Shows: @rpath/OptionalSDK.framework/OptionalSDK (weak)

2. Verification:
   Attacker confirms library doesn't exist:
   ls /Library/Frameworks/OptionalSDK.framework
   "No such file or directory"

3. Exploitation:
   Attacker creates malicious library:
   mkdir -p /Library/Frameworks/OptionalSDK.framework/
   cp malicious.dylib /Library/Frameworks/OptionalSDK.framework/OptionalSDK

4. Execution:
   User runs VulnerableApp
   Attacker's code runs with user's privileges

Why Weak Linking Exists

Use Case Intent
Optional features "Use if available"
SDK flexibility Support multiple SDK versions
Backward compat Run on older macOS

Attack Surface

Weak Dylib Location Attacker Access Risk
/usr/local/lib Often writable High
~/Library/... User-writable High
@rpath (app bundle) Needs app write Medium
/System/Library SIP protected Low

Privilege Escalation Path

1. Normal user runs admin app (sudo, etc.)
2. App has weak dylib in writable location
3. Attacker (as normal user) plants malicious lib
4. Next time admin runs app:
   Malicious code runs with admin privileges

Detection Difficulty

Indicator Visibility
Malicious dylib on disk Visible if you look
Load at runtime In logs (if enabled)
Code execution Indistinguishable

Once loaded, malicious code looks legitimate.

Safer Alternatives

Instead Of Use
Weak linking dlopen() with checks
Optional features Feature detection at runtime
SDK flexibility Bundle required SDKs

Dylib Hijacking Attack

  1. Application weakly links to /opt/SomeSDK/lib/helper.dylib
  2. Attacker notices the library doesn't exist on the system
  3. Attacker creates /opt/SomeSDK/lib/helper.dylib with malicious code
  4. Application loads attacker's library with full privileges

Real-World Impact

  • Privilege escalation: Malicious code runs with app's permissions
  • Data theft: Access to app's memory and files
  • Persistence: Library loads every time app runs
  • Code signing bypass: On older macOS versions

Resolution

Use Strong References

Before (vulnerable):

clang source.c -o binary -weak_library /path/to/lib.dylib
clang source.c -o binary -weak-lhelper

After (secure):

clang source.c -o binary -L/path/to -lhelper

Bundle Required Libraries

Instead of weak linking, bundle the library with your application:

MyApp.app/
β”œβ”€β”€ Contents/
β”‚   β”œβ”€β”€ MacOS/
β”‚   β”‚   └── MyApp
β”‚   └── Frameworks/
β”‚       └── helper.dylib  ← Bundle the library

Runtime Loading with Validation

If optional library support is needed, load at runtime with validation:

#include <dlfcn.h>

void *handle = dlopen("/path/to/lib.dylib", RTLD_LAZY);
if (handle) {
    // Validate the library before using
    // Check code signature, etc.
}

Xcode

Check Link Binary With Libraries and remove any libraries marked as "Optional".

When to Suppress

This rule may be suppressed for:

  • Plugin systems: Intentionally optional features
  • SDK compatibility: Supporting systems without certain frameworks
  • iOS: iOS's strict code signing mitigates this attack

Platform Notes

  • macOS: Primary concern; attackers can place files
  • iOS: Less concerning due to code signing and sandboxing
  • Hardened Runtime: Mitigates but doesn't eliminate the risk
  • AD5006 - Symbol namespace security

References