swagger/scan/
checks.rs

1use super::*;
2use crate::scan::active::*;
3use crate::scan::passive::*;
4use comfy_table::*;
5use strum_macros::EnumIter;
6
7///Add the rule name to this enum
8impl Default for PassiveChecks {
9    fn default() -> Self {
10        //Self::No404
11        Self::CheckServerUrl(vec![])
12    }
13}
14pub trait Check {
15    fn alerts_text(&self) -> Cell;
16    fn top_severity(&self) -> Level;
17    fn result(&self) -> &'static str;
18}
19impl Check for PassiveChecks {
20    fn alerts_text(&self) -> Cell {
21        match self.inner().len() {
22            0 => Cell::new(self.inner().len())
23                .fg(Color::Green)
24                .add_attribute(Attribute::Bold),
25            1..=10 => Cell::new(self.inner().len())
26                .fg(Color::Yellow)
27                .add_attribute(Attribute::Bold),
28            11..=99 => Cell::new(self.inner().len())
29                .fg(Color::Red)
30                .add_attribute(Attribute::Bold),
31            _ => Cell::new(self.inner().len())
32                .fg(Color::Red)
33                .add_attribute(Attribute::Bold)
34                .add_attribute(Attribute::SlowBlink),
35        }
36    }
37    fn top_severity(&self) -> Level {
38        let mut top = Level::Info;
39        for alert in self.inner() {
40            if alert.level > top {
41                top = alert.level;
42            }
43        }
44        top
45    }
46    fn result(&self) -> &'static str {
47        //let failed = self.inner().iter().map(|a| if a.level != Level::Info {1}else{0}).sum::<u64>();
48        if self.inner().is_empty() {
49            "PASSED"
50        } else {
51            "FAILED"
52        }
53    }
54}
55
56impl Check for ActiveChecks {
57    fn alerts_text(&self) -> Cell {
58        match self.inner().len() {
59            0 => Cell::new(self.inner().len())
60                .fg(Color::Green)
61                .add_attribute(Attribute::Bold),
62            1..=10 => Cell::new(self.inner().len())
63                .fg(Color::Yellow)
64                .add_attribute(Attribute::Bold),
65            11..=99 => Cell::new(self.inner().len())
66                .fg(Color::Red)
67                .add_attribute(Attribute::Bold),
68            _ => Cell::new(self.inner().len())
69                .fg(Color::Red)
70                .add_attribute(Attribute::Bold)
71                .add_attribute(Attribute::SlowBlink),
72        }
73    }
74    fn top_severity(&self) -> Level {
75        let mut top = Level::Info;
76        for alert in self.inner() {
77            if alert.level > top {
78                top = alert.level;
79            }
80        }
81        top
82    }
83    fn result(&self) -> &'static str {
84        if !self.inner().is_empty() {
85            "FAILED"
86        } else {
87            "PASSED"
88        }
89    }
90}
91
92impl_passive_checks![
93    //name in enum   check function   check name    check description
94    (CheckServerUrl,check_server_url,"SERVER URL","Checks for server url misconfigurations"),
95    (CheckAdditionalProperties,check_additional_properties,"ADDITIONAL PROPERTIES","Checks for bad defaults in object additional properties, alerts if the swagger is using the default configuration"),
96    (CheckDefaultResponse,check_default_response,"DEFAULT RESPONSE","Checks for the definition of a default response, and alerts if none is defined"),
97    (CheckResponseBodySchema,check_response_body_schema,"RESPONSE BODY SCHEMA","Checks the response body schema, and alerts when there is none"),
98    (CheckDefaultType,check_default_type,"DEFAULT TYPE","Checks that the default type is the same as the parameter type"),
99    (CheckEnumType,check_enum_type,"ENUM TYPE","Checks that the Enum type is the same as the parameter type"),
100    //(CheckRequiredUndefined,check_required_undefined,"REQUIRED UNDEFINED","Checks for any required parameters that are undefined"),
101    (CheckUnusedSchema,check_unused_schema,"UNUSED SCHEMA","Checks for unused schemas"),
102    (Check401,check_401,"401","Checks for a 401 response if there is authentication necessary"),
103    (Check403,check_403,"403","Checks for a 403 response if there is authentication necessary"),
104    (CheckSuccesses,check_successes,"RESPONSE SUCCESSES (2xx)","Checks for successful responses (2xx) in every operation"),
105    (CheckAuth,check_auth,"AUTH","Checks for a global authentication definition"),
106    (CheckFNAuth,check_fn_auth,"ENDPOINT AUTH","Checks for an authentication definition for each endpoint"),
107    (CheckIntAttrs,check_int_attrs,"INTEGER ATTRIBUTES","Checks for the definition of integer type attributes - maximum, minimum"),
108    (CheckStrAttrs,check_str_attrs,"STRING ATTRIBUTES","Checks for the definition of string type attributes - max_length, min_length, pattern"),
109    (CheckArrAttrs,check_arr_attrs,"ARRAY ATTRIBUTES","Checks for the definition of array type attributes - max_items, min_items"),
110    (CheckObjAttrs,check_obj_attrs,"OBJECT ATTRIBUTES","Checks for the definition of object type attributes - max_properties, properties"),
111    (CheckValidResponses,check_valid_responses,"VALID RESPONSES","Checks for valid responses codes"),
112    (CheckMethodPermissions, check_method_permissions, "METHOD PERMISSIONS", "Checks for correct permission configuration for GET/PUT/POST requests"),
113    (CheckContainsOperation, check_contains_operation, "CONTAINS OPERATION", "Checks that each path contains at least one operation"),
114    (CheckValidEncodings, check_valid_encoding, "VALID ENCODINGS", "Checks that all content types are valid"),
115    (CheckDescription, check_description, "DESCRIPTION", "Checks that all operations have a description"),
116    (CheckContainsResponse, check_contains_response, "CONTAINS RESPONSE", "Checks that each operation has a response")
117];
118
119impl_active_checks![
120    (
121        CheckMinMax,
122        check_min_max,
123        is_2xx,
124        "NUMBER LIMITS ENFORCED",
125        "checks that the api enforces the number limits in the OAS"
126    ),
127    (
128        CheckOpenRedirect,
129        check_open_redirect,
130        is_2xx,
131        "OPEN REDIRECT",
132        "Check if the API may be vulnerable to open redirect"
133    ),
134    (
135        CheckStringMaxLength,
136        check_string_length_max,
137        is_2xx,
138        "STRING LENGTH ENFORCED",
139        "check that the api validate the String length"
140    ),
141    (
142        CheckParameterPollution,
143        check_parameter_pollution,
144        reflected_and_2xx,
145        "PARAMETER POLLUTION",
146        "Check if the endpoint is vulnerable to http pollution"
147    ),
148    (
149        CheckSSL,
150        check_ssl,
151        is_2xx,
152        "SSL ENFORCED",
153        "Check if the connection is secure"
154    ),
155    (
156        CheckMethodPermissionsActive,
157        check_method_permissions_active,
158        is_2xx,
159        "METHOD PERMISSION",
160        "Check if the endpoint is correctly configured"
161    ),
162    (
163        CheckAuthentication,
164        check_authentication,
165        is_2xx,
166        "BROKEN FUNCTION LEVEL AUTHENTICATION",
167        "Check if the auth is correctly configured"
168   )
169     
170];