Fuzz all endpoints in an API. Args: api: Parsed API specification Returns: Scan result with findings
(self, api: ParsedAPI)
| 128 | ) |
| 129 | |
| 130 | async def fuzz_api(self, api: ParsedAPI) -> ScanResult: |
| 131 | """Fuzz all endpoints in an API. |
| 132 | |
| 133 | Args: |
| 134 | api: Parsed API specification |
| 135 | |
| 136 | Returns: |
| 137 | Scan result with findings |
| 138 | """ |
| 139 | target = Target.from_string(api.base_url) |
| 140 | self.logger.info(f"Fuzzing {api.title} ({len(api.endpoints)} endpoints)") |
| 141 | |
| 142 | all_findings = [] |
| 143 | request_count = 0 |
| 144 | |
| 145 | async for result in self._fuzz_endpoints(api): |
| 146 | if result.finding: |
| 147 | all_findings.append(result.finding) |
| 148 | |
| 149 | request_count += 1 |
| 150 | if request_count >= self.max_requests: |
| 151 | self.logger.info(f"Reached max requests limit ({self.max_requests})") |
| 152 | break |
| 153 | |
| 154 | return ScanResult( |
| 155 | module="apisec.fuzzer", |
| 156 | target=target, |
| 157 | success=True, |
| 158 | findings=all_findings, |
| 159 | data={ |
| 160 | "api_title": api.title, |
| 161 | "requests_sent": request_count, |
| 162 | "findings_count": len(all_findings), |
| 163 | }, |
| 164 | ) |
| 165 | |
| 166 | async def _fuzz_endpoints(self, api: ParsedAPI) -> AsyncIterator[FuzzResult]: |
| 167 | """Fuzz all endpoints. |
no test coverage detected