نسخهٔ وب مستقل — پلتفرم نیروی کار هوش مصنوعی
مخزن اختصاصی برنامهٔ وب؛ محتوای پوشهٔ web در ریشهٔ مخزن قرار گرفت. تاریخچهٔ پروژهٔ ربات (agy-bot) در این مخزن وجود ندارد و هیچ وابستگی runtime به آن نیست.
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
"""Platform safety rules: subdomain validation, proxy targets, port ranges."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from app.domain.platform.rules import (
|
||||
RuleViolation,
|
||||
assert_not_protected_port,
|
||||
assert_port_allocatable,
|
||||
build_host,
|
||||
is_port_allocatable,
|
||||
validate_managed_host,
|
||||
validate_proxy_target,
|
||||
validate_subdomain_label,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"label", ["my-app", "app1", "a" * 40, "abc"]
|
||||
)
|
||||
def test_valid_labels(label: str):
|
||||
assert validate_subdomain_label(label) == label
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"label",
|
||||
[
|
||||
"ab", # too short
|
||||
"a" * 41, # too long
|
||||
"-abc", # leading hyphen
|
||||
"abc-", # trailing hyphen
|
||||
"My-App", # uppercase is normalised, but this one has no other issue
|
||||
"app_name", # underscore not allowed
|
||||
"app.name", # dot not allowed
|
||||
"app name", # whitespace
|
||||
"app{}", # brace injection attempt
|
||||
"app\nother", # newline injection attempt
|
||||
"", # empty
|
||||
],
|
||||
)
|
||||
def test_invalid_labels(label: str):
|
||||
if label == "My-App":
|
||||
# Documented behaviour: input is lower-cased, so this is accepted as "my-app".
|
||||
assert validate_subdomain_label(label) == "my-app"
|
||||
return
|
||||
with pytest.raises(RuleViolation):
|
||||
validate_subdomain_label(label)
|
||||
|
||||
|
||||
def test_build_host_appends_root_domain():
|
||||
assert build_host("shop", "msa.artacloud.ir") == "shop.msa.artacloud.ir"
|
||||
|
||||
|
||||
def test_managed_host_rejects_foreign_domain():
|
||||
with pytest.raises(RuleViolation):
|
||||
validate_managed_host("evil.example.com", "msa.artacloud.ir")
|
||||
|
||||
|
||||
def test_managed_host_rejects_nested_label():
|
||||
with pytest.raises(RuleViolation):
|
||||
validate_managed_host("a.b.msa.artacloud.ir", "msa.artacloud.ir")
|
||||
|
||||
|
||||
def test_managed_host_rejects_injection_attempt():
|
||||
with pytest.raises(RuleViolation):
|
||||
validate_managed_host("app { reverse_proxy evil:80 }.msa.artacloud.ir", "msa.artacloud.ir")
|
||||
|
||||
|
||||
def test_managed_host_accepts_valid_host():
|
||||
assert (
|
||||
validate_managed_host("my-app.msa.artacloud.ir", "msa.artacloud.ir")
|
||||
== "my-app.msa.artacloud.ir"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"target",
|
||||
["localhost:8080", "127.0.0.1:8080", "http://localhost:8080", "http://127.0.0.1:9000"],
|
||||
)
|
||||
def test_valid_proxy_targets(target: str):
|
||||
host, port = validate_proxy_target(target)
|
||||
assert host in {"localhost", "127.0.0.1"}
|
||||
assert 1 <= port <= 65535
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"target",
|
||||
[
|
||||
"example.com:80",
|
||||
"169.254.169.254:80", # cloud metadata endpoint
|
||||
"10.0.0.5:8080", # internal network
|
||||
"localhost", # no port
|
||||
"localhost:notaport",
|
||||
"0.0.0.0:8080",
|
||||
],
|
||||
)
|
||||
def test_ssrf_proxy_targets_rejected(target: str):
|
||||
with pytest.raises(RuleViolation):
|
||||
validate_proxy_target(target)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("port", [22, 53, 80, 443, 3000, 5432, 6379, 8008, 2019, 7999, 9000])
|
||||
def test_reserved_and_out_of_range_ports_rejected(port: int):
|
||||
assert not is_port_allocatable(port)
|
||||
with pytest.raises(RuleViolation):
|
||||
assert_port_allocatable(port)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("port", [8080, 8500, 8999])
|
||||
def test_allocatable_ports(port: int):
|
||||
assert is_port_allocatable(port)
|
||||
assert assert_port_allocatable(port) == port
|
||||
|
||||
|
||||
@pytest.mark.parametrize("port", [3000, 35555, 35556, 35557, 5432])
|
||||
def test_protected_ports_cannot_be_proxied(port: int):
|
||||
with pytest.raises(RuleViolation):
|
||||
assert_not_protected_port(port)
|
||||
Reference in New Issue
Block a user