()
| 1147 | } |
| 1148 | |
| 1149 | func ScanCSS() reportResult { |
| 1150 | var repResult reportResult |
| 1151 | repResult.Technique = "CSS poisoning" |
| 1152 | |
| 1153 | webStruct, err := GetWebsite(Config.Website.Url.String(), false, false) // get body without cachebuster. TODO use response w/o cachebuster from recon, so it doesn't have to be fetched again |
| 1154 | if err != nil { |
| 1155 | msg := fmt.Sprintf("Error while fetching css files %s: %s\n", Config.Website.Url.String(), err.Error()) |
| 1156 | Print(msg, Red) |
| 1157 | repResult.ErrorMessages = append(repResult.ErrorMessages, msg) |
| 1158 | return repResult |
| 1159 | } |
| 1160 | bodyReader := strings.NewReader(webStruct.Body) // use body without cachebuster, so the css files can be found |
| 1161 | tokenizer := html.NewTokenizer(bodyReader) |
| 1162 | |
| 1163 | var urls []string |
| 1164 | |
| 1165 | eof := false |
| 1166 | for !eof { |
| 1167 | tokentype := tokenizer.Next() |
| 1168 | |
| 1169 | switch tokentype { |
| 1170 | case html.StartTagToken, html.SelfClosingTagToken: |
| 1171 | |
| 1172 | token := tokenizer.Token() |
| 1173 | |
| 1174 | if token.Data == "link" { |
| 1175 | for _, a := range token.Attr { |
| 1176 | if a.Key == "href" { |
| 1177 | if !strings.HasSuffix(a.Val, ".css") && !strings.Contains(a.Val, ".css?") { |
| 1178 | break |
| 1179 | } |
| 1180 | tempURL := addDomain(a.Val, Config.Website.Domain) |
| 1181 | if tempURL != "" { |
| 1182 | urls = append(urls, tempURL) |
| 1183 | } |
| 1184 | break |
| 1185 | } |
| 1186 | } |
| 1187 | } |
| 1188 | // When EOF is reached a html.ErrorToken appears |
| 1189 | case html.ErrorToken: |
| 1190 | err := tokenizer.Err() |
| 1191 | if err == io.EOF { |
| 1192 | eof = true |
| 1193 | break |
| 1194 | } |
| 1195 | msg := fmt.Sprintf("error tokenizing HTML: %+v", tokenizer.Err()) |
| 1196 | Print(msg, Yellow) |
| 1197 | } |
| 1198 | } |
| 1199 | |
| 1200 | if len(urls) == 0 { |
| 1201 | msg := "No CSS files were found.\n" |
| 1202 | PrintVerbose(msg, Yellow, 1) |
| 1203 | |
| 1204 | return repResult |
| 1205 | } |
| 1206 | msg := fmt.Sprintf("Testing the following CSS files for poisoning\n%s\n", urls) |
no test coverage detected