CVE-2013-1629
Insecure package retrieval in pre-1.3 pip allows code execution via crafted response
- CVSS 6.8
- CWE-20 Improper Input Validation
- Cryptographic
- Remote
pip before 1.3 uses HTTP to retrieve packages from the PyPI repository, and does not perform integrity checks on package contents, which allows man-in-the-middle attackers to execute arbitrary code via a crafted response to a "pip install" operation.
- CVSS base score
- 6.8
- Published
- 2013-08-06
- OWASP
- A08 Software and Data Integrity Failures
- Orthogonal defect classification
- Function
- Code defect classification
- Incorrect Functionality
- Category
- Cryptographic
- Subcategory
- Unencrypted communication
- Accessibility scope
- Remote
- Impact
- Arbitrary Code Execution
- Fixed by upgrading
- Yes
Solution
Update pip to version 1.3 or higher.
Vulnerable code sample
import requests
def download_package(package_name, version):
url = f"http://pypi.python.org/pypi/{package_name}/{version}/json"
response = requests.get(url)
response.raise_for_status()
package_info = response.json()
package_url = package_info['urls'][0]['url']
package_response = requests.get(package_url)
package_response.raise_for_status()
with open(f"{package_name}-{version}.whl", "wb") as f:
f.write(package_response.content)
download_package("example-package", "1.0.0")Patched code sample
import os
import re
import hashlib
import tempfile
from typing import Optional
from urllib.parse import urlparse
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
def download_package(
package_name: str,
version: str,
output_dir: Optional[str] = None
) -> str:
try:
if not re.match(r'^[a-zA-Z0-9_-]+$', package_name):
raise ValueError("Invalid package name")
if not re.match(r'^[a-zA-Z0-9_.-]+$', version):
raise ValueError("Invalid version")
session = requests.Session()
retry = Retry(
total=3,
backoff_factor=0.5,
status_forcelist=[500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('https://', adapter)
info_url = f"https://pypi.org/pypi/{package_name}/{version}/json"
response = session.get(info_url, timeout=10)
response.raise_for_status()
info = response.json()
urls = info.get('urls', [])
if not urls:
raise ValueError("No package URLs found")
package_info = None
for url_info in urls:
if url_info['packagetype'] in {'bdist_wheel', 'sdist'}:
package_info = url_info
break
if not package_info:
raise ValueError("No suitable package format found")
package_url = package_info['url']
expected_hash = package_info['digests']['sha256']
parsed_url = urlparse(package_url)
if parsed_url.scheme != 'https' or not parsed_url.netloc.endswith('.pypi.org'):
raise ValueError("Invalid package URL")
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
response = session.get(package_url, stream=True, timeout=30)
response.raise_for_status()
sha256 = hashlib.sha256()
for chunk in response.iter_content(chunk_size=8192):
sha256.update(chunk)
temp_file.write(chunk)
if sha256.hexdigest() != expected_hash:
os.unlink(temp_file.name)
raise ValueError("Package integrity check failed")
output_dir = output_dir or os.getcwd()
output_path = os.path.join(
output_dir,
os.path.basename(package_url)
)
os.replace(temp_file.name, output_path)
return output_path
except requests.exceptions.RequestException as e:
raise ValueError(f"Download failed: {str(e)}")
except Exception as e:
raise ValueError(f"Error downloading package: {str(e)}")Cite this entry
@misc{vaitp:cve20131629,
title = {{Insecure package retrieval in pre-1.3 pip allows code execution via crafted response}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2013},
note = {VAITP Python Vulnerability Dataset, entry CVE-2013-1629},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2013-1629/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
