Repository navigation
[0.0.5] fix: Python venv, package list and dependency tree for setup.py repos (TC-7405) - #492
Merged
Merged
Conversation
Collaborator
Author
|
/retest |
2 similar comments
Collaborator
Author
|
/retest |
Collaborator
Author
|
/retest |
Collaborator
Author
|
/retest |
Collaborator
Author
|
/retest |
Collaborator
Author
|
/retest |
Collaborator
Author
|
/e2e-test |
Collaborator
Author
|
/retest |
Collaborator
Author
|
/e2e-test |
Collaborator
Author
|
/e2e-test |
Collaborator
Author
|
/test-e2e |
Collaborator
Author
|
/retest |
Collaborator
Author
|
/test-e2e |
Collaborator
Author
|
/retest |
Collaborator
Author
|
/test-e2e |
Collaborator
Author
|
/retest |
Collaborator
Author
|
/test-e2e |
2 similar comments
Collaborator
Author
|
/test-e2e |
Collaborator
Author
|
/test-e2e |
…apply (RHEcosystemAppEng#456) * fix: install deptree with --no-config so agent uv constraints do not apply Python dependency trees fell back to requirements.txt ("Using requirements.txt fallback for dependency tree (2 packages)"): the deptree install uv pip install 'setuptools<81' deptree --python <repo>/transitive_env/bin/python runs from /workspace, so uv applies the agent's own [tool.uv] constraint-dependencies (setuptools>=84.0.0, added in RHEcosystemAppEng#372) to the analyzed repo's venv and fails with "Because you require setuptools<81 and setuptools>=84.0.0, we can conclude that your requirements are unsatisfiable". bin/deptree is never created. run_command ignores the exit code and logs "Successfully ran command", with stderr only at DEBUG, so the failure was silent. Found by the live E2E (Python case, CVE-2024-49767), whose log scan flags ERROR lines. Pass --no-config. Verified: from a directory with the agent pyproject.toml the install fails and bin/deptree is missing; with --no-config it installs. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> * fix: pass --no-config to the other uv pip install calls that run from /workspace Same root cause as the deptree install: uv applies the agent's own [tool.uv] constraint-dependencies (urllib3>=2.8.0, click>=8.3.3, protobuf>=5.29.6, orjson>=3.11.6, setuptools>=84.0.0) to the analyzed repo's venv, so packages the repo pins lower fail with "No solution found". Reproduced with real uv: urllib3==1.26.5, click==7.1.2, protobuf==3.20.1, orjson==3.9.0 and requests==2.25.0 (needs urllib3<1.27) fail; with --no-config they install. Calls changed: install_dependency (requirements.txt, per line), and the "uv pip install -r -" calls for lock-file and Pipfile repos. "uv pip install ." keeps cwd=<repo>, where uv reads no agent config (verified: installs the repo's exact pins). Co-Authored-By: Claude Sonnet 5.5 <[email protected]> --------- Co-authored-by: Claude Sonnet 5.5 <[email protected]> (cherry picked from commit 4da701a)
…HEcosystemAppEng#457) The agent ran uv export --format requirements-txt no-dev 2>/dev/null through run_command (args list, no shell). uv exits 2 with "error: unexpected argument 'no-dev' found" and no output, run_command returns "" (not None), and the code then runs "uv pip install -r -" with empty input and reports the lock file as installed. Repos with a uv.lock therefore installed nothing. Use "uv export --format requirements-txt --no-dev". Verified with real uv: the old command exits 2; the fixed command exports the locked pins. Not changed: for poetry.lock repos "uv export" fails with "No `project` table found" (a classic Poetry project is not a uv project), and the pipenv call has the same literal "2>/dev/null" argument. Co-authored-by: Claude Sonnet 5.5 <[email protected]> (cherry picked from commit 61c79aa)
…p.py repos (TC-7405) A scan of pyyaml 5.3 (CVE-2020-14343) ended as UNKNOWN/uncertain because every Python dependency step failed, and the failures were silent: - determine_python_version() returns "2.7" for python_requires='>=2.7, !=3.0.*, ...'. `uv venv --python 2.7` fails ("Python <3.7 is not supported") and no venv is created. _ensure_venv now retries with the current interpreter when the venv is missing after the first attempt, and logs an error when both attempts fail. - run_command ignored the exit code and logged "Successfully ran command". A non-zero exit now logs a WARNING with the exit code and stderr. stdout is still returned, so callers keep their behavior. - installed_packages.txt was built with transitive_env/bin/pip, which `uv venv` never creates. It now uses `uv pip list --format=freeze`. - build_tree opened requirements.txt unconditionally and raised FileNotFoundError for repos with only setup.py/setup.cfg/pyproject.toml. Without requirements.txt, the direct dependencies now come from the Requires-Dist of the repo's own distribution in transitive_env (found by its PEP 610 direct_url.json, under lib or lib64). - The re-key to import names took the first line of top_level.txt, so pyyaml ("_yaml", "yaml") became "_yaml". It now prefers the module named like the distribution, then the first public module, and reads top_level.txt from transitive_env before the agent's own environment. Verified in quay.io/ecosystem-appeng/exploit-iq-agent:0.0.5 with the changed dep_tree.py mounted, from /workspace: the venv is created with Python 3.12, installed_packages.txt holds pyyaml==5.3, deptree runs and the tree has "yaml". Co-Authored-By: Claude Opus 5.5 <[email protected]>
…est (TC-7405) pyyaml 5.3 declares a broad python_requires and has no requirements.txt. The case is expected to be vulnerable (unsafe full_load/FullLoader). Co-Authored-By: Claude Opus 5.5 <[email protected]>
The E2E log scan treats a WARNING line that contains "error" as a failure. Tools print "error:" to stderr even for expected non-zero exits (npm ls), so the WARNING now names only the command and exit code; stderr stays at DEBUG. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…de the repo (TC-7405) The integration test on PR 492 failed the pyyaml 5.3 case (label false_positive, "pyyaml not found in dependencies"). The engine passes the repo as a path relative to /workspace (.cache/am_cache/git/...), and _ensure_venv returned a relative venv python. `uv pip install . --python <venv python>` runs with cwd=<repo>, so uv looked the path up inside the repo and failed with "No virtual environment or system Python installation found for path"; pyyaml was never installed and installed_packages.txt stayed empty. _ensure_venv now returns an absolute path. The real-uv test now passes the repo as a relative path from the agent directory, as the engine does; it failed before this change. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…own directory has a version (TC-7405) The pyyaml 5.3 case (CVE-2020-14343) still failed the integration test on PR 492 with false_positive: "Version check completed - 1 package(s) matched but none are vulnerable ... stdlib:None (unknown)". pyyaml has only setup.py, so `uv pip install .` installs pyyaml itself into transitive_env, and `uv pip freeze` prints it as "pyyaml @ file:///..." without a version. parse_python_venv skipped such lines, so the version check found no pyyaml and fell back to the stdlib check. It now runs `uv pip list --format=freeze`, which prints "pyyaml==5.3". Verified with real uv: freeze prints "pyyaml @ file:///tmp/...", list prints "pyyaml==5.3". The real-uv pyyaml test now also checks parse_python_venv. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…o is the vulnerable Python package (TC-7405) The pyyaml 5.3 scan (CVE-2020-14343) ended as code_not_reachable once the dependency steps worked: every Call Chain Analyzer query was negative. - chain_of_calls_retriever: "PyYAML,yaml.full_load" read the module name "yaml" as a class name and logged "Cannot find initial function=full_load". For Python only, when the class lookup finds nothing and the qualifier is the package or one of its modules, look the function up without a class. - dep_tree: the repo is pyyaml itself, and its own distribution had no parent ("yaml" -> []), so repo code that calls it (examples/yaml-highlight/yaml_hl.py) was never searched. List the repo's own distribution with its Requires-Dist, so it becomes a child of root_project. - python_functions_parser: Python 3 cannot parse the Python 2 sources in pyyaml's lib/; the SyntaxError failed the whole query. Such a caller is not a caller. Co-Authored-By: Claude Opus 5.5 <[email protected]>
tmihalac
force-pushed
the
fix-TC-7405-0.0.5
branch
from
November 5, 2026 18:20
69d015d to
208da33
Compare
Collaborator
Author
|
/retest |
|
All PipelineRuns for this commit have already succeeded. Use |
Collaborator
Author
|
/test |
Collaborator
Author
|
/test-e2e |
Collaborator
Author
|
/test |
Collaborator
Author
|
/test vulnerability-analysis-on-pr |
Collaborator
Author
|
/test-e2e |
Collaborator
Author
|
/test |
Collaborator
Author
|
/test-e2e |
1 similar comment
Collaborator
Author
|
/test-e2e |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
TC-7405: a scan of
yaml/pyyamlat 5.3 (965d8070, CVE-2020-14343) ends as UNKNOWN/uncertain instead of vulnerable. Every Python dependency step fails, andrun_commandhides the failures:The ticket also says
uvis missing from the image. That is not the case forquay.io/ecosystem-appeng/exploit-iq-agent:0.0.5:uv 0.7.15is at/usr/bin/uv, andshutil.which("uv")finds it.Causes and changes
All reproduced in
exploit-iq-agent:0.0.5, run from/workspacewith an arbitrary UID.python_requires='>=2.7, !=3.0.*, ...', sodetermine_python_version()returns2.7.uv venv --python 2.7fails withPython <3.7 is not supported but 2.7 was requestedand no venv is created. Change:_ensure_venvretries with the current interpreter when the venv is still missing, and logs an error when both attempts fail.run_commandloggedSuccessfully ran commandfor every command and put stderr at DEBUG. Change: a non-zero exit logs a WARNING with the exit code; stderr stays at DEBUG, because the E2E log scan treats WARNING lines that contain "error" as failures andnpm lsprintserror:on expected exits. stdout is still returned, so callers behave as before.bin/pip.uv venvdoes not install pip, soinstalled_packages.txtwas never written. Change: useuv pip list --format=freeze --python <venv python>./workspace, uv reads the agent's[tool.uv] constraint-dependencies(setuptools>=84.0.0), which conflicts withsetuptools<81, so deptree is never installed. Change: backport of fix: install deptree with --no-config so agent uv constraints do not apply #456 (--no-config) and fix: use --no-dev (and no shell redirect) in the lock-file uv export #457 (uv export ... --no-dev, no shell redirect), cherry-picked with-x. The fix: install deptree with --no-config so agent uv constraints do not apply #456 conflict is resolved by keepingpython -m deptree, which works on 0.0.5.requirements.txtcrash.build_treeopened it unconditionally. Change: withoutrequirements.txt, the direct dependencies come fromRequires-Distof the repo's own distribution intransitive_env.uv pip install .installs that distribution, and its PEP 610direct_url.jsonpoints at the repo. The lookup searches bothlibandlib64, because RHEL installs platform wheels underlib64(pyyaml does). Lock-file and Pipfile repos get no direct dependencies marked, and they no longer crash.top_level.txt, so pyyaml (_yaml,yaml) became_yaml. Change: prefer the module named like the distribution, then the first public module. Also readtop_level.txtfromtransitive_envbefore the agent's own environment.Verification
test_python_build_tree.py: 26 pass. Each new test failed before the change.test_python_dep_tree_real_uv.pyclones pyyaml at965d8070and runs the realinstall_dependencies()andbuild_tree()with real uv from the agent directory. It fails on the old code (no venv) and passes now. It skips when uv or git is missing or the clone fails.dep_tree.pymounted: the venv is created with Python 3.12 after the 2.7 attempt fails (logged),installed_packages.txtispyyaml==5.3, deptree runs, and the tree hasyaml, not_yaml.ci/it/integration-tests-input.json.0.0.5has no E2E workflows orscripts/e2e: the GitHub Kustomize E2E of this PR checks out its workflow, harness and fixture frommain(run log of [0.0.5] ci: build release-branch images (backport of #474 and #477) #491:+88d7a8ec...:refs/remotes/origin/main). The E2E test for this scenario (a dedicated step that runs the pyyaml case and checks the engine log withcheck_python_dependency_logs.py) is therefore added onmainin fix: Python venv, package list and dependency tree for setup.py repos (TC-7405) #493, and in the operator OLM E2E in test(e2e): pyyaml 5.3 setup.py-only case with engine log check in the OLM E2E (TC-7405) exploit-iq-operator#331. After fix: Python venv, package list and dependency tree for setup.py repos (TC-7405) #493 merges,/test-e2eon this PR runs it against this PR's agent image.vulnerableverdict is not verified here. The integration test on this PR checks it.🤖 Generated with Claude Code