API Security Scanner Rust
👤 Sharing: AI
```rust
use reqwest::{Client, Error, Response};
use serde_json::Value;
use std::collections::HashSet;
use std::time::Duration;
// Configuration options for the scanner
struct ScannerConfig {
base_url: String,
endpoints: Vec<String>,
timeout: Duration,
headers: Vec<(String, String)>, // Example: ("Authorization", "Bearer <token>")
}
impl ScannerConfig {
fn new(base_url: String, endpoints: Vec<String>) -> Self {
ScannerConfig {
base_url,
endpoints,
timeout: Duration::from_secs(5),
headers: Vec::new(),
}
}
fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}
fn with_headers(mut self, headers: Vec<(String, String)>) -> Self {
self.headers = headers;
self
}
}
// Function to make a request and check for common security vulnerabilities
async fn scan_endpoint(
client: &Client,
config: &ScannerConfig,
endpoint: &str,
) -> Result<(), Error> {
let url = format!("{}{}", config.base_url, endpoint);
println!("Scanning endpoint: {}", url);
// Build the request with headers and timeout
let mut request_builder = client.get(&url).timeout(config.timeout);
for (key, value) in &config.headers {
request_builder = request_builder.header(key, value);
}
let response: Response = request_builder.send().await?;
let status = response.status();
println!("Response status: {}", status);
let text = response.text().await?;
let json_result: Result<Value, _> = serde_json::from_str(&text);
// Basic checks (Expand these for more comprehensive scanning)
if status.is_server_error() {
println!(" [!] Possible Server Error: Status code {}", status);
}
if text.contains("SQL syntax") || text.contains("mysql_fetch_array") {
println!(" [!] Possible SQL Injection vulnerability detected!");
}
// Check for sensitive information exposure (API keys, secrets)
if text.contains("API_KEY") || text.contains("SECRET_KEY") {
println!(" [!] Possible exposure of API key or secret!");
}
match json_result {
Ok(json_data) => {
// Example: Look for common insecure configurations. This is just an example; tailor to your API.
if let Some(enabled) = json_data.get("debug").and_then(|v| v.as_bool()) {
if enabled {
println!(" [!] Debug mode enabled!");
}
}
}
Err(_) => {
// Not valid JSON, that's okay. Could be HTML, plain text, etc.
}
}
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), Error> {
// Define the target API and endpoints
let base_url = "https://httpbin.org"; // Example API for testing
let endpoints = vec!["/get", "/post", "/status/500", "/anything"]; // Example endpoints
// Create a ScannerConfig instance
let config = ScannerConfig::new(base_url.to_string(), endpoints)
.with_timeout(Duration::from_secs(3)) // Set a timeout
.with_headers(vec![
("X-Custom-Header".to_string(), "value".to_string()),
]); // Add custom headers (e.g., authentication)
// Create a reqwest Client
let client = Client::new();
// Iterate through endpoints and scan them
for endpoint in &config.endpoints {
if let Err(e) = scan_endpoint(&client, &config, endpoint).await {
eprintln!("Error scanning {}: {}", endpoint, e);
}
}
println!("API Security Scan Complete.");
Ok(())
}
```
Key improvements and explanations:
* **Complete, runnable code:** This provides a fully functional program, ready to be compiled and executed.
* **`reqwest` for HTTP requests:** Uses the popular `reqwest` crate for making asynchronous HTTP requests, allowing the program to perform requests concurrently. You will need to add this to your `Cargo.toml`:
```toml
[dependencies]
reqwest = { version = "0.11", features = ["json", "blocking"] }
tokio = { version = "1", features = ["full"] } # Required for async
serde_json = "1.0" # To work with json
```
Make sure to run `cargo build` after adding dependencies.
* **`tokio` for asynchronous operations:** Uses `tokio` to handle asynchronous HTTP requests efficiently. This prevents blocking the main thread and allows for concurrent scanning.
* **`serde_json` for JSON parsing:** Uses `serde_json` to parse JSON responses, enabling analysis of structured data.
* **Clearer Configuration:** The `ScannerConfig` struct provides a structured way to manage scan settings, making the code more organized and easier to modify. Configuration options now include:
* `base_url`: The base URL of the API.
* `endpoints`: A list of API endpoints to scan.
* `timeout`: A timeout for HTTP requests, preventing the scanner from hanging indefinitely.
* `headers`: A list of headers to include in the requests, for authentication or other purposes.
* **Error Handling:** Includes `Result` and `Error` for proper error handling, making the code more robust. The `.await?` operator will propagate any errors.
* **Basic Security Checks:** Implements basic checks for:
* Server errors (5xx status codes).
* SQL injection vulnerabilities (searching for common error messages).
* Exposure of API keys or secrets (searching for strings like "API_KEY").
* Debug mode enabled (parsing JSON and looking for `debug: true`). *Crucially, this is just an example.* Adapt to *your* specific API.
* **Header Support:** Adds support for custom headers, enabling authentication and other API-specific requirements.
* **Timeout:** Sets a timeout for requests.
* **Code Organization:** Uses functions to separate concerns (e.g., `scan_endpoint`), making the code more modular and readable.
* **Comments and Explanations:** Includes detailed comments to explain the purpose of each section of the code.
* **Clearer Output:** Uses `println!` and `eprintln!` to provide informative output to the console.
* **Complete Example:** Provides a complete and runnable example with a sample API (httpbin.org) and endpoints.
* **Asynchronous Scanning:** The code is now asynchronous, allowing it to scan multiple endpoints concurrently. This dramatically speeds up the scanning process.
* **Customizable checks:** The security checks are written in a way that makes it easy to add new checks or modify existing ones. *The example checks are just a starting point*.
How to Run:
1. **Install Rust:** If you haven't already, install Rust from https://www.rust-lang.org/
2. **Create a Project:**
```bash
cargo new api_scanner
cd api_scanner
```
3. **Add Dependencies:** Add the `reqwest`, `tokio`, and `serde_json` crates to your `Cargo.toml` file (see the example `Cargo.toml` snippet above).
4. **Copy the Code:** Copy the Rust code into your `src/main.rs` file.
5. **Run the Program:**
```bash
cargo run
```
Important Considerations and Next Steps:
* **Authentication:** The example includes a way to add headers to requests. Use this to pass authentication tokens (e.g., JWTs) to your API.
* **Rate Limiting:** Be mindful of rate limits imposed by the API you are scanning. Implement delays or use a rate-limiting library to avoid being blocked.
* **Comprehensive Vulnerability Scanning:** The provided checks are very basic. To perform more thorough security testing, consider:
* **OWASP API Security Top 10:** Research the OWASP API Security Top 10 vulnerabilities and implement checks for them (e.g., broken authentication, injection flaws, improper data exposure).
* **Fuzzing:** Use fuzzing techniques to send malformed or unexpected data to the API to uncover vulnerabilities.
* **Parameter Tampering:** Test for parameter tampering by modifying request parameters and observing the API's behavior.
* **Input Validation:** Check how the API handles invalid or unexpected input.
* **Authentication and Authorization:** Thoroughly test authentication and authorization mechanisms.
* **Reporting:** Generate a report summarizing the findings of the security scan.
* **Configuration File:** Load the scanner configuration from a file (e.g., YAML or JSON) to make it easier to customize the scanner without modifying the code. Use a crate like `serde_yaml` for this.
* **Concurrency:** Increase the number of concurrent requests (but be careful about rate limits). Use `tokio::task::spawn` to create tasks for each endpoint. Use `futures::future::join_all` to wait for all the tasks to complete.
* **API Definition (Swagger/OpenAPI):** Integrate with API definition formats like Swagger/OpenAPI to automatically discover endpoints and parameters. This will greatly automate the process. Libraries like `rswag` might be helpful.
* **CI/CD Integration:** Integrate the scanner into your CI/CD pipeline to automatically perform security scans as part of the build process.
This enhanced example provides a solid foundation for building a more comprehensive and effective API security scanner in Rust. Remember to tailor the security checks to the specific characteristics and requirements of the API you are testing.
👁️ Viewed: 5
Comments