Skip to content

Commit 7f80e47

Browse files
lobziikStranger6667
authored andcommitted
Add possibility to skip https ssl check for schemathesis
This commit adds new flag to the wafp cli - `--fuzzer-skip-ssl-verify` which tells fuzzeers to skip certs ferification. Also added possibility to disable certs verification on per target basis, for such purposes new field `fuzzer_skip_ssl_verify` was introduced in target context. After target run its value will be piped down to a fuzzer run function.
1 parent ff03d69 commit 7f80e47

File tree

14 files changed

+133
-22
lines changed

14 files changed

+133
-22
lines changed

src/wafp/__main__.py

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class CliArguments(targets.cli.SharedCliArguments, fuzzers.cli.SharedCliArgument
1818

1919
build: bool
2020
output_dir: str
21+
fuzzer_skip_ssl_verify: bool
2122

2223
@classmethod
2324
def from_all_args(
@@ -39,6 +40,13 @@ def extend_parser(cls, parser: argparse.ArgumentParser, *, catalog: Optional[str
3940
parser.add_argument(
4041
"--build", action="store_true", required=False, default=False, help="Force building docker images"
4142
)
43+
parser.add_argument(
44+
"--fuzzer-skip-ssl-verify",
45+
action="store_true",
46+
required=False,
47+
default=False,
48+
help="Tells fuzzer to skip certificates verification in case of https",
49+
)
4250
parser.add_argument(
4351
"--output-dir",
4452
action="store",
@@ -65,6 +73,7 @@ def main(
6573
schema=context.schema_location,
6674
base_url=context.base_url,
6775
headers=context.headers,
76+
ssl_insecure=cli_args.fuzzer_skip_ssl_verify or context.fuzzer_skip_ssl_verify,
6877
build=cli_args.build,
6978
target=cli_args.target,
7079
) as result:

src/wafp/fuzzers/catalog/api_fuzzer/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,16 @@
88

99
class Default(BaseFuzzer):
1010
def get_entrypoint_args(
11-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
11+
self,
12+
context: FuzzerContext,
13+
schema: str,
14+
base_url: str,
15+
headers: Dict[str, str],
16+
ssl_insecure: bool = False,
1217
) -> List[str]:
18+
if ssl_insecure:
19+
self.logger.warning("Explicit cert verification skip is not supported for this fuzzer yet")
20+
1321
args = ["--basic_output=True"]
1422
if is_url(schema):
1523
args.append(f"--src_url={schema}")

src/wafp/fuzzers/catalog/cats/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,16 @@ def get_container_output_directory(self) -> pathlib.Path:
2525
return pathlib.Path("/app/test-report/")
2626

2727
def get_entrypoint_args(
28-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
28+
self,
29+
context: FuzzerContext,
30+
schema: str,
31+
base_url: str,
32+
headers: Dict[str, str],
33+
ssl_insecure: bool = False,
2934
) -> List[str]:
35+
if ssl_insecure:
36+
self.logger.warning("Explicit cert verification skip is not supported for this fuzzer yet")
37+
3038
args = [f"--contract={schema}", f"--server={base_url}"]
3139
if headers:
3240
# Over-simplified YAML serialization only for this exact case

src/wafp/fuzzers/catalog/fuzz_lightyear/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,16 @@
77

88
class Default(BaseFuzzer):
99
def get_entrypoint_args(
10-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
10+
self,
11+
context: FuzzerContext,
12+
schema: str,
13+
base_url: str,
14+
headers: Dict[str, str],
15+
ssl_insecure: bool = False,
1116
) -> List[str]:
17+
if ssl_insecure:
18+
self.logger.warning("Explicit cert verification skip is not supported for this fuzzer yet")
19+
1220
if not is_url(schema):
1321
# The `url` argument is ignored if we pass the `--schema` option
1422
args = [f"--schema={schema}", "http://0.0.0.0/any.yaml"]

src/wafp/fuzzers/catalog/fuzzy_swagger/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@
55

66
class Default(BaseFuzzer):
77
def get_entrypoint_args(
8-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
8+
self,
9+
context: FuzzerContext,
10+
schema: str,
11+
base_url: str,
12+
headers: Dict[str, str],
13+
ssl_insecure: bool = False,
914
) -> List[str]:
15+
if ssl_insecure:
16+
self.logger.warning("Explicit cert verification skip is not supported for this fuzzer yet")
17+
1018
# Fuzzy-Swagger does not support custom headers
1119
return [f"--swagger={schema}", f"--server={base_url}", "--verbose"]

src/wafp/fuzzers/catalog/got_swag/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@
55

66
class Default(BaseFuzzer):
77
def get_entrypoint_args(
8-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
8+
self,
9+
context: FuzzerContext,
10+
schema: str,
11+
base_url: str,
12+
headers: Dict[str, str],
13+
ssl_insecure: bool = False,
914
) -> List[str]:
15+
if ssl_insecure:
16+
self.logger.warning("Explicit cert verification skip is not supported for this fuzzer yet")
17+
1018
# Custom headers are only supported as variables for their tests DSL
1119
return [schema, "-m"]

src/wafp/fuzzers/catalog/restler/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,16 @@ def prepare_schema(self, context: FuzzerContext, schema: str) -> str:
2626
return str(container_input / filename)
2727

2828
def get_entrypoint_args(
29-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
29+
self,
30+
context: FuzzerContext,
31+
schema: str,
32+
base_url: str,
33+
headers: Dict[str, str],
34+
ssl_insecure: bool = False,
3035
) -> List[str]:
36+
if ssl_insecure:
37+
self.logger.warning("Explicit cert verification skip is not supported for this fuzzer yet")
38+
3139
parsed = urlparse(base_url)
3240
args = [
3341
str(self.get_container_output_directory()),

src/wafp/fuzzers/catalog/schemathesis/__init__.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
class Default(BaseFuzzer):
99
def get_entrypoint_args(
10-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
10+
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str], ssl_insecure: bool = False
1111
) -> List[str]:
1212
args = [
1313
"run",
@@ -22,6 +22,8 @@ def get_entrypoint_args(
2222
if headers:
2323
for key, value in headers.items():
2424
args.extend(["-H", f"{key}: {value}"])
25+
if ssl_insecure:
26+
args.extend(["--request-tls-verify=false"])
2527
extend_entrypoint_args(context, args)
2628
return args
2729

@@ -36,27 +38,27 @@ def extend_entrypoint_args(context: FuzzerContext, args: List[str]) -> None:
3638

3739
class AllChecks(Default):
3840
def get_entrypoint_args(
39-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
41+
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str], ssl_insecure: bool = False
4042
) -> List[str]:
41-
args = super().get_entrypoint_args(context, schema, base_url, headers)
43+
args = super().get_entrypoint_args(context, schema, base_url, headers, ssl_insecure)
4244
args.append("--checks=all")
4345
return args
4446

4547

4648
class Negative(Default):
4749
def get_entrypoint_args(
48-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
50+
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str], ssl_insecure: bool = False
4951
) -> List[str]:
50-
args = super().get_entrypoint_args(context, schema, base_url, headers)
52+
args = super().get_entrypoint_args(context, schema, base_url, headers, ssl_insecure)
5153
args.append("--data-generation-method=negative")
5254
return args
5355

5456

5557
class StatefulOld(Default):
5658
def get_entrypoint_args(
57-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
59+
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str], ssl_insecure: bool = False
5860
) -> List[str]:
59-
args = super().get_entrypoint_args(context, schema, base_url, headers)
61+
args = super().get_entrypoint_args(context, schema, base_url, headers, ssl_insecure)
6062
args.append("--stateful=links")
6163
return args
6264

@@ -66,8 +68,11 @@ def get_entrypoint(self) -> Union[str, NotSet]:
6668
return "pytest"
6769

6870
def get_entrypoint_args(
69-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
71+
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str], ssl_insecure: bool = False
7072
) -> List[str]:
73+
if ssl_insecure:
74+
self.logger.warning("Explicit cert verification skip is not supported for this target yet")
75+
7176
filename = "test_stateful.py"
7277
if context.target is not None and context.target.startswith("age_of_empires_2_api"):
7378
extra = {"force_schema_version": "30"}

src/wafp/fuzzers/catalog/swagger_conformance/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@
55

66
class Default(BaseFuzzer):
77
def get_entrypoint_args(
8-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
8+
self,
9+
context: FuzzerContext,
10+
schema: str,
11+
base_url: str,
12+
headers: Dict[str, str],
13+
ssl_insecure: bool = False,
914
) -> List[str]:
15+
if ssl_insecure:
16+
self.logger.warning("Explicit cert verification skip is not supported for this fuzzer yet")
17+
1018
# Swagger-conformance does not support setting base URL or custom headers
1119
return [schema]

src/wafp/fuzzers/catalog/swagger_fuzzer/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,15 @@ def prepare_schema(self, context: FuzzerContext, schema: str) -> str:
1212
return self.serve_spec(context, schema)
1313

1414
def get_entrypoint_args(
15-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
15+
self,
16+
context: FuzzerContext,
17+
schema: str,
18+
base_url: str,
19+
headers: Dict[str, str],
20+
ssl_insecure: bool = False,
1621
) -> List[str]:
22+
if ssl_insecure:
23+
self.logger.warning("Explicit cert verification skip is not supported for this fuzzer yet")
24+
1725
# Swagger-fuzzer does not support setting base URL or custom headers
1826
return [schema]

src/wafp/fuzzers/catalog/tnt_fuzzer/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,16 @@ def prepare_schema(self, context: FuzzerContext, schema: str) -> str:
1414
return self.serve_spec(context, schema)
1515

1616
def get_entrypoint_args(
17-
self, context: FuzzerContext, schema: str, base_url: str, headers: Dict[str, str]
17+
self,
18+
context: FuzzerContext,
19+
schema: str,
20+
base_url: str,
21+
headers: Dict[str, str],
22+
ssl_insecure: bool = False,
1823
) -> List[str]:
24+
if ssl_insecure:
25+
self.logger.warning("Explicit cert verification skip is not supported for this fuzzer yet")
26+
1927
parsed = urlparse(base_url)
2028
args = [
2129
f"--url={schema}",

src/wafp/fuzzers/core.py

+16-3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def start(
7474
schema: str,
7575
base_url: str,
7676
headers: Optional[Dict[str, str]] = None,
77+
ssl_insecure: bool = False,
7778
build: bool = False,
7879
target: Optional[str] = None,
7980
) -> "FuzzResult":
@@ -90,7 +91,7 @@ def start(
9091
start = time.perf_counter()
9192
completed_process = self.compose.run(
9293
service=self.get_fuzzer_service_name(),
93-
args=self.get_entrypoint_args(context, schema_location, base_url, headers),
94+
args=self.get_entrypoint_args(context, schema_location, base_url, headers, ssl_insecure),
9495
entrypoint=self.get_entrypoint(),
9596
volumes=self.get_volumes(context),
9697
)
@@ -104,6 +105,7 @@ def run(
104105
schema: str,
105106
base_url: str,
106107
headers: Optional[Dict[str, str]] = None,
108+
ssl_insecure: bool = False,
107109
build: bool = False,
108110
target: Optional[str] = None,
109111
) -> Generator["FuzzResult", None, None]:
@@ -112,7 +114,13 @@ def run(
112114
It is a common workflow for CLI.
113115
"""
114116
try:
115-
yield self.start(schema, base_url, headers, build, target)
117+
yield self.start(
118+
schema,
119+
base_url,
120+
headers,
121+
ssl_insecure,
122+
build,
123+
)
116124
except subprocess.CalledProcessError as exc:
117125
sys.exit(exc.returncode)
118126
finally:
@@ -130,7 +138,12 @@ def serve_spec(self, context: "FuzzerContext", schema: str) -> str:
130138

131139
@abc.abstractmethod
132140
def get_entrypoint_args(
133-
self, context: "FuzzerContext", schema: str, base_url: str, headers: Dict[str, str]
141+
self,
142+
context: "FuzzerContext",
143+
schema: str,
144+
base_url: str,
145+
headers: Dict[str, str],
146+
ssl_insecure: bool = False,
134147
) -> List[str]:
135148
"""Arguments to fuzzer's entrypoint in `docker-compose run <service> <args>`."""
136149
raise NotImplementedError

src/wafp/targets/core.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def generate_run_id() -> str:
2626
class BaseTarget(abc.ABC, Component):
2727
port: int = attr.ib(factory=unused_port)
2828
force_build: bool = attr.ib(default=False)
29+
fuzzer_skip_ssl_verify: bool = attr.ib(default=False)
2930
sentry_dsn: Optional[str] = attr.ib(default=None)
3031
run_id: str = attr.ib(factory=generate_run_id)
3132
wait_target_ready_timeout: int = WAIT_TARGET_READY_TIMEOUT
@@ -64,7 +65,12 @@ def start(self, extra_env: Optional[Dict[str, str]] = None) -> "TargetContext":
6465
if headers:
6566
info["headers"] = headers
6667
self.logger.msg("Target is ready", **info)
67-
return TargetContext(base_url=base_url, schema_location=self.get_schema_location(), headers=headers)
68+
return TargetContext(
69+
base_url=base_url,
70+
schema_location=self.get_schema_location(),
71+
headers=headers,
72+
fuzzer_skip_ssl_verify=self.fuzzer_skip_ssl_verify,
73+
)
6874

6975
# These methods are expected to be overridden
7076

@@ -173,6 +179,7 @@ class TargetContext:
173179
base_url: str = attr.ib()
174180
schema_location: str = attr.ib()
175181
headers: Dict[str, str] = attr.ib()
182+
fuzzer_skip_ssl_verify: bool = attr.ib(default=False)
176183

177184

178185
Target = Type[BaseTarget]

test/fuzzers/fuzzers_catalog/example_fuzzer/__init__.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55

66
class Default(BaseFuzzer):
77
def get_entrypoint_args(
8-
self, context: FuzzerContext, schema: str, base_url: str, headers: Optional[Dict[str, str]]
8+
self,
9+
context: FuzzerContext,
10+
schema: str,
11+
base_url: str,
12+
headers: Optional[Dict[str, str]],
13+
ssl_insecure: bool = False,
914
) -> List[str]:
1015
args = [schema]
1116
if headers is not None:

0 commit comments

Comments
 (0)