Insufficient Isolation of System-Dependent Functions
Description
Insufficient Isolation of System-Dependent Functions occurs when a product fails to isolate system-dependent functionality into separate, standalone modules. This design weakness results in system-specific code being scattered throughout the application rather than being centralized in abstraction layers. When code that depends on specific operating systems, hardware, or runtime environments is not properly isolated, it becomes difficult to port the software, maintain it, and ensure consistent security behavior across platforms.
Risk
Failure to isolate system-dependent code has indirect security implications. Platform-specific security mechanisms may be implemented inconsistently across the codebase. Security fixes for platform-specific issues must be applied in multiple places. Porting to new platforms may introduce security vulnerabilities if system dependencies are not clearly identified. Testing security across platforms becomes more difficult. Code review for security is complicated by scattered platform-specific code. Security-sensitive operations like file permissions, process execution, and cryptography may behave differently on different platforms.
Solution
Create abstraction layers that encapsulate system-dependent functionality. Use interface or abstract class patterns to define platform-independent APIs. Implement platform-specific code in dedicated modules that implement these interfaces. Apply the dependency inversion principle to depend on abstractions rather than concrete implementations. Use configuration or factory patterns to select appropriate implementations. Centralize platform detection logic. Follow established patterns like the Bridge pattern for platform abstraction. Document platform dependencies clearly. Test on all supported platforms.
Common Consequences
| Impact | Details |
|---|---|
| Other | Scope: Other Reduce Maintainability - Scattered platform-specific code is harder to maintain. |
| Other | Scope: Other Reduce Portability - Difficult to port to new platforms or environments. |
| Integrity | Scope: Integrity Inconsistent Behavior - May behave differently on different platforms unexpectedly. |
Example Code
Vulnerable Code
// Vulnerable: System-dependent code scattered throughout
public class VulnerableFileManager {
public void createSecureFile(String path, String content) {
// Vulnerable: OS-specific code mixed with business logic
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
// Windows-specific file creation
try {
Path filePath = Paths.get(path);
Files.write(filePath, content.getBytes());
// Windows ACL handling scattered here
AclFileAttributeView aclView = Files.getFileAttributeView(
filePath, AclFileAttributeView.class);
// Set Windows permissions...
} catch (IOException e) {
throw new RuntimeException(e);
}
} else if (osName.contains("linux") || osName.contains("mac")) {
// Unix-specific file creation
try {
Path filePath = Paths.get(path);
Files.write(filePath, content.getBytes());
// Unix permissions scattered here
Set<PosixFilePermission> perms = EnumSet.of(
PosixFilePermission.OWNER_READ,
PosixFilePermission.OWNER_WRITE);
Files.setPosixFilePermissions(filePath, perms);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public String getConfigPath() {
// Vulnerable: More OS checks scattered throughout
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
return System.getenv("APPDATA") + "\\MyApp\\config.ini";
} else if (osName.contains("mac")) {
return System.getProperty("user.home") + "/Library/MyApp/config.ini";
} else {
return System.getProperty("user.home") + "/.myapp/config.ini";
}
}
public void executeCommand(String command) {
// Vulnerable: Platform-specific execution mixed with business logic
String osName = System.getProperty("os.name").toLowerCase();
try {
Process process;
if (osName.contains("windows")) {
process = Runtime.getRuntime().exec("cmd.exe /c " + command);
} else {
process = Runtime.getRuntime().exec("/bin/sh -c " + command);
}
process.waitFor();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
# Vulnerable: Platform-specific code mixed throughout
import os
import sys
import platform
class VulnerableSystemService:
def get_temp_directory(self):
# Vulnerable: Platform check scattered in method
if sys.platform == 'win32':
return os.environ.get('TEMP', 'C:\\Temp')
elif sys.platform == 'darwin':
return '/tmp'
else:
return '/tmp'
def set_file_permissions(self, path, mode):
# Vulnerable: Platform-specific permission handling
if sys.platform == 'win32':
# Windows doesn't support chmod - use icacls
import subprocess
subprocess.run(['icacls', path, '/grant', 'Users:R'], check=True)
else:
os.chmod(path, mode)
def get_username(self):
# Vulnerable: Different approaches for different platforms
if sys.platform == 'win32':
return os.environ.get('USERNAME', 'unknown')
else:
import pwd
return pwd.getpwuid(os.getuid()).pw_name
def open_browser(self, url):
# Vulnerable: Platform-specific browser opening
if sys.platform == 'win32':
os.startfile(url)
elif sys.platform == 'darwin':
os.system(f'open "{url}"')
else:
os.system(f'xdg-open "{url}"')
def get_line_ending(self):
# Vulnerable: Line endings scattered throughout code
if sys.platform == 'win32':
return '\r\n'
else:
return '\n'
// Vulnerable: Platform code scattered throughout C# application
public class VulnerablePathManager
{
public string GetAppDataPath()
{
// Vulnerable: Platform checks mixed with business logic
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
"Library", "Application Support");
}
else
{
return Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".config");
}
}
public void CreateHiddenFile(string path)
{
// Vulnerable: More platform-specific code
File.Create(path).Close();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
File.SetAttributes(path, FileAttributes.Hidden);
}
// On Unix, file is hidden by starting name with '.'
// This logic is now split across creation and naming
}
public string GetPathSeparator()
{
// Vulnerable: Platform-specific path handling scattered
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "\\" : "/";
}
}
Fixed Code
// Fixed: Platform-specific code isolated in abstraction layer
// Platform-independent interface
public interface FileSystemService {
void createSecureFile(String path, String content) throws IOException;
String getConfigPath();
void executeCommand(String command) throws IOException;
}
// Windows implementation
public class WindowsFileSystemService implements FileSystemService {
@Override
public void createSecureFile(String path, String content) throws IOException {
Path filePath = Paths.get(path);
Files.write(filePath, content.getBytes());
// Windows-specific ACL handling in one place
AclFileAttributeView aclView = Files.getFileAttributeView(
filePath, AclFileAttributeView.class);
configureWindowsAcl(aclView);
}
@Override
public String getConfigPath() {
return System.getenv("APPDATA") + "\\MyApp\\config.ini";
}
@Override
public void executeCommand(String command) throws IOException {
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", command);
pb.inheritIO();
Process process = pb.start();
try {
process.waitFor();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
private void configureWindowsAcl(AclFileAttributeView aclView) {
// Windows-specific ACL configuration
}
}
// Unix implementation
public class UnixFileSystemService implements FileSystemService {
@Override
public void createSecureFile(String path, String content) throws IOException {
Path filePath = Paths.get(path);
Files.write(filePath, content.getBytes());
// Unix permissions in one place
Set<PosixFilePermission> perms = EnumSet.of(
PosixFilePermission.OWNER_READ,
PosixFilePermission.OWNER_WRITE);
Files.setPosixFilePermissions(filePath, perms);
}
@Override
public String getConfigPath() {
String home = System.getProperty("user.home");
return home + "/.myapp/config.ini";
}
@Override
public void executeCommand(String command) throws IOException {
ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", command);
pb.inheritIO();
Process process = pb.start();
try {
process.waitFor();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
// macOS implementation (extends Unix with overrides as needed)
public class MacOSFileSystemService extends UnixFileSystemService {
@Override
public String getConfigPath() {
String home = System.getProperty("user.home");
return home + "/Library/MyApp/config.ini";
}
}
// Factory to create appropriate implementation
public class FileSystemServiceFactory {
public static FileSystemService create() {
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
return new WindowsFileSystemService();
} else if (osName.contains("mac")) {
return new MacOSFileSystemService();
} else {
return new UnixFileSystemService();
}
}
}
// Business logic uses abstraction
public class FixedFileManager {
private final FileSystemService fileSystem;
public FixedFileManager() {
this.fileSystem = FileSystemServiceFactory.create();
}
// Constructor injection for testing
public FixedFileManager(FileSystemService fileSystem) {
this.fileSystem = fileSystem;
}
public void createSecureFile(String path, String content) {
try {
// Platform-independent code
fileSystem.createSecureFile(path, content);
} catch (IOException e) {
throw new RuntimeException("Failed to create secure file", e);
}
}
public String getConfigPath() {
return fileSystem.getConfigPath();
}
}
# Fixed: Platform abstraction layer in Python
from abc import ABC, abstractmethod
import os
import sys
from typing import Optional
# Platform-independent interface
class PlatformService(ABC):
@abstractmethod
def get_temp_directory(self) -> str:
pass
@abstractmethod
def set_file_permissions(self, path: str, mode: int) -> None:
pass
@abstractmethod
def get_username(self) -> str:
pass
@abstractmethod
def open_url(self, url: str) -> None:
pass
@property
@abstractmethod
def line_ending(self) -> str:
pass
# Windows implementation
class WindowsPlatformService(PlatformService):
def get_temp_directory(self) -> str:
return os.environ.get('TEMP', 'C:\\Temp')
def set_file_permissions(self, path: str, mode: int) -> None:
import subprocess
# Map Unix mode to Windows permissions
if mode & 0o444: # Readable
subprocess.run(['icacls', path, '/grant', 'Users:R'],
check=True, capture_output=True)
def get_username(self) -> str:
return os.environ.get('USERNAME', 'unknown')
def open_url(self, url: str) -> None:
os.startfile(url)
@property
def line_ending(self) -> str:
return '\r\n'
# Unix implementation
class UnixPlatformService(PlatformService):
def get_temp_directory(self) -> str:
return os.environ.get('TMPDIR', '/tmp')
def set_file_permissions(self, path: str, mode: int) -> None:
os.chmod(path, mode)
def get_username(self) -> str:
import pwd
return pwd.getpwuid(os.getuid()).pw_name
def open_url(self, url: str) -> None:
import subprocess
subprocess.run(['xdg-open', url], check=True)
@property
def line_ending(self) -> str:
return '\n'
# macOS implementation
class MacOSPlatformService(UnixPlatformService):
def open_url(self, url: str) -> None:
import subprocess
subprocess.run(['open', url], check=True)
# Factory
class PlatformServiceFactory:
@staticmethod
def create() -> PlatformService:
if sys.platform == 'win32':
return WindowsPlatformService()
elif sys.platform == 'darwin':
return MacOSPlatformService()
else:
return UnixPlatformService()
# Business logic uses abstraction
class FixedSystemService:
"""Platform-independent system service."""
def __init__(self, platform_service: Optional[PlatformService] = None):
self._platform = platform_service or PlatformServiceFactory.create()
def get_temp_directory(self) -> str:
return self._platform.get_temp_directory()
def set_file_permissions(self, path: str, mode: int) -> None:
self._platform.set_file_permissions(path, mode)
def get_username(self) -> str:
return self._platform.get_username()
def open_url(self, url: str) -> None:
self._platform.open_url(url)
def write_text_file(self, path: str, content: str) -> None:
"""Write text file with correct line endings."""
with open(path, 'w', newline=self._platform.line_ending) as f:
f.write(content)
// Fixed: Platform abstraction in C#
// Platform-independent interface
public interface IPlatformService
{
string GetAppDataPath();
void CreateHiddenFile(string path, string content);
string PathSeparator { get; }
string NormalizePath(string path);
}
// Windows implementation
public class WindowsPlatformService : IPlatformService
{
public string GetAppDataPath()
{
return Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
}
public void CreateHiddenFile(string path, string content)
{
File.WriteAllText(path, content);
File.SetAttributes(path, File.GetAttributes(path) | FileAttributes.Hidden);
}
public string PathSeparator => "\\";
public string NormalizePath(string path)
{
return path.Replace("/", "\\");
}
}
// Unix/Linux implementation
public class UnixPlatformService : IPlatformService
{
public string GetAppDataPath()
{
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
return Path.Combine(home, ".config");
}
public void CreateHiddenFile(string path, string content)
{
// On Unix, hidden files start with '.'
var dir = Path.GetDirectoryName(path);
var name = Path.GetFileName(path);
var hiddenPath = Path.Combine(dir, "." + name.TrimStart('.'));
File.WriteAllText(hiddenPath, content);
}
public string PathSeparator => "/";
public string NormalizePath(string path)
{
return path.Replace("\\", "/");
}
}
// macOS implementation
public class MacOSPlatformService : UnixPlatformService
{
public new string GetAppDataPath()
{
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
return Path.Combine(home, "Library", "Application Support");
}
}
// Factory using dependency injection pattern
public static class PlatformServiceFactory
{
public static IPlatformService Create()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return new WindowsPlatformService();
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
return new MacOSPlatformService();
return new UnixPlatformService();
}
}
// Business logic with dependency injection
public class FixedPathManager
{
private readonly IPlatformService _platform;
public FixedPathManager(IPlatformService platform)
{
_platform = platform;
}
public string GetAppDataPath() => _platform.GetAppDataPath();
public void CreateHiddenFile(string path, string content)
{
_platform.CreateHiddenFile(path, content);
}
public string BuildPath(params string[] segments)
{
return string.Join(_platform.PathSeparator, segments);
}
}
CVE Examples
This CWE is allowed for vulnerability mapping, as insufficient platform abstraction can lead to security inconsistencies across platforms.
Related CWEs
- CWE-1061: Insufficient Encapsulation (parent)
- CWE-1227: Encapsulation Issues (category member)
- CWE-1102: Reliance on Machine-Dependent Data Representation (related)
References
- MITRE Corporation. "CWE-1100: Insufficient Isolation of System-Dependent Functions." https://cwe.mitre.org/data/definitions/1100.html
- Martin, Robert C. "Clean Architecture" - Dependency Rule.
- Gamma et al. "Design Patterns" - Bridge Pattern.