Upload files to "tests"
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import json
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
from redflare.core.models import Target
|
||||
from redflare.modules.base import ModuleContext
|
||||
from redflare.modules.browser import NativeBrowserRuntimeModule
|
||||
from redflare.modules.http import HTTPResponse
|
||||
from redflare.modules.noauth import NativeNoAuthModule
|
||||
from redflare.modules.repository import normalize_repository, run_repository_intelligence
|
||||
|
||||
|
||||
class NativeModuleTests(unittest.TestCase):
|
||||
def test_repository_slug_normalization(self):
|
||||
self.assertEqual(normalize_repository("owner/repository"), "owner/repository")
|
||||
with self.assertRaises(ValueError): normalize_repository("repository")
|
||||
|
||||
@patch("redflare.modules.browser.NativeBrowserRuntimeModule._capture", side_effect=RuntimeError("fixture"))
|
||||
@patch("redflare.modules.browser.request")
|
||||
def test_browser_runtime_has_native_fallback(self, get, _capture):
|
||||
get.return_value = HTTPResponse("https://example.test", 200, {}, b"fixture")
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
context = ModuleContext("run", Path(directory))
|
||||
result = NativeBrowserRuntimeModule().run(Target("https://example.test", "example.test", "https", 443), context)
|
||||
self.assertEqual(result.status, "completed")
|
||||
self.assertEqual(result.observations["engine"], "native-http-fallback")
|
||||
|
||||
@patch("redflare.modules.noauth.time.sleep")
|
||||
@patch("redflare.modules.noauth.request")
|
||||
def test_noauth_module_emits_native_finding(self, get, _sleep):
|
||||
get.return_value = HTTPResponse("https://example.test/admin", 200, {"content-type": "text/html"}, b"admin console")
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
context = ModuleContext("run", Path(directory), rate=0)
|
||||
result = NativeNoAuthModule().run(Target("https://example.test", "example.test", "https", 443), context)
|
||||
self.assertGreater(len(result.findings), 0)
|
||||
self.assertEqual(result.observations["engine"], "native-redflare")
|
||||
|
||||
@patch("redflare.modules.repository._github")
|
||||
@patch.dict("os.environ", {"GITHUB_TOKEN": "fixture-token"})
|
||||
def test_repository_intelligence_masks_findings(self, github):
|
||||
github.side_effect = [
|
||||
{"default_branch": "main"},
|
||||
{"tree": [{"type": "blob", "path": "config.js", "sha": "abc", "size": 100}]},
|
||||
{"encoding": "base64", "content": "YXBpX2tleSA9ICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiI="},
|
||||
]
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
result = run_repository_intelligence(["owner/repo"], Path(directory))
|
||||
data = json.loads(Path(result["output"]).read_text())
|
||||
self.assertEqual(result["engine"], "native-redflare")
|
||||
self.assertNotIn("abcdefghijklmnopqrstuvwxyz", json.dumps(data))
|
||||
|
||||
|
||||
if __name__ == "__main__": unittest.main()
|
||||
@@ -0,0 +1,18 @@
|
||||
import unittest
|
||||
|
||||
from redflare.modules.surface import SurfaceParser, decode_targets
|
||||
|
||||
|
||||
class SurfaceTests(unittest.TestCase):
|
||||
def test_extracts_forms_and_redirects(self):
|
||||
parser = SurfaceParser("https://example.test/start")
|
||||
parser.feed(
|
||||
'<meta http-equiv="refresh" content="0; url=/next">'
|
||||
'<form action="/login" method="post"><input name="password" type="password"></form>'
|
||||
)
|
||||
self.assertEqual(parser.forms[0]["action"], "https://example.test/login")
|
||||
self.assertEqual(parser.meta_refresh, ["https://example.test/next"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,45 @@
|
||||
import unittest
|
||||
|
||||
from redflare.core.surface_graph import AttackSurfaceGraph
|
||||
|
||||
|
||||
class SurfaceGraphTests(unittest.TestCase):
|
||||
def test_merges_sources_methods_and_query_parameters(self):
|
||||
graph = AttackSurfaceGraph()
|
||||
graph.add_endpoint(
|
||||
"https://example.test",
|
||||
"https://example.test/api/users?id=7",
|
||||
method="GET",
|
||||
source="html-link",
|
||||
)
|
||||
graph.add_endpoint(
|
||||
"https://example.test",
|
||||
"https://example.test/api/users?id=9",
|
||||
method="POST",
|
||||
source="openapi",
|
||||
parameters=[{"name": "name", "location": "body", "required": True, "data_type": "string"}],
|
||||
)
|
||||
snapshot = graph.snapshot()
|
||||
endpoints = snapshot["targets"]["https://example.test"]["endpoints"]
|
||||
self.assertEqual(len(endpoints), 1)
|
||||
self.assertEqual(endpoints[0]["methods"], ["GET", "POST"])
|
||||
self.assertEqual({item["name"] for item in endpoints[0]["parameters"]}, {"id", "name"})
|
||||
self.assertEqual(
|
||||
graph.request_urls("https://example.test"),
|
||||
["https://example.test/api/users?id=7"],
|
||||
)
|
||||
|
||||
def test_redacts_sensitive_query_values_in_snapshot(self):
|
||||
graph = AttackSurfaceGraph()
|
||||
graph.add_endpoint(
|
||||
"https://example.test",
|
||||
"https://example.test/callback?id=7&access_token=super-secret",
|
||||
source="browser-traffic",
|
||||
)
|
||||
serialized = str(graph.snapshot())
|
||||
self.assertNotIn("super-secret", serialized)
|
||||
self.assertIn("access_token=%3Credacted%3E", serialized)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,57 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
import unittest
|
||||
|
||||
from redflare.core.models import Finding, ModuleResult
|
||||
from redflare.ui import LiveConsole
|
||||
|
||||
|
||||
class FinalReportTests(unittest.TestCase):
|
||||
def test_full_module_assessment_includes_observations_findings_and_artifacts(self):
|
||||
stream = StringIO()
|
||||
finding = Finding(
|
||||
run_id="run_test",
|
||||
target="https://example.test",
|
||||
module="path_discovery",
|
||||
category="discovered-path",
|
||||
title="Accessible path discovered: /admin",
|
||||
severity="info",
|
||||
confidence=0.8,
|
||||
description="The path returned HTTP 200.",
|
||||
evidence={"status": 200, "url": "https://example.test/admin"},
|
||||
)
|
||||
result = ModuleResult(
|
||||
module="path_discovery",
|
||||
target="https://example.test",
|
||||
findings=[finding],
|
||||
observations={
|
||||
"paths_tested": 2,
|
||||
"hits": [{"path": "/admin", "status": 200, "bytes": 42}],
|
||||
},
|
||||
artifacts=["runs/run_test/artifacts/path.log"],
|
||||
duration_seconds=1.25,
|
||||
)
|
||||
summary = {
|
||||
"run_id": "run_test",
|
||||
"completed": 1,
|
||||
"errors": 0,
|
||||
"findings": 1,
|
||||
"by_severity": {"info": 1},
|
||||
}
|
||||
|
||||
LiveConsole(stream).final_report(summary, [result], Path("runs/run_test"))
|
||||
output = stream.getvalue()
|
||||
|
||||
self.assertIn("PATH DISCOVERY ASSESSMENT — https://example.test", output)
|
||||
self.assertIn("Paths tested: 2", output)
|
||||
self.assertIn("Path: /admin", output)
|
||||
self.assertIn("Status: 200", output)
|
||||
self.assertIn("Module findings:", output)
|
||||
self.assertIn("runs/run_test/artifacts/path.log", output)
|
||||
self.assertIn("CONSOLIDATED FINDINGS", output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user