{"adoption": {"forks": 91, "observed_at": "2026-08-28T04:03:29.235045+00:00", "stars": 1075}, "canonical_url": "https://ross.abutalabs.com/products/anamorpher", "card": {"archived": false, "artifact_type": "application", "description": "image scaling attacks for multi-modal prompt injection", "domain": ["security", "machine-learning", "artificial-intelligence", "image-processing", "penetration-testing"], "enriched": true, "function": ["image-processing", "security", "penetration-testing", "machine-learning", "gui"], "health_score": 70, "homepage": null, "language": "Python", "license": "Apache-2.0", "license_family": "permissive", "maturity": "active", "member_repos": ["trailofbits/anamorpher"], "name": "trailofbits/anamorpher", "platform": ["python"], "pushed_at": "2026-05-19T20:12:03+00:00", "repo": "trailofbits/anamorpher", "stars": 1075, "tags": ["adversarial-ml", "prompt-injection", "image-scaling-attack", "multimodal-ai", "red-team", "attack-tool", "linux", "macos", "web-server"], "topics": [], "urls": [], "use_cases": ["generate images that hide prompt injection payloads revealed on downscaling", "test whether a multimodal AI system is vulnerable to image scaling attacks", "compare bicubic, bilinear, and nearest neighbor downscaling implementations for attack susceptibility", "evaluate payload effectiveness across OpenCV, PyTorch, TensorFlow, and Pillow scaling", "research adversarial preprocessing attacks on vision-language models", "build custom downscaling implementations to test with the Python API"], "what_it_is": "Anamorpher is a tool for crafting and visualizing image scaling attacks that hide multi-modal prompt injections in images, revealed only when the image is downscaled. It provides a web frontend for comparing payload effectiveness across downscaling implementations (OpenCV, PyTorch, TensorFlow, Pillow) and a modular Python API for custom scaling implementations.", "when_to_avoid": ["you need general-purpose image resizing or editing rather than attack payload generation", "you need a production-ready, stable tool - it is in active beta with probabilistic results", "your environment is Windows without WSL2, due to TensorFlow dependencies"], "when_to_choose": ["red-teaming or security-testing multimodal AI systems against image scaling prompt injection", "researching image-scaling attack vectors described in the Trail of Bits blog post", "you need a visual interface to compare downscaling algorithm behavior on adversarial images"]}, "data_as_of": "2026-08-30T08:39:29.467469+00:00", "members": [{"path": "/products/anamorpher", "repo": "trailofbits/anamorpher", "role": "main", "score": 55}], "provenance": {"archived": {"kind": "observed", "observed_at": "2026-08-28T04:03:29.235045+00:00", "source": "github"}, "artifact_type": {"confidence": null, "enriched_at": "2026-08-30T06:53:28.642949+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "eadfea653b3926ee4e04defee8aa45e5658b5a90350aee0749d8c6db069215e7", "fetched_at": "2026-08-28T04:03:29.235045+00:00", "kind": "readme", "missing": false, "url": "https://github.com/trailofbits/anamorpher"}], "taxonomy_version": 1}, "description": {"kind": "observed", "observed_at": "2026-08-28T04:03:29.235045+00:00", "source": "github"}, "domain": {"confidence": null, "enriched_at": "2026-08-30T06:53:28.642949+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "eadfea653b3926ee4e04defee8aa45e5658b5a90350aee0749d8c6db069215e7", "fetched_at": "2026-08-28T04:03:29.235045+00:00", "kind": "readme", "missing": false, "url": "https://github.com/trailofbits/anamorpher"}], "taxonomy_version": 1}, "enriched": {"inputs": [], "kind": "computed", "method": "enrichment_status"}, "function": {"confidence": null, "enriched_at": "2026-08-30T06:53:28.642949+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "eadfea653b3926ee4e04defee8aa45e5658b5a90350aee0749d8c6db069215e7", "fetched_at": "2026-08-28T04:03:29.235045+00:00", "kind": "readme", "missing": false, "url": "https://github.com/trailofbits/anamorpher"}], "taxonomy_version": 1}, "health_score": {"inputs": ["days_since_push", "days_since_release", "archived"], "kind": "computed", "method": "health_v1"}, "homepage": {"kind": "observed", "observed_at": "2026-08-28T04:03:29.235045+00:00", "source": "github"}, "language": {"kind": "observed", "observed_at": "2026-08-28T04:03:29.235045+00:00", "source": "github"}, "license": {"kind": "observed", "observed_at": "2026-08-28T04:03:29.235045+00:00", "source": "github"}, "license_family": {"inputs": ["license"], "kind": "computed", "method": "license_family"}, "maturity": {"confidence": null, "enriched_at": "2026-08-30T06:53:28.642949+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "eadfea653b3926ee4e04defee8aa45e5658b5a90350aee0749d8c6db069215e7", "fetched_at": "2026-08-28T04:03:29.235045+00:00", "kind": "readme", "missing": false, "url": "https://github.com/trailofbits/anamorpher"}], "taxonomy_version": 1}, "member_repos": {"kind": "observed", "observed_at": "2026-08-28T04:03:29.235045+00:00", "source": "github"}, "name": {"kind": "observed", "observed_at": "2026-08-28T04:03:29.235045+00:00", "source": "github"}, "platform": {"confidence": null, "enriched_at": "2026-08-30T06:53:28.642949+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "eadfea653b3926ee4e04defee8aa45e5658b5a90350aee0749d8c6db069215e7", "fetched_at": "2026-08-28T04:03:29.235045+00:00", "kind": "readme", "missing": false, "url": "https://github.com/trailofbits/anamorpher"}], "taxonomy_version": 1}, "pushed_at": {"kind": "observed", "observed_at": "2026-08-28T04:03:29.235045+00:00", "source": "github"}, "repo": {"kind": "observed", "observed_at": "2026-08-28T04:03:29.235045+00:00", "source": "github"}, "stars": {"kind": "observed", "observed_at": "2026-08-28T04:03:29.235045+00:00", "source": "github"}, "tags": {"confidence": null, "enriched_at": "2026-08-30T06:53:28.642949+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "eadfea653b3926ee4e04defee8aa45e5658b5a90350aee0749d8c6db069215e7", "fetched_at": "2026-08-28T04:03:29.235045+00:00", "kind": "readme", "missing": false, "url": "https://github.com/trailofbits/anamorpher"}], "taxonomy_version": 1}, "topics": {"kind": "observed", "observed_at": "2026-08-28T04:03:29.235045+00:00", "source": "github"}, "urls": {"kind": "observed", "observed_at": "2026-08-28T04:03:29.235045+00:00", "source": "github"}, "use_cases": {"confidence": null, "enriched_at": "2026-08-30T06:53:28.642949+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "eadfea653b3926ee4e04defee8aa45e5658b5a90350aee0749d8c6db069215e7", "fetched_at": "2026-08-28T04:03:29.235045+00:00", "kind": "readme", "missing": false, "url": "https://github.com/trailofbits/anamorpher"}], "taxonomy_version": 1}, "what_it_is": {"confidence": null, "enriched_at": "2026-08-30T06:53:28.642949+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "eadfea653b3926ee4e04defee8aa45e5658b5a90350aee0749d8c6db069215e7", "fetched_at": "2026-08-28T04:03:29.235045+00:00", "kind": "readme", "missing": false, "url": "https://github.com/trailofbits/anamorpher"}], "taxonomy_version": 1}, "when_to_avoid": {"confidence": null, "enriched_at": "2026-08-30T06:53:28.642949+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "eadfea653b3926ee4e04defee8aa45e5658b5a90350aee0749d8c6db069215e7", "fetched_at": "2026-08-28T04:03:29.235045+00:00", "kind": "readme", "missing": false, "url": "https://github.com/trailofbits/anamorpher"}], "taxonomy_version": 1}, "when_to_choose": {"confidence": null, "enriched_at": "2026-08-30T06:53:28.642949+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "eadfea653b3926ee4e04defee8aa45e5658b5a90350aee0749d8c6db069215e7", "fetched_at": "2026-08-28T04:03:29.235045+00:00", "kind": "readme", "missing": false, "url": "https://github.com/trailofbits/anamorpher"}], "taxonomy_version": 1}}, "score": {"components": {"activity": 83, "longevity": 27, "rhythm": 35}, "computed_at": "2026-09-03T02:20:16.233290+00:00", "flags": ["no_releases"], "formula": "round(0.45*activity + 0.35*rhythm + 0.20*longevity); archived -> min(score, 10)", "inputs": {"age_days": 378, "days_push": 106, "days_rel": null, "gap_med": null, "n_releases_24m": 0}, "score": 55, "version": 2}, "staleness": {"enrichment_outdated": false, "low_confidence": false, "scrape_days": 9, "stale_scrape": false}}