web-dev-qa-db-fra.com

Comment valider et désinfecter HTTP Get avec Spring Boot?

Je continue à recevoir cette erreur gênante du scanner de code Checkmarx,

Method getTotalValue at line 220 of src\Java\com\example\PeopleController.Java 
gets user input for the personName element. This element’s value then flows through
the code without being properly sanitized or validated and is eventually 
displayed to the user. This may enable a Cross-Site-Scripting attack. 

Voici mon code. Je pense que j'ai fait TOUTE la validation nécessaire. Quoi d'autre ???

@Slf4j
@Configuration
@RestController
@Validated 

public class PeopleController {

    @Autowired
    private PeopleRepository peopleRepository; 

    @RequestMapping(value = "/api/getTotalValue/{personName}", method = RequestMethod.GET)
    @ResponseBody
    public Integer getTotalValue(@Size(max = 20, min = 1, message = "person is not found") 
    @PathVariable(value="personName", required=true) String personName) {

        PersonObject po = peopleRepository.findByPersonName(
                            Jsoup.clean(personName, Whitelist.basic()));

        try {
            return po.getTotalValue(); 
            } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }  


@ExceptionHandler
    public String constraintViolationHandler(ConstraintViolationException ex) {
        return ex.getConstraintViolations().iterator().next()
                .getMessage();
    } 

} 

Il doit y avoir une validation manquante. Comment valider correctement HTTP GET avec Spring Boot

3
john

Vous devez être un peu prudent avec ces outils d'analyse car parfois ces outils signalent des faux positifs et parfois aucune modification de code n'est requise. Je ne suis pas un expert de checkmarx mais assurez-vous que cet outil comprend vraiment les annotations de validation de bean que vous utilisez et l'appel Jsoup.clean(personName, Whitelist.basic()).

Je pense que j'ai fait TOUTE la validation nécessaire. Quoi d'autre???

Vous devez d'abord comprendre les différences entre la validation des entrées entre le niveau d'application et le niveau métier pour un contrôleur. Ce que vous faites ici est la deuxième partie et la première peut être manquante dans votre configuration, ce qui se fait exclusivement du point de vue de la sécurité et généralement configuré pour l'application entière.

Vous utilisez l'annotation @Size Pour limiter la taille d'une entrée, mais cela ne garantit pas les chaînes incorrectes - les chaînes qui peuvent provoquer des attaques XSS. Ensuite, vous utilisez l'appel Jsoup.clean(personName, Whitelist.basic())) pour nettoyer cette entrée validée par la taille. Comme je ne suis pas sûr de ce que cet appel fait, vous devez vous assurer que la nouvelle valeur est XSS - Safe. Vous passez immédiatement cette valeur à l'appel de la base de données, puis renvoyez un Integer à l'appelant/client, donc je suis très pessimiste quant à toute possibilité d'attaque XSS ici, mais l'outil le dit.

Il doit y avoir une validation manquante. Comment valider correctement HTTP GET avec Spring Boot

Comme je l'ai expliqué précédemment, la validation des entrées est un terme généralement destiné à la validation des entrées au niveau de la logique métier tandis que le nettoyage/nettoyage des entrées concerne la sécurité. Dans l'environnement Spring Boot, cela se fait généralement en utilisant les API de sécurité Spring et en activant les filtres XSS ou en écrivant votre propre filtre XSS et en le connectant à votre application. Le filtre vient en premier et votre contrôleur plus tard, de sorte que votre contrôleur aura toujours une valeur filtrée et vous appliquerez des validations commerciales sur cette valeur filtrée.

Ceci est une réponse de niveau large et pour le code, etc., vous pouvez faire Google. Suggérez également d'en savoir plus sur les attaques XSS. Comprenez simplement qu'il existe plusieurs façons d'atteindre le même objectif.

façons d'empêcher XSS

prévention XSS en Java

Comment créer un filtre dans Spring RESTful pour Prevent XSS?

Tutoriel d'attaque Cross Site Scripting (XSS) avec exemples, types et prévention

Dans le dernier lien, son mentionné,

La première étape de la prévention de cette attaque est la validation des entrées. Tout ce qui est entré par l'utilisateur doit être validé avec précision, car l'entrée de l'utilisateur peut trouver son chemin vers la sortie.

& que vous ne faites pas dans votre code donc je suppose qu'il n'y a pas de XSS.

MODIFIER:

Il y a deux aspects de la sécurité XSS - premièrement, ne pas autoriser les entrées malveillantes sur le code côté serveur et cela se ferait en ayant un filtre XSS & Parfois, il n'y a aucun mal à autoriser les entrées malveillantes (disons que vous enregistrez cette entrée malveillante dans la base de données ou retour en réponse API).

Le deuxième aspect est d'instruire les clients HTML sur les attaques XSS possibles (si nous savons avec certitude que le client API sera HTML/UI), nous devons ajouter l'en-tête X-XSS-Protection Et cela se ferait par le code ci-dessous. Cela permettra au navigateur d'activer sa fonction de protection XSS (le cas échéant).

@Override protected void configure (HttpSecurity http) lève une exception {

http.headers().xssProtection()....

}

Qu'est-ce que l'en-tête http "X-XSS-Protection"?

La protection Xss dans la sécurité Spring est-elle activée par défaut?

Pour le premier aspect, c'est-à-dire le filtre d'écriture - reportez-vous ma cette réponse et les liens dans cette réponse.

Je pense que j'ai écrit à tort ci-dessus que Spring Security fournit des filtres d'assainissement d'entrée, je suppose que non. Vérifie et vous informe. J'ai écrit mon filtre personnalisé sur les lignes mentionnées en réponse à cette question - Empêcher XSS dans le contrôleur Spring MVC

Vous devez également comprendre que Spring Boot est également utilisé pour écrire des applications MVC traditionnelles là où le côté serveur présente du HTML pour le rendu. En cas de réponses JSON (REST), le client d'interface utilisateur peut contrôler ce qui doit s'échapper et ce qui ne l'est pas, la complexité survient parce que la sortie JSON n'est pas toujours alimentée par les navigateurs des clients HTML.

3
Sabir Khan

J'ai une excellente solution (à mon humble avis) avec Jsoup et Apache Commons. J'espère que cela aidera d'autres personnes

Ajouter cette classe

import org.Apache.commons.lang.StringEscapeUtils;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;

public class SecurityEscape {

    public static String cleanIt(String arg0) {
        return Jsoup.clean(
                StringEscapeUtils.escapeHtml(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeSql(arg0)))
                , Whitelist.basic());
    }


} 

Vous pouvez maintenant nettoyer toutes les chaînes entrantes de GET ou POST comme ceci dans votre contrôleur

    @PostMapping("/api/blah") or GET whatever . .. . .  .
    public ResponseEntity<?> testIt(String whatever) { 

String whatever = SecurityEscape.cleanIt(whatever); 

... .. 

APRÈS CE CHECKMARX DIT CECI IS UN CODE SÛR

Remerciements particuliers à @Sabir Khan pour ses conseils

4
john