# SPDX-License-Identifier: CC-BY-4.0
#
# profiles/expose_public_https_web_service/fiche.yaml
# Fiche NeuralWall — Exposer un service web HTTPS public vers la DMZ
#
# Scénario adversarial n°1 : ingress HTTPS depuis Internet, déchiffrement ENTRANT,
# dépendances DNS, profils de sécurité complets.
# Consulter docs/control-taxonomy.md pour le vocabulaire canonique.

# ─────────────────────────────────────────────────
# FRONTMATTER
# ─────────────────────────────────────────────────

# schema_version : version du CONTRAT d'ingestion (invariant 7).
# Distinct de `version` (contenu de la fiche).
schema_version: "1.0.0"

# id : clé primaire snake_case stable — correspond au nom du dossier.
id: expose_public_https_web_service

# version : semver du CONTENU de la fiche.
# 1.0.0 = version initiale complète, pas encore revue par un mainteneur.
version: "1.0.0"

# trust_tier : niveau de confiance pondéré par NeuralWall à l'ingestion (ADR-0002 §3).
# reviewed = passée en revue par un mainteneur avant merge.
trust_tier: reviewed

title:
  fr: "Exposition d'un service web HTTPS public depuis Internet vers la DMZ"
  en: "Exposing a public HTTPS web service from the Internet to the DMZ"

description:
  fr: |
    Ce scénario couvre l'exposition d'un serveur web HTTPS hébergé en DMZ et accessible
    depuis Internet. Il inclut le déchiffrement SSL entrant (ssl_inbound_inspection) pour
    permettre l'inspection L7 du trafic chiffré, ainsi que les règles de dépendance DNS
    nécessaires au bon fonctionnement du service. Ce scénario est particulièrement sensible :
    le serveur exposé est une cible directe pour l'exploitation de vulnérabilités publiques,
    l'injection de charge utile et l'utilisation détournée du service comme relais C2.
    Les profils de sécurité complets (antivirus, IPS, c2_protection, url_filtering,
    file_control, sandboxing) sont obligatoires sur la règle allow principale.
  en: |
    This scenario covers exposing an HTTPS web server hosted in the DMZ and reachable
    from the Internet. It includes inbound SSL decryption (ssl_inbound_inspection) to
    enable L7 inspection of encrypted traffic, along with the DNS dependency rules
    required for the service to function. This scenario is particularly sensitive: the
    exposed server is a direct target for public-facing application exploitation, payload
    injection, and use of the service as a C2 relay. Full security profiles (antivirus,
    IPS, c2_protection, url_filtering, file_control, sandboxing) are mandatory on the
    main allow rule.

authors:
  - name: "NeuralWall Rules Team"
    email: "rules@neuralwall.io"
    org: "NeuralWall"

# includes : réservé à la composition Phase 2+. Omis en Phase 1 (fiches auto-contenues).

# ─────────────────────────────────────────────────
# THREAT CONTEXT — Champs AUTEURÉS (invariant 5, ADR-0002 §2)
# Ne pas déduire des enums — saisie experte obligatoire.
# ─────────────────────────────────────────────────

mitre_attack:
  # T1190 : l'attaquant exploite une vulnérabilité du service exposé directement
  # accessible depuis Internet (serveur web, CMS, API publique).
  - technique_id: "T1190"
    name: "Exploit Public-Facing Application"
    tactic: "initial-access"

  # T1071.001 : une fois un accès initial obtenu (ou via un agent implanté),
  # l'attaquant utilise HTTP/HTTPS comme canal de command-and-control discret.
  - technique_id: "T1071.001"
    name: "Application Layer Protocol: Web Protocols"
    tactic: "command-and-control"

  # T1105 : transfert d'outils ou de charges utiles additionnelles vers le
  # serveur compromis via le canal HTTPS entrant (ingress tool transfer).
  - technique_id: "T1105"
    name: "Ingress Tool Transfer"
    tactic: "command-and-control"

  # T1059 : exécution de commandes ou de scripts via l'exploitation du service
  # web (injection, deserialization, RCE via upload).
  - technique_id: "T1059"
    name: "Command and Scripting Interpreter"
    tactic: "execution"

threat_model:
  summary:
    fr: |
      Un service web exposé directement sur Internet constitue la surface d'attaque la
      plus large d'un périmètre. L'attaquant cherche à exploiter une vulnérabilité
      applicative (CVE publique, injection, mauvaise configuration) pour obtenir un
      accès initial sur la DMZ, puis progresser latéralement vers le réseau interne.
      Sans déchiffrement SSL entrant, l'inspection L7 est aveugle : antivirus, IPS et
      sandboxing ne voient qu'un flux opaque. Avec ssl_inbound_inspection, le flux est
      re-chiffré côté serveur après inspection — le certificat serveur doit être importé
      dans le firewall.
    en: |
      A web service directly exposed to the Internet represents the widest attack surface
      of a perimeter. The attacker attempts to exploit an application vulnerability
      (public CVE, injection, misconfiguration) to gain initial access on the DMZ, then
      move laterally toward the internal network. Without inbound SSL decryption, L7
      inspection is blind: antivirus, IPS, and sandboxing see only an opaque stream.
      With ssl_inbound_inspection, the stream is re-encrypted toward the server after
      inspection — the server certificate must be imported into the firewall.
  attacker_goal:
    fr: |
      Obtenir un accès initial sur le serveur DMZ via l'exploitation du service HTTPS
      public, déposer une charge utile ou un implant, puis établir un canal C2 sortant
      ou pivoter vers le réseau interne (élévation de privilèges, mouvement latéral).
    en: |
      Gain initial access on the DMZ server by exploiting the public HTTPS service,
      drop a payload or implant, then establish an outbound C2 channel or pivot into
      the internal network (privilege escalation, lateral movement).
  key_controls:
    - ssl_inbound_inspection   # Sans déchiffrement entrant, IPS/AV/sandboxing sont aveugles
    - ips                      # Détection des exploits applicatifs (CVE, RCE, injection)
    - antivirus                # Inspection des fichiers uploadés et des charges utiles
    - sandboxing               # Détonation des fichiers inconnus — couverture 0-day
    - c2_protection            # Blocage des communications de type command-and-control
    - file_control             # Blocage des types de fichiers dangereux en upload entrant
    - dns_security             # Sinkhole des requêtes DNS malveillantes depuis la DMZ

# ─────────────────────────────────────────────────
# RULES — Règles du scénario complet (ADR-0002 §1)
# Règle 1 : flux HTTPS entrant principal (internet -> dmz)
# Règle 2 : dépendance DNS sortante depuis la DMZ (dmz -> internal)
# Règle 3 : deny par défaut sur la DMZ (défense en profondeur)
# ─────────────────────────────────────────────────

rules:

  # ── Règle 1 : Flux HTTPS entrant principal ──────────────────────────────────
  # Posture next-gen : identification L7 (web_browsing + ssl), pas uniquement tcp/443.
  # Le déchiffrement ssl_inbound_inspection est OBLIGATOIRE ici : sans lui, tous les
  # profils d'inspection (antivirus, ips, sandboxing) voient un tunnel opaque et sont
  # réduits à une inspection de métadonnées uniquement.
  - application:
      app_id: web_browsing
      category: general_internet
      default_ports:
        - tcp/443
        - tcp/80
      # depends_on : dns est requis pour que les clients résolvent le FQDN du service.
      # Cette dépendance justifie la règle DNS (règle 2 ci-dessous).
      depends_on:
        - dns
        - ssl
      # risk=4 : service public exposé, vecteur d'accès initial classique (T1190).
      risk: 4

    zones:
      source:
        - internet
      destination:
        - dmz

    direction: inbound

    service:
      protocol: tcp
      ports:
        - "443"
        - "80"
      # app_default: true — posture next-gen recommandée ; les ports sont donnés
      # ci-dessus pour le contrôle de cohérence uniquement.
      app_default: true

    action: allow

    # security_profiles : TOUS les profils pertinents sont activés.
    # Une règle allow sans security_profiles sur un service public est un anti-pattern
    # critique (CLAUDE.md posture par défaut).
    security_profiles:

      # antivirus : inspection des fichiers et contenus uploadés via HTTP/HTTPS.
      # action: block — tout fichier malveillant détecté est bloqué, pas seulement alerté.
      antivirus:
        action: block

      # ips : protection contre les exploits applicatifs (CVE publiques, injections, RCE).
      # min_severity: medium — on bloque dès "medium" pour ne pas manquer les CVE CVSS ≥5.
      # Sur un service public, la tolérance aux faux positifs est plus basse que sur l'interne.
      ips:
        action: block
        min_severity: medium

      # c2_protection : détection des comportements de type command-and-control dans le flux
      # HTTP entrant (ex. beacon périodique, tunneling DNS-over-HTTP).
      # min_severity: low — seuil bas car les agents C2 modernes sont discrets.
      c2_protection:
        action: block
        min_severity: low

      # url_filtering : même en entrant, le filtrage de catégories permet de bloquer
      # les requêtes vers des paths associés à des patterns malveillants connus
      # (ex. proxies d'évitement, domaines de phishing relayés).
      url_filtering:
        block_categories:
          - malware
          - phishing
          - c2
          - newly_registered_domain
          - proxy_avoidance
          - hacking
          - compromised
        # uncategorized_action : bloque les requêtes vers des domaines non catégorisés.
        uncategorized_action: block

      # file_control : blocage des types de fichiers dangereux en upload entrant.
      # pe (Portable Executable), scripts, archives chiffrées souvent utilisés en ingress
      # tool transfer (T1105). Direction inbound car on contrôle ce que l'attaquant pousse.
      file_control:
        block_types:
          - "pe"
          - "elf"
          - "script"
          - "encrypted_archive"
        direction: inbound

      # sandboxing : détonation cloud des fichiers inconnus ou suspects.
      # Couverture 0-day indispensable sur un service public exposé.
      sandboxing:
        enabled: true
        file_types:
          - "pe"
          - "pdf"
          - "office"
          - "jar"
          - "script"

    # decryption : ssl_inbound_inspection est OBLIGATOIRE sur ce flux.
    # Sans déchiffrement entrant, l'inspection L7 (antivirus, ips, sandboxing) est aveugle.
    # Le certificat TLS du serveur DMZ doit être importé dans le firewall pour que
    # la terminaison SSL + ré-encryption côté serveur fonctionne.
    # Pas d'exclusions ici : c'est un service d'entreprise, pas une app de santé ou finance.
    decryption:
      mode: ssl_inbound_inspection

    logging:
      log_start: false
      # log_end: true — journalisation systématique de chaque session terminée.
      log_end: true
      # log_forwarding: true — envoi vers le SIEM pour corrélation et triage SOC.
      log_forwarding: true
      profile: "siem_high_priority"

    rationale:
      fr: |
        Cette règle autorise le trafic HTTPS entrant d'Internet vers le serveur web en DMZ.
        Le déchiffrement ssl_inbound_inspection est activé pour permettre l'inspection L7 :
        sans lui, antivirus, IPS et sandboxing voient un flux opaque et ne peuvent pas
        détecter les exploits ni les charges utiles. Les profils de sécurité sont tous
        activés en mode blocage (pas seulement alerte) car la surface d'attaque est maximale
        sur un service public. Le port 80 est inclus pour la redirection HTTP→HTTPS ; une
        règle de redirection applicative côté serveur est recommandée en complément.
      en: |
        This rule allows inbound HTTPS traffic from the Internet to the DMZ web server.
        The ssl_inbound_inspection decryption mode is enabled to allow L7 inspection:
        without it, antivirus, IPS, and sandboxing see an opaque stream and cannot detect
        exploits or payloads. Security profiles are all set to blocking mode (not just alert)
        because the attack surface is maximal on a public-facing service. Port 80 is included
        for HTTP→HTTPS redirection; a server-side redirect rule is recommended in addition.

  # ── Règle 2 : Dépendance DNS depuis la DMZ vers le résolveur interne ────────
  # La DMZ a besoin de résoudre des noms DNS (pour les dépendances amont du service,
  # les vérifications OCSP/CRL, les mises à jour, etc.).
  # Cette règle est distincte de la règle principale : flux différent (dmz->internal),
  # direction interne (est-ouest), pas de déchiffrement (DNS UDP non chiffré par nature).
  # Le profil dns_security avec sinkhole atténue l'utilisation de DNS comme canal C2
  # (T1071.001 via DNS tunneling) depuis la DMZ.
  - application:
      app_id: dns
      category: networking
      default_ports:
        - udp/53
        - tcp/53
      risk: 2

    zones:
      source:
        - dmz
      destination:
        - internal

    # direction: internal — flux est-ouest entre zones internes (DMZ vers résolveur).
    direction: internal

    service:
      protocol: udp
      ports:
        - "53"
      app_default: true

    action: allow

    security_profiles:
      # dns_security + sinkhole : atténue le tunneling DNS (C2 via DNS depuis la DMZ).
      # Un serveur compromis en DMZ peut tenter d'établir un canal C2 via des requêtes
      # DNS vers des domaines malveillants — le sinkhole redirige ces réponses.
      dns_security:
        action: block
        sinkhole: true

    # decryption mode: none — DNS UDP est un protocole non chiffré par nature.
    # Le déchiffrement est non applicable ici (pas de TLS sur UDP/53 standard).
    # Ce n'est pas un anti-pattern : la taxonomie documente que none est justifiable
    # quand le protocole ne supporte pas le chiffrement.
    decryption:
      mode: none

    logging:
      log_end: true
      log_forwarding: true
      profile: "siem_default"

    rationale:
      fr: |
        La résolution DNS est requise pour le bon fonctionnement du service web en DMZ
        (résolution OCSP/CRL pour la validation de certificats, dépendances amont, mises
        à jour). Le flux est restreint vers un résolveur interne de confiance (pas
        directement vers Internet) pour éviter le DNS rebinding et limiter la surface
        d'exfiltration. Le profil dns_security avec sinkhole bloque le tunneling DNS
        qui pourrait être utilisé comme canal C2 discret depuis un serveur compromis.
        Déchiffrement non applicable : DNS UDP standard n'est pas chiffré.
      en: |
        DNS resolution is required for the DMZ web service to function properly (OCSP/CRL
        resolution for certificate validation, upstream dependencies, updates). The flow
        is restricted to a trusted internal resolver (not directly to the Internet) to
        prevent DNS rebinding and limit the exfiltration surface. The dns_security profile
        with sinkhole blocks DNS tunneling that could be used as a covert C2 channel from
        a compromised server. Decryption not applicable: standard DNS over UDP is not
        encrypted.

  # ── Règle 3 : Deny par défaut — tout autre trafic sortant depuis la DMZ ─────
  # Principe de moindre privilège : la DMZ ne doit pas pouvoir initier de connexions
  # arbitraires vers Internet ou le réseau interne. Cette règle drop couvre les flux
  # non explicitement autorisés (ex. tentative d'exfiltration via un port non standard,
  # connexion directe Internet depuis la DMZ).
  # Note : une règle drop/deny explicite renforce la lisibilité de la politique de sécurité
  # et facilite l'audit. Le linter NeuralWall n'exige pas cette règle, mais les bonnes
  # pratiques de segmentation la recommandent.
  - application:
      app_id: any_application
      category: unknown
      risk: 5

    zones:
      source:
        - dmz
      destination:
        - internet

    direction: outbound

    service:
      protocol: any

    # action: drop — blocage silencieux ; pas de réponse à l'émetteur (discret).
    # Pas de security_profiles sur action=drop (logiquement non applicable).
    action: drop

    logging:
      # log_start: true ici uniquement — pour détecter les tentatives (forensic).
      log_start: true
      log_end: true
      log_forwarding: true
      profile: "siem_high_priority"

    rationale:
      fr: |
        Règle de deny-by-default : tout trafic initié depuis la DMZ vers Internet qui
        n'est pas explicitement couvert par une règle allow ci-dessus est bloqué
        silencieusement. Cette règle est critique pour contenir un serveur DMZ compromis
        et empêcher l'établissement d'un canal C2 sortant (T1071.001) ou l'exfiltration
        de données. L'app_id 'any_application' avec category 'unknown' est justifié ici :
        il s'agit d'une règle de blocage de "catch-all", non d'une règle allow.
      en: |
        Deny-by-default rule: any traffic initiated from the DMZ toward the Internet that
        is not explicitly covered by an allow rule above is silently dropped. This rule is
        critical to contain a compromised DMZ server and prevent the establishment of an
        outbound C2 channel (T1071.001) or data exfiltration. The 'any_application' app_id
        with 'unknown' category is justified here: this is a catch-all blocking rule, not
        an allow rule.
