Skip to content

fix: sanitize shell/subprocess call in odmOptionsToJson.py (CWE-78) - #4

Closed
anupamme wants to merge 1 commit into
WebODM:masterfrom
anupamme:fix-repo-nodeodx-odmoptions-path-sanitization
Closed

anupamme wants to merge 1 commit into
WebODM:masterfrom
anupamme:fix-repo-nodeodx-odmoptions-path-sanitization

Conversation

@anupamme

Copy link
Copy Markdown

The helpers/odmOptionsToJson.py script uses sys.argv[2] directly in sys.path.append() and os.path.join() operations without any sanitization. An attacker who can control the command-line arguments passed to this script can inject malicious paths, potentially leading to arbitrary code execution when Python modules are loaded from attacker-controlled directories. The affected code is helpers/odmOptionsToJson.py:40. This change is the fix I would apply.

Reference: CWE-78

What changed

  • helpers/odmOptionsToJson.py

Verification

No automated check could be run against this repository, so this change is unverified beyond review. Please treat it as a suggestion.

Regression test

The security boundary is maintained under adversarial input

Test
import pytest
import subprocess
import sys
import os


@pytest.mark.parametrize("payload", [
    "../../../malicious",  # path traversal exploit
    "..",                  # boundary: minimal traversal
    "/valid/path",         # valid absolute path (should not crash)
])
def test_argv2_path_sanitization(payload, tmp_path):
    """Invariant: sys.argv[2] must not be used to load code from attacker-controlled paths without validation"""
    # Create a mock directory structure to test path resolution
    malicious_dir = tmp_path / "malicious"
    malicious_dir.mkdir()
    
    # Write a detectable payload module
    (malicious_dir / "modules").mkdir()
    (malicious_dir / "modules" / "__init__.py").write_text(
        "import sys; sys.exit(42)  # Signal: arbitrary code executed"
    )
    
    # Build the actual path traversal target
    if payload.startswith(".."):
        # Resolve relative to tmp_path to make traversal work
        test_path = os.path.join(tmp_path, payload, "malicious")
    else:
        test_path = str(malicious_dir) if "malicious" in payload else payload
    
    # Run the actual script with adversarial input
    script_path = os.path.join(os.path.dirname(__file__), "..", "helpers", "odmOptionsToJson.py")
    result = subprocess.run(
        [sys.executable, script_path, "dummy", test_path],
        capture_output=True,
        timeout=5
    )
    
    # Security invariant: must not exit with code 42 (arbitrary code execution)
    # and must not successfully load from attacker-controlled path
    assert result.returncode != 42, "Arbitrary code execution via path injection"

Automated security fix by OrbisAI Security

Automated security fix generated by OrbisAI Security
@pierotofy pierotofy closed this Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants