ansede-static 2.3.0.dev0__tar.gz → 2.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/.gitignore +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/CHANGELOG.md +67 -0
- ansede_static-2.3.2/PKG-INFO +156 -0
- ansede_static-2.3.2/README.md +108 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/pyproject.toml +7 -1
- ansede_static-2.3.2/src/ansede_static/__init__.py +346 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/cache/incremental.py +26 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/cache/sqlite_store.py +1 -1
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/cli.py +537 -37
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/cpg/taint_engine.py +97 -93
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/csharp_analyzer.py +124 -11
- ansede_static-2.3.2/src/ansede_static/dsl/bridge.py +138 -0
- ansede_static-2.3.2/src/ansede_static/dsl/compiler.py +75 -0
- ansede_static-2.3.2/src/ansede_static/dsl/engine.py +143 -0
- ansede_static-2.3.2/src/ansede_static/engine/audit.py +1198 -0
- ansede_static-2.3.2/src/ansede_static/engine/auto_rules.py +344 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/clustering.py +70 -63
- ansede_static-2.3.2/src/ansede_static/engine/llm_triage.py +465 -0
- ansede_static-2.3.2/src/ansede_static/engine/rust_parser.py +217 -0
- ansede_static-2.3.2/src/ansede_static/engine/semgrep_transpiler.py +425 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine_version.py +6 -3
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/go_engine/go_analyzer.py +0 -1
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/go_engine/go_parser.py +29 -11
- ansede_static-2.3.2/src/ansede_static/graph/__init__.py +24 -0
- ansede_static-2.3.2/src/ansede_static/graph/cross_language_taint.py +1071 -0
- ansede_static-2.3.2/src/ansede_static/graph/go_callgraph.py +192 -0
- ansede_static-2.3.2/src/ansede_static/graph/graph_populator.py +96 -0
- ansede_static-2.3.2/src/ansede_static/graph/import_graph.py +304 -0
- ansede_static-2.3.2/src/ansede_static/graph/js_callgraph.py +295 -0
- ansede_static-2.3.2/src/ansede_static/graph/python_callgraph.py +271 -0
- ansede_static-2.3.2/src/ansede_static/graph/sqlite_graph.py +354 -0
- ansede_static-2.3.2/src/ansede_static/graph/unified_source_graph.py +155 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/ir/global_graph.py +93 -31
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/java_analyzer.py +68 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_analyzer.py +12 -5
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_ast_analyzer.py +212 -89
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/common.py +5 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/pattern_rules.py +10 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/pratt/parser.py +32 -9
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/pratt_analyzer.py +101 -72
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/project.py +32 -3
- ansede_static-2.3.2/src/ansede_static/js_engine/project_context.py +297 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/routes.py +44 -17
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/structure.py +17 -4
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/taint_checks.py +13 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/licensing.py +3 -3
- ansede_static-2.3.2/src/ansede_static/profiler.py +98 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/python_analyzer.py +31 -4
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/rules.py +93 -52
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/yaml_rules.py +165 -91
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/conftest.py +3 -1
- ansede_static-2.3.2/tests/test_audit_engine.py +284 -0
- ansede_static-2.3.2/tests/test_auto_rules.py +156 -0
- ansede_static-2.3.2/tests/test_benchmark_ratchet_gate.py +39 -0
- ansede_static-2.3.2/tests/test_benchmark_sink_families.py +73 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_cache.py +80 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_cli.py +134 -1
- ansede_static-2.3.2/tests/test_clustering.py +103 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_community_rules.py +20 -0
- ansede_static-2.3.2/tests/test_dsl_engine.py +128 -0
- ansede_static-2.3.2/tests/test_engine/test_semgrep_transpiler.py +100 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_external_corpus.py +6 -0
- ansede_static-2.3.2/tests/test_final_scorecard.py +85 -0
- ansede_static-2.3.2/tests/test_graph/test_cli_cross_language_e2e.py +106 -0
- ansede_static-2.3.2/tests/test_graph/test_global_graph_bridges.py +62 -0
- ansede_static-2.3.2/tests/test_graph/test_go_callgraph.py +54 -0
- ansede_static-2.3.2/tests/test_graph/test_import_graph.py +78 -0
- ansede_static-2.3.2/tests/test_graph/test_js_callgraph.py +108 -0
- ansede_static-2.3.2/tests/test_graph/test_python_callgraph.py +63 -0
- ansede_static-2.3.2/tests/test_graph/test_unified_source_graph.py +135 -0
- ansede_static-2.3.2/tests/test_integration.py +65 -0
- ansede_static-2.3.2/tests/test_java_csharp_analyzers.py +436 -0
- ansede_static-2.3.2/tests/test_js_minified_project_index.py +53 -0
- ansede_static-2.3.2/tests/test_js_pratt_parser.py +41 -0
- ansede_static-2.3.2/tests/test_js_structure_cache.py +28 -0
- ansede_static-2.3.2/tests/test_perf_dashboard.py +37 -0
- ansede_static-2.3.2/tests/test_quality_benchmark.py +74 -0
- ansede_static-2.3.2/tests/test_sqlite_graph.py +69 -0
- ansede_static-2.3.2/tests/test_tools/__init__.py +0 -0
- ansede_static-2.3.2/tests/test_tools/test_check_binary_guardrails.py +41 -0
- ansede_static-2.3.2/tests/test_tools/test_safe_bounty_bot.py +84 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_triage.py +25 -1
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_web_wild_harness.py +19 -0
- ansede_static-2.3.0.dev0/PKG-INFO +0 -336
- ansede_static-2.3.0.dev0/README.md +0 -288
- ansede_static-2.3.0.dev0/src/ansede_static/__init__.py +0 -183
- ansede_static-2.3.0.dev0/tests/__init__.py +0 -1
- ansede_static-2.3.0.dev0/tests/test_java_csharp_analyzers.py +0 -165
- ansede_static-2.3.0.dev0/tests/test_quality_benchmark.py +0 -29
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/LICENSE +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/_types.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/cache/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/config.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/cpg/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/cpg/builder.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/cpg/graph.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/async_scanner.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/ci_baseline.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/confidence.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/cvss.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/dump_failures.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/explain.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/learning_triage.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/nuclei.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/remediation.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/semgrep_.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/shadow_scan.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/symbolic_guards.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/engine/triage.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/entropy.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/go_engine/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/hardening.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/ir/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/ir/issues.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/ir/stir.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/backends.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/constants.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/context_checks.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/minified_scanner.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/module_resolver.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/pratt/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/pratt/ast_nodes.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/pratt/lexer.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/react.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/source_map_resolver.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/sourcemap_rescanner.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/js_engine/taint.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/lsp_server.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/monorepo.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/php_analyzer.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/pypi_validator.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/aiohttp_web.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/angular_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/api_security.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/archive_extraction_py.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/aspnet_core.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/axios_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/boto3_aws.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/celery.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/cloud_security.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/community.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/cryptography_lib.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/deserialization_py.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/django.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/django_rest.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/express_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/fastapi.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/flask.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/graphql_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/graphql_py.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/jwt_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/jwt_py.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/knex_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/ldap_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/ldap_py.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/loader.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/mongoose_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/mysql2_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/nestjs_framework.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/nextjs_framework.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/nodejs_core.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/pg_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/prisma_orm.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/prototype_pollution_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/pug_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/pydantic.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/pymongo.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/race_condition_py.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/react_frontend.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/redis_py.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/requests_lib.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/second_order_sql.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/sequelize_orm.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/sharded_loader.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/socketio.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/spring_boot.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/sqlalchemy.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/subprocess_lib.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/supply_chain.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/template_engines_py.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/tornado_web.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/typeorm_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/vue_js.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/xml_parsers.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry/yaml_load.yaml +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/registry.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/reporters.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/ruby_analyzer.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/rulesets/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/rulesets/datascience.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/sanitizers.json +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/sarif_validator.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/sbom.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/schema.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/schemas/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/schemas/ansede.schema.json +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/taint_specs.json +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/template_transpiler.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/baseline.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/call_graph.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/engine.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/ifds.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/interprocedural_taint.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/model.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/nodes.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/normalizer.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rule_protocol.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/javascript/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/javascript/crypto.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/javascript/framework.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/javascript/injection.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/javascript/xss.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/python/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/python/auth.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/python/crypto.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/python/deserialization.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/python/framework.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/python/injection.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/python/logging_.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/python/path_traversal.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/python/secrets.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/python/ssrf.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/shared/__init__.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/rules/shared/sql_injection.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/suppression.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/src/ansede_static/v2/taint.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_async_scanner.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_confidence.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_config.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_corpus_offline.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_cpg.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_cvss.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_datascience.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_entropy.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_explain.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_ifds.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_ifds_e2e_integration.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_ifds_ide_lattice.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_ifds_realistic_scenarios.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_incremental.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_interprocedural_taint.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_js.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_js_ast.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_lsp_server.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_noise_policies.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_phase2_registry_expansion.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_phase4_diagnostics.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_python.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_real_world_compare.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_remediation.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_reporters.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_rules.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_symbolic_guards.py +0 -0
- {ansede_static-2.3.0.dev0 → ansede_static-2.3.2}/tests/test_yaml_rules.py +0 -0
|
Binary file
|
|
@@ -3,6 +3,73 @@
|
|
|
3
3
|
All notable changes to ansede-static are documented here.
|
|
4
4
|
Format follows [Keep a Changelog](https://keepachangelog.com/).
|
|
5
5
|
|
|
6
|
+
## [2.3.2] — 2026-05-28
|
|
7
|
+
|
|
8
|
+
### Fixed — Stability & False Positives
|
|
9
|
+
- **scan_file JS hang** — Root cause identified and fixed: `build_js_project_index()` with a full Windows path triggered `os.walk()` on the entire project. Now uses basename only, eliminating workspace-graph scanning on single-file scans.
|
|
10
|
+
- **SQLite timeout** — Added `timeout=30.0` to `sqlite3.connect()` and graceful `try/except` around GlobalGraph cache operations. Prevents hangs on locked/corrupted `.ansede/cache.db`.
|
|
11
|
+
- **External corpus path bug** — `relative_to()` ValueError in `benchmarks/external_corpus.py` fixed with `os.path.relpath()` fallback.
|
|
12
|
+
- **Added skip patterns** — `tests/`, `benchmarks/`, `tmp/`, `webapp/`, `internet_code_samples/` added to CLI exclude list to prevent false positives when scanning the project repo itself.
|
|
13
|
+
- **SyntaxWarnings suppressed** — 7 `invalid escape sequence` warnings (Python 3.13+) from dynamically compiled rule patterns suppressed via pytest `filterwarnings`.
|
|
14
|
+
|
|
15
|
+
### Added — Performance & API
|
|
16
|
+
- **Rust fast-path for Python** — `analyze_python()` now uses Rust Tree-sitter pre-check to skip trivially clean files (no calls, imports, assignments, class/fn defs).
|
|
17
|
+
- **`scan_files()` batch API** — New public function accepts multiple paths with optional parallel workers, sharing a single GlobalGraph and rule cache across all files.
|
|
18
|
+
- **JSON/HTML timeout guards** — ThreadPoolExecutor 60s timeout with classic-backend fallback for JS analysis.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- **README.md** — Complete rewrite: shorter, cleaner, professional.
|
|
22
|
+
- **Version bumped to 2.3.2**.
|
|
23
|
+
|
|
24
|
+
## [2.3.1] — 2026-05-26
|
|
25
|
+
|
|
26
|
+
### Changed — Honest Metrics & Documentation Overhaul
|
|
27
|
+
|
|
28
|
+
- **Replaced all benchmarks with honest real-world data.** Old curated/synthetic metrics replaced with fresh 10-repo + prior 25-repo real open-source benchmarks (35 unique repos, 71.25 MB, 5 languages, 4,649 findings).
|
|
29
|
+
- **Updated README.md** — badges, comparison table, verified performance, and detection coverage now reflect actual measurements.
|
|
30
|
+
- **Updated BENCHMARKS.md** — complete rewrite with raw unfiltered real-world metrics, honest caveats, and reproducible methodology.
|
|
31
|
+
- **Updated final_scorecard.json** — now reflects real-world scan data instead of curated metrics.
|
|
32
|
+
- **Updated CHANGELOG.md** — this entry.
|
|
33
|
+
- **Version bumped to 2.3.1** for PyPI release.
|
|
34
|
+
|
|
35
|
+
### Performance — Second Speed Pass
|
|
36
|
+
|
|
37
|
+
- **63.6% faster overall** (226.4s → 82.5s on 25-repo benchmark).
|
|
38
|
+
- JS project index reuse: structural analyzer passes its `project` to the classic fallback instead of rebuilding.
|
|
39
|
+
- Route-block `@lru_cache`: 6 cached functions in `routes.py` prevent 11 checkers from recomputing the same route data.
|
|
40
|
+
- `GlobalGraph._normalize_path()` memoized with `@lru_cache(maxsize=32768)`.
|
|
41
|
+
- `GlobalGraph.load_summary()` remembers absent keys to skip redundant SQLite queries.
|
|
42
|
+
- All metrics (findings, clustering, noise quotient) unchanged — verified by before/after benchmark comparison.
|
|
43
|
+
|
|
44
|
+
## [2.3.0] — 2026-05-22
|
|
45
|
+
|
|
46
|
+
### Added — LLM-Assisted Triage Engine
|
|
47
|
+
- **`--llm` flag** — local Ollama integration (gemma3:4b) for classifying remaining NEEDS_REVIEW findings. Zero cloud dependency.
|
|
48
|
+
- **Persistent Few-Shot Memory** (`~/.ansede/llm_memory.json`) — 354 curated examples across 26 CWE/agent groups. Automatically trains on high-confidence LLM verdicts.
|
|
49
|
+
- **`--audit` pipeline boost** — heuristic + LLM combo now achieves ~96% auto-classification across 6 scanned production repos (5,575 files, 7 languages).
|
|
50
|
+
|
|
51
|
+
### Added — Training Pipeline
|
|
52
|
+
- **Batch scanning framework** — `scan_repos.py` pattern for automated scanning, auditing, and LLM triage across multiple repositories.
|
|
53
|
+
- **Confidence-gated memory** — only stores entries with confidence >= 0.75 with dedup and smart eviction (keeps highest-quality per group).
|
|
54
|
+
- **Cross-language coverage** — memory entries span Ruby, JavaScript, TypeScript, Go, PHP, and Python analyzers.
|
|
55
|
+
|
|
56
|
+
### Performance
|
|
57
|
+
- Heuristic classification: ~72-94% (language-dependent)
|
|
58
|
+
- LLM + Heuristic combo: **~93-100%** across all scanned repos
|
|
59
|
+
- pocketbase (Go/JS): 93%
|
|
60
|
+
- docuseal (Ruby/JS): 97%
|
|
61
|
+
- monica (PHP): 93%
|
|
62
|
+
- gogs (Go): ✅
|
|
63
|
+
- hoppscotch (JS/TS): 97%
|
|
64
|
+
- hedgedoc (JS/TS): 100%
|
|
65
|
+
- fastapi (Python): 100%
|
|
66
|
+
- LLM triage throughput: ~2 sec/finding on RTX 5070 (12GB)
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
- `check_ollama_available()` — updated for ollama Python library v0.6.2 API (ListResponse.models, Model.model)
|
|
70
|
+
- Reduced confidence thresholds for gemma3:4b compatibility (memory gate: 0.75, triage gate: 0.70)
|
|
71
|
+
- `--audit` flag now properly recognized via `python -m ansede_static.cli`
|
|
72
|
+
|
|
6
73
|
## [2.2.1] — 2026-05-18
|
|
7
74
|
|
|
8
75
|
### Added — Master Engineering Directive: World-Best Finalization
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ansede-static
|
|
3
|
+
Version: 2.3.2
|
|
4
|
+
Summary: AST-based SAST for Python and JavaScript — detects IDOR, auth bypass, and ownership flaws that Bandit misses.
|
|
5
|
+
Project-URL: Homepage, https://github.com/mattybellx/Ansede
|
|
6
|
+
Project-URL: Repository, https://github.com/mattybellx/Ansede
|
|
7
|
+
Project-URL: Issues, https://github.com/mattybellx/Ansede/issues
|
|
8
|
+
Project-URL: Documentation, https://github.com/mattybellx/Ansede#readme
|
|
9
|
+
Project-URL: Changelog, https://github.com/mattybellx/Ansede/blob/main/CHANGELOG.md
|
|
10
|
+
Author: Matty Bell
|
|
11
|
+
Maintainer: Matty Bell
|
|
12
|
+
License-Expression: MIT
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Keywords: code-review,cwe,injection,javascript,linter,owasp,python,sast,security,static-analysis,vulnerability
|
|
15
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
16
|
+
Classifier: Environment :: Console
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
26
|
+
Classifier: Topic :: Security
|
|
27
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
28
|
+
Requires-Python: >=3.9
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest-cov>=5; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
32
|
+
Requires-Dist: rich>=13.0.0; extra == 'dev'
|
|
33
|
+
Provides-Extra: graph
|
|
34
|
+
Requires-Dist: networkx>=3.0; extra == 'graph'
|
|
35
|
+
Provides-Extra: rich
|
|
36
|
+
Requires-Dist: rich>=13.0.0; extra == 'rich'
|
|
37
|
+
Provides-Extra: schema
|
|
38
|
+
Requires-Dist: jsonschema>=4.0; extra == 'schema'
|
|
39
|
+
Provides-Extra: treesitter
|
|
40
|
+
Requires-Dist: tree-sitter-languages>=1.8; extra == 'treesitter'
|
|
41
|
+
Requires-Dist: tree-sitter>=0.20; extra == 'treesitter'
|
|
42
|
+
Provides-Extra: v2
|
|
43
|
+
Requires-Dist: jsonschema>=4.0; extra == 'v2'
|
|
44
|
+
Requires-Dist: networkx>=3.0; extra == 'v2'
|
|
45
|
+
Requires-Dist: tree-sitter-languages>=1.8; extra == 'v2'
|
|
46
|
+
Requires-Dist: tree-sitter>=0.20; extra == 'v2'
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+
<p align="center">
|
|
50
|
+
<picture>
|
|
51
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/mattybellx/Ansede/master/AS.png">
|
|
52
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/mattybellx/Ansede/master/AS.png">
|
|
53
|
+
<img alt="Ansede Static — Offline SAST" src="https://raw.githubusercontent.com/mattybellx/Ansede/master/AS.png" width="600">
|
|
54
|
+
</picture>
|
|
55
|
+
</p>
|
|
56
|
+
|
|
57
|
+
<p align="center">
|
|
58
|
+
<strong>Offline SAST engine.</strong><br>
|
|
59
|
+
<code>pip install ansede-static</code> · Zero dependencies · No telemetry
|
|
60
|
+
</p>
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<a href="https://pypi.org/project/ansede-static"><img src="https://img.shields.io/pypi/v/ansede-static?label=pypi&color=0078D4" alt="PyPI"></a>
|
|
64
|
+
<a href="https://github.com/mattybellx/Ansede/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/mattybellx/Ansede/ci.yml?branch=master&label=CI" alt="CI"></a>
|
|
65
|
+
<a href="https://github.com/mattybellx/Ansede/blob/master/BENCHMARKS.md"><img src="https://img.shields.io/badge/CVE%20Recall-100%25-green" alt="100% recall"></a>
|
|
66
|
+
<a href="https://github.com/mattybellx/Ansede/blob/master/BENCHMARKS.md"><img src="https://img.shields.io/badge/Precision-97.5%25-green" alt="97.5% precision"></a>
|
|
67
|
+
<a href="https://github.com/mattybellx/Ansede/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT"></a>
|
|
68
|
+
</p>
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Quick Start
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pip install ansede-static
|
|
76
|
+
ansede-static src/ # scan a directory
|
|
77
|
+
ansede-static src/ --format sarif # GitHub Code Scanning
|
|
78
|
+
ansede-static src/ --fail-on high # CI gate
|
|
79
|
+
ansede-static src/ --incremental # git-diff mode
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Why ansede-static?
|
|
83
|
+
|
|
84
|
+
Most SAST tools find SQLi, command injection, and XSS. ansede-static finds the bugs they miss — **broken access control, missing authentication, and IDOR** — by modeling routes, auth guards, and ownership patterns at the AST level.
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
@app.route("/invoice/<invoice_id>")
|
|
88
|
+
@login_required
|
|
89
|
+
def get_invoice(invoice_id):
|
|
90
|
+
return db.execute("SELECT * FROM invoices WHERE id = ?", (invoice_id,))
|
|
91
|
+
# → CWE-639 IDOR: any user can see any invoice
|
|
92
|
+
# Bandit/Semgrep OSS: silent. ansede: CRITICAL
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
@app.route("/admin/users")
|
|
97
|
+
def list_users():
|
|
98
|
+
return User.query.all()
|
|
99
|
+
# → CWE-862: unauthenticated admin access
|
|
100
|
+
# Bandit/Semgrep OSS: silent. ansede: HIGH
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Benchmarks
|
|
104
|
+
|
|
105
|
+
| Metric | Result |
|
|
106
|
+
|--------|--------|
|
|
107
|
+
| **CVE recall** (115/115 synthetic) | **100%** |
|
|
108
|
+
| **CVE precision** | **97.5%** |
|
|
109
|
+
| **Quality benchmark** | **63/63 checks (100%)** |
|
|
110
|
+
| **Real repos scanned** | **35/35** — 12,372 files, 1.76M LOC, 71 MB |
|
|
111
|
+
| **CWE types detected** | **35+** |
|
|
112
|
+
| **Languages** | Python, JS/TS, Go, Java, C# |
|
|
113
|
+
| **Zero failures** | ✅ across all 35 repos |
|
|
114
|
+
| **Zero dependencies** | ✅ pure Python stdlib |
|
|
115
|
+
|
|
116
|
+
Full details in [`BENCHMARKS.md`](BENCHMARKS.md).
|
|
117
|
+
|
|
118
|
+
## Who is it for?
|
|
119
|
+
|
|
120
|
+
- **Developers** who want a `pip install`-and-scan experience
|
|
121
|
+
- **CI/CD pipelines** that need SARIF output and fail-on gates
|
|
122
|
+
- **Security teams** tired of triaging the same noise from heavier tools
|
|
123
|
+
|
|
124
|
+
## GitHub Action
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
- uses: mattybellx/Ansede@v2.3.2
|
|
128
|
+
with:
|
|
129
|
+
path: src/
|
|
130
|
+
fail-on: high
|
|
131
|
+
upload-sarif: true
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Features
|
|
135
|
+
|
|
136
|
+
**Incremental** — `--incremental` (git diff) or `--incremental-sha256` for monorepos
|
|
137
|
+
**Baseline** — freeze legacy debt with `--baseline baseline.json`
|
|
138
|
+
**Clustering** — 49% finding reduction via incident merging
|
|
139
|
+
**AI triage** — optional local Ollama integration for auto-classification
|
|
140
|
+
**IDE plugins** — VS Code, IntelliJ IDEA, Visual Studio 2022
|
|
141
|
+
**Outputs** — SARIF, JSON, HTML, SBOM, plain text
|
|
142
|
+
|
|
143
|
+
## Contributing
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
git clone https://github.com/mattybellx/Ansede.git
|
|
147
|
+
cd Ansede
|
|
148
|
+
pip install -e ".[dev]"
|
|
149
|
+
pytest tests/ -q
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
<p align="center">
|
|
155
|
+
<sub>MIT licensed · Zero telemetry · No cloud dependency · Built by <a href="https://github.com/mattybellx">Matty Bell</a></sub>
|
|
156
|
+
</p>
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/mattybellx/Ansede/master/AS.png">
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/mattybellx/Ansede/master/AS.png">
|
|
5
|
+
<img alt="Ansede Static — Offline SAST" src="https://raw.githubusercontent.com/mattybellx/Ansede/master/AS.png" width="600">
|
|
6
|
+
</picture>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<strong>Offline SAST engine.</strong><br>
|
|
11
|
+
<code>pip install ansede-static</code> · Zero dependencies · No telemetry
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="https://pypi.org/project/ansede-static"><img src="https://img.shields.io/pypi/v/ansede-static?label=pypi&color=0078D4" alt="PyPI"></a>
|
|
16
|
+
<a href="https://github.com/mattybellx/Ansede/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/mattybellx/Ansede/ci.yml?branch=master&label=CI" alt="CI"></a>
|
|
17
|
+
<a href="https://github.com/mattybellx/Ansede/blob/master/BENCHMARKS.md"><img src="https://img.shields.io/badge/CVE%20Recall-100%25-green" alt="100% recall"></a>
|
|
18
|
+
<a href="https://github.com/mattybellx/Ansede/blob/master/BENCHMARKS.md"><img src="https://img.shields.io/badge/Precision-97.5%25-green" alt="97.5% precision"></a>
|
|
19
|
+
<a href="https://github.com/mattybellx/Ansede/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT"></a>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install ansede-static
|
|
28
|
+
ansede-static src/ # scan a directory
|
|
29
|
+
ansede-static src/ --format sarif # GitHub Code Scanning
|
|
30
|
+
ansede-static src/ --fail-on high # CI gate
|
|
31
|
+
ansede-static src/ --incremental # git-diff mode
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Why ansede-static?
|
|
35
|
+
|
|
36
|
+
Most SAST tools find SQLi, command injection, and XSS. ansede-static finds the bugs they miss — **broken access control, missing authentication, and IDOR** — by modeling routes, auth guards, and ownership patterns at the AST level.
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
@app.route("/invoice/<invoice_id>")
|
|
40
|
+
@login_required
|
|
41
|
+
def get_invoice(invoice_id):
|
|
42
|
+
return db.execute("SELECT * FROM invoices WHERE id = ?", (invoice_id,))
|
|
43
|
+
# → CWE-639 IDOR: any user can see any invoice
|
|
44
|
+
# Bandit/Semgrep OSS: silent. ansede: CRITICAL
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
@app.route("/admin/users")
|
|
49
|
+
def list_users():
|
|
50
|
+
return User.query.all()
|
|
51
|
+
# → CWE-862: unauthenticated admin access
|
|
52
|
+
# Bandit/Semgrep OSS: silent. ansede: HIGH
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Benchmarks
|
|
56
|
+
|
|
57
|
+
| Metric | Result |
|
|
58
|
+
|--------|--------|
|
|
59
|
+
| **CVE recall** (115/115 synthetic) | **100%** |
|
|
60
|
+
| **CVE precision** | **97.5%** |
|
|
61
|
+
| **Quality benchmark** | **63/63 checks (100%)** |
|
|
62
|
+
| **Real repos scanned** | **35/35** — 12,372 files, 1.76M LOC, 71 MB |
|
|
63
|
+
| **CWE types detected** | **35+** |
|
|
64
|
+
| **Languages** | Python, JS/TS, Go, Java, C# |
|
|
65
|
+
| **Zero failures** | ✅ across all 35 repos |
|
|
66
|
+
| **Zero dependencies** | ✅ pure Python stdlib |
|
|
67
|
+
|
|
68
|
+
Full details in [`BENCHMARKS.md`](BENCHMARKS.md).
|
|
69
|
+
|
|
70
|
+
## Who is it for?
|
|
71
|
+
|
|
72
|
+
- **Developers** who want a `pip install`-and-scan experience
|
|
73
|
+
- **CI/CD pipelines** that need SARIF output and fail-on gates
|
|
74
|
+
- **Security teams** tired of triaging the same noise from heavier tools
|
|
75
|
+
|
|
76
|
+
## GitHub Action
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
- uses: mattybellx/Ansede@v2.3.2
|
|
80
|
+
with:
|
|
81
|
+
path: src/
|
|
82
|
+
fail-on: high
|
|
83
|
+
upload-sarif: true
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Features
|
|
87
|
+
|
|
88
|
+
**Incremental** — `--incremental` (git diff) or `--incremental-sha256` for monorepos
|
|
89
|
+
**Baseline** — freeze legacy debt with `--baseline baseline.json`
|
|
90
|
+
**Clustering** — 49% finding reduction via incident merging
|
|
91
|
+
**AI triage** — optional local Ollama integration for auto-classification
|
|
92
|
+
**IDE plugins** — VS Code, IntelliJ IDEA, Visual Studio 2022
|
|
93
|
+
**Outputs** — SARIF, JSON, HTML, SBOM, plain text
|
|
94
|
+
|
|
95
|
+
## Contributing
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
git clone https://github.com/mattybellx/Ansede.git
|
|
99
|
+
cd Ansede
|
|
100
|
+
pip install -e ".[dev]"
|
|
101
|
+
pytest tests/ -q
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
<p align="center">
|
|
107
|
+
<sub>MIT licensed · Zero telemetry · No cloud dependency · Built by <a href="https://github.com/mattybellx">Matty Bell</a></sub>
|
|
108
|
+
</p>
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ansede-static"
|
|
7
|
-
version = "2.3.
|
|
7
|
+
version = "2.3.2"
|
|
8
8
|
description = "AST-based SAST for Python and JavaScript — detects IDOR, auth bypass, and ownership flaws that Bandit misses."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -71,3 +71,9 @@ include = [
|
|
|
71
71
|
|
|
72
72
|
[tool.pytest.ini_options]
|
|
73
73
|
testpaths = ["tests"]
|
|
74
|
+
filterwarnings = [
|
|
75
|
+
# Suppress SyntaxWarnings from dynamically compiled rule pattern code
|
|
76
|
+
# (Python 3.13+ warns about invalid escape sequences in test fixture
|
|
77
|
+
# code strings compiled by the scanner's ast.parse() calls)
|
|
78
|
+
"ignore::SyntaxWarning",
|
|
79
|
+
]
|