Serwis używa plików cookies, aby mógł lepiej spełniać Państwa oczekiwania. Podczas korzystania z serwisu pliki te są zapisywane w pamięci urządzenia. Zapisywanie plików cookies można zablokować, zmieniając ustawienia przeglądarki. Więcej o plikach cookies możesz przeczytać tutaj.

Autorzy więcej

Audyt infrastruktury sieciowej — Bramka WAF systemu KSeF 2.0

Czy bramkę bezpieczeństwa WAF systemu KSeF obsługuje zagraniczna firma Imperva w chmurze, czy on-premises — i czy chodzi tu o obecne, produkcyjne API KSeF 2.0?

Audyt infrastruktury sieciowej — Bramka WAF systemu KSeF 2.0
źródło: GPS

api.ksef.mf.gov.pl — środowisko produkcyjne | Raport techniczny, marzec 2026

Przedmiot audytu api.ksef.mf.gov.pl (KSeF 2.0, produkcja)
Metoda Pasywny rekonesans sieciowy + aktywne testy filtracji WAF
Data Marzec 2026
Środowisko testowe PowerShell 5.1+ / Windows, Play Polska (PL)

1. Pytanie audytowe

Czy bramkę bezpieczeństwa WAF systemu KSeF obsługuje zagraniczna firma Imperva w chmurze, czy on-premises — i czy chodzi tu o obecne, produkcyjne API KSeF 2.0?

Pytanie dotyczy dwóch kwestii: (a) modelu deploymentu ochrony WAF — cloud vs. on-premises, oraz (b) weryfikacji, czy diagnozowane środowisko jest faktycznym środowiskiem produkcyjnym KSeF 2.0. Audyt odpowiada na oba pytania na podstawie twardych śladów infrastrukturalnych zebranych metodami pasywnymi, uzupełnionymi o aktywne testy zachowania warstwy filtrującej.


2. Metodologia i zakres

Audyt składa się z sześciu kroków pomiarowych wykonanych sekwencyjnie. Kroki 1–4 opierają się na pasywnym rekonesansie (DNS, TLS, HTTP fingerprinting, traceroute, WHOIS/RIPE). Kroki 5–6 to aktywne testy weryfikujące, czy warstwa Impervy aktywnie pośredniczy i filtruje ruch oraz jakie warstwy infrastruktury kryją się za nią.

Krok Technika Cel
1 DNS CNAME — multi-resolver (Google, Cloudflare, system) Weryfikacja delegacji DNS i trwałości rekordu
2 Inspekcja certyfikatu TLS (X.509) Identyfikacja certyfikatu prezentowanego przez edge
3 Traceroute + ASN / WHOIS / RIPE RDAP Fizyczna trasa ruchu, przynależność IP, podmioty prawne
4 HTTP headers fingerprinting (GET, HEAD) Identyfikacja warstwy WAF i stosu backendowego
5 POST control vs. POST probe (SQLi, XSS, path traversal) Dowód aktywnej filtracji ruchu przez WAF
6 TRACE / HEAD / OPTIONS — wykrywanie warstw Identyfikacja warstw infrastruktury za Impervą

3. Krok 1 — Wielopunktowa weryfikacja DNS

3.1 Komenda PowerShell

$hostName = "api.ksef.mf.gov.pl"
$resolvers = @{
    "Google (8.8.8.8)"     = "8.8.8.8"
    "Cloudflare (1.1.1.1)" = "1.1.1.1"
    "System (domyślny)"    = $null
}
foreach ($label in $resolvers.Keys) {
    $params = @{ Name = $hostName; Type = "CNAME" }
    if ($resolvers[$label]) { $params["Server"] = $resolvers[$label] }
    Resolve-DnsName @params | Select-Object Name, Type, TTL, NameHost | Format-Table
}

3.2 Wynik

=== DNS CNAME via Google (8.8.8.8) ===
api.ksef.mf.gov.pl  CNAME  55  hju8yoo.ng.impervadns.net

=== DNS CNAME via System (domyślny) ===
api.ksef.mf.gov.pl  CNAME  55  hju8yoo.ng.impervadns.net

=== DNS CNAME via Cloudflare (1.1.1.1) ===
api.ksef.mf.gov.pl  CNAME  60  hju8yoo.ng.impervadns.net

3.3 Interpretacja

Wszystkie trzy niezależne resolvery zwracają identyczny cel CNAME: hju8yoo.ng.impervadns.net. CNAME wskazuje na domenę impervadns.net, związaną z infrastrukturą Impervy. Spójność wyniku na trzech niezależnych resolverach wyklucza scenariusz tymczasowego lub lokalnego przekierowania.

Wynik wskazuje na chmurową warstwę edge Impervy jako publiczny front usługi, a nie lokalny front on-premises. Delegacja CNAME do domeny Impervy wskazuje na chmurową warstwę edge jako publiczny front usługi, a nie na lokalny front on-premises.

Obserwacja Wartość Wniosek
Cel CNAME hju8yoo.ng.impervadns.net DNS wskazuje na chmurową warstwę edge Impervy, a nie lokalny front on-premises
Spójność resolverów 3/3 identyczne Wyklucza tymczasowe lub lokalne przekierowanie

4. Krok 2 — Inspekcja certyfikatu TLS

4.1 Komenda PowerShell

Add-Type @"
using System.Net; using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
public class CertGrabber {
    public static X509Certificate2 GetCert(string host) {
        X509Certificate2 captured = null;
        var req = (HttpWebRequest)WebRequest.Create("https://" + host + "/");
        req.ServerCertificateValidationCallback = (s, cert, chain, err) => {
            captured = new X509Certificate2(cert); return true; };
        try { req.GetResponse().Close(); } catch {}
        return captured; } }
"@
$cert = [CertGrabber]::GetCert("api.ksef.mf.gov.pl")
"Subject: {0}" -f $cert.Subject
"Issuer:  {0}" -f $cert.Issuer
"Valid:   {0} — {1}" -f $cert.NotBefore, $cert.NotAfter

4.2 Wynik

Subject:    CN=*.ksef.mf.gov.pl, O=MINISTERSTWO FINANSÓW, L=Warszawa, C=PL
Issuer:     CN=GeoTrust TLS RSA CA G1, OU=www.digicert.com, O=DigiCert Inc, C=US
Valid From: 08.12.2025 01:00:00
Valid To:   08.12.2026 00:59:59
Thumbprint: 6AF8575E9149E4B62C04027912951BFF43A75DEE

4.3 Interpretacja

Certyfikat wildcard *.ksef.mf.gov.pl jest wystawiony na Ministerstwo Finansów przez DigiCert/GeoTrust. Usługa prezentuje ten certyfikat klientom łączącym się z api.ksef.mf.gov.pl — co jest spójne z modelem, w którym warstwa edge posługuje się certyfikatem domeny chronionej. Sam certyfikat nie rozstrzyga modelu zarządzania kluczem prywatnym ani miejsca terminacji TLS.


5. Krok 3 — Trasa ruchu i jurysdykcja węzłów

5.1 Komenda PowerShell

$hostName = "api.ksef.mf.gov.pl"
$targetIP = (Resolve-DnsName $hostName -Type A -Server 8.8.8.8 |
    Where-Object { $_.Type -eq "A" } | Select-Object -First 1).IPAddress
tracert -h 20 -w 1000 $hostName

foreach ($ip in @("213.248.77.211","131.125.134.75","45.60.74.103")) {
    Invoke-RestMethod "https://rdap.db.ripe.net/ip/$ip" | Select-Object handle, name, country
}

5.2 Wynik

Docelowy IP: 45.60.74.103

 1  <1ms   192.168.1.1
 2    8ms   10.161.192.1
 3    7ms   89-75-3-8.infra.play.pl [89.75.3.8]
 4   25ms   pl-waw10a-rc1_ae48.0.as9141.pl [185.182.246.0]
 5    9ms   pl-waw26c-ri1_ae2.0.as9141.pl [185.182.244.29]
 6   13ms   war-b8-link.ip.twelve99.net [62.115.182.116]
 7   24ms   hbg-bb2-link.ip.twelve99.net [62.115.141.150]
 8   29ms   ddf-b3-link.ip.twelve99.net [62.115.135.155]
 9   27ms   imperva-ic-379643.ip.twelve99-cust.net [213.248.77.211]
10   29ms   131.125.134.75   [Imperva Ltd., IL — blok 131.125.128.0/17]
11   28ms   45.60.74.103     [Incapsula Inc, USA — blok 45.60.0.0/16, AS19551]

5.3 Interpretacja

Ścieżka prowadzi przez infrastrukturę operatorską Arelion/Twelve99 do punktu styku z Impervą. W widocznej trasie pojawia się węzeł imperva-ic-379643.ip.twelve99-cust.net, a następnie dwa adresy z bloków przypisanych w RIPE do podmiotów Impervy: blok 131.125.128.0/17 zarejestrowany na Imperva Ltd. w Izraelu oraz blok 45.60.0.0/16 zarejestrowany na Incapsula Inc w USA.

IP Blok CIDR Podmiot RIPE Kraj rejestracji
213.248.77.211 213.248.64.0/19 Twelve99 / Arelion (Telia Carrier) UE / Szwecja
131.125.134.75 131.125.128.0/17 Imperva Ltd. Izrael (IL)
45.60.74.103 45.60.0.0/16 Incapsula Inc USA

W przeprowadzonym teście latencja do węzła końcowego wyniosła 27–31 ms z Polski. Niska latencja sugeruje, że punkt obsługi ruchu znajduje się geograficznie bliżej Polski niż typowa lokalizacja w kontynentalnych USA, choć bloki IP są zarejestrowane na podmioty z USA i Izraela.


6. Krok 4 — Fingerprinting warstwy HTTP

6.1 Komenda PowerShell

$req = [System.Net.HttpWebRequest]::Create("https://api.ksef.mf.gov.pl/")
$req.Method = "GET"
$req.AllowAutoRedirect = $false
try { $resp = $req.GetResponse() }
catch [System.Net.WebException] { $resp = $_.Exception.Response }
foreach ($key in $resp.Headers.AllKeys) {
    "{0,-35} {1}" -f $key, $resp.Headers[$key]
}

6.2 Wynik

GET / → HTTP 302 (Redirect → /docs/v2)

Server:        Kestrel
X-CDN:         Imperva
X-Iinfo:       62-59611270-59597222 pNNN RT(1773355916122 62) q(0 0 0 5) r(0 0) U11
Set-Cookie:    visid_incap_3296082=...; HttpOnly; Secure; SameSite=None
               incap_ses_1855_3296082=...; Secure; SameSite=None

6.3 Interpretacja

Odpowiedź HTTP dostarcza trzech niezależnych śladów identyfikujących warstwę Impervy:

  • X-CDN: Imperva — jawny fingerprint warstwy edge Impervy.
  • Ciasteczka visid_incap_* i incap_ses_* — charakterystyczne dla platformy Incapsula / Imperva.
  • X-Iinfo — dodatkowy nagłówek warstwy pośredniej, pojawiający się razem z fingerprintami Impervy.

Nagłówek Server: Kestrel wskazuje, że za warstwą pośrednią znajduje się backend oparty na ASP.NET Core.


7. Krok 5 — Aktywna filtracja: POST control vs. POST probe

7.1 Komenda PowerShell

$auth = "https://api.ksef.mf.gov.pl/api/online/Session/AuthorisationChallenge"

function Invoke-Probe($label, $body, $ct) {
    $req = [System.Net.HttpWebRequest]::Create($auth)
    $req.Method = "POST"; $req.ContentType = $ct
    $req.AllowAutoRedirect = $false; $req.Timeout = 10000
    $bytes = [System.Text.Encoding]::UTF8.GetBytes($body)
    $req.ContentLength = $bytes.Length
    $s = $req.GetRequestStream(); $s.Write($bytes,0,$bytes.Length); $s.Close()
    try   { $resp = $req.GetResponse() }
    catch [System.Net.WebException] { $resp = $_.Exception.Response }
    if ($resp) {
        $code   = [int]$resp.StatusCode
        $server = if ($resp.Headers["Server"]) { $resp.Headers["Server"] } else { "(brak)" }
        $xcdn   = if ($resp.Headers["X-CDN"])  { $resp.Headers["X-CDN"]  } else { "(brak)" }
        "[{0}] HTTP {1} | Server: {2} | X-CDN: {3}" -f $label,$code,$server,$xcdn
        $resp.Close()
    } else { "[{0}] Brak odpowiedzi HTTP" -f $label }
}

Invoke-Probe "CONTROL JSON" '{"contextIdentifier":{"type":"onip","identifier":"1234563218"},"documentType":{"version":"FA(2)"},"encryptionKey":null}' "application/json"
Invoke-Probe "CONTROL XML"  '<?xml version="1.0"?><AuthorisationChallengeRequest xmlns="http://ksef.mf.gov.pl/schema/gtw/svc/online/auth/request/2021/10/01/0001"><ContextIdentifier><Type>onip</Type><Identifier>1234563218</Identifier></ContextIdentifier></AuthorisationChallengeRequest>' "application/octet-stream"
Invoke-Probe "PROBE SQLi"   "id=' OR '1'='1"              "application/x-www-form-urlencoded"
Invoke-Probe "PROBE XSS"    "<script>alert(1)</script>"   "text/plain"
Invoke-Probe "PROBE PATH"   "file=../../../../etc/passwd"  "application/x-www-form-urlencoded"

7.2 Wynik

[CONTROL JSON] HTTP 404 | Server: Kestrel | X-CDN: Imperva
[CONTROL XML ] HTTP 404 | Server: Kestrel | X-CDN: Imperva
[PROBE SQLi  ] Brak odpowiedzi HTTP
[PROBE XSS   ] Brak odpowiedzi HTTP
[PROBE PATH  ] HTTP 302 | Server: (brak) | X-CDN: (brak)

7.3 Interpretacja

Wynik testów stanowi bezpośredni dowód, że warstwa Impervy nie jest biernym elementem DNS ani ozdobnym CDN-em — aktywnie pośredniczy w ruchu HTTP i filtruje część żądań.

Żądanie Kod HTTP Server Interpretacja
CONTROL JSON 404 Kestrel Żądanie dotarło do backendu MF — warstwa Impervy przepuściła
CONTROL XML 404 Kestrel Żądanie dotarło do backendu MF — warstwa Impervy przepuściła
PROBE SQLi Brak odpowiedzi (brak) Połączenie zerwane przed odpowiedzią HTTP — backend MF nie był osiągany
PROBE XSS Brak odpowiedzi (brak) Połączenie zerwane przed odpowiedzią HTTP — backend MF nie był osiągany
PROBE PATH 302 (brak) Warstwa pośrednia odpowiedziała samodzielnie — backend niewidoczny w odpowiedzi

Przy żądaniach CONTROL obecność Server: Kestrel potwierdza dotarcie do backendu MF (HTTP 404 oznacza nieznany endpoint, nie błąd WAF). Przy PROBE SQLi i XSS PowerShell zgłosił wyjątek zamkniętego połączenia — jest to zachowanie charakterystyczne dla twardego zerwania połączenia TCP przez WAF (pakiet TCP RST). Taka polityka Drop, w odróżnieniu od odpowiedzi HTTP 403, jest celowym wyborem konfiguracyjnym: WAF nie odpowiada atakującemu żadnym kodem HTTP, oszczędzając zasoby i nie ujawniając faktu blokady. Backend MF nie był w tych przypadkach osiągany. Przy PROBE PATH warstwa pośrednia zwróciła samodzielnie kod 302, a nagłówki Server i X-CDN zniknęły z odpowiedzi.


8. Krok 6 — TRACE i wykrywanie warstw za Impervą

8.1 Komenda PowerShell

$urls = @(
    "https://api.ksef.mf.gov.pl/",
    "https://api.ksef.mf.gov.pl/docs/v2"
)
foreach ($url in $urls) {
    foreach ($method in @("TRACE","HEAD","OPTIONS")) {
        $req = [System.Net.HttpWebRequest]::Create($url)
        $req.Method = $method
        $req.AllowAutoRedirect = $false; $req.Timeout = 8000
        try   { $resp = $req.GetResponse() }
        catch [System.Net.WebException] { $resp = $_.Exception.Response }
        if ($resp) {
            $server = if ($resp.Headers["Server"]) { $resp.Headers["Server"] } else { "(brak)" }
            $xcdn   = if ($resp.Headers["X-CDN"])  { $resp.Headers["X-CDN"]  } else { "(brak)" }
            "{0,-10} {1,-45} → {2} | Server: {3} | X-CDN: {4}" -f $method,$url,[int]$resp.StatusCode,$server,$xcdn
            $resp.Close()
        }
    }
}

8.2 Wynik

TRACE      https://api.ksef.mf.gov.pl/          → 405 | Server: Microsoft-Azure-Application-Gateway/v2 | X-CDN: Imperva
HEAD       https://api.ksef.mf.gov.pl/          → 405 | Server: Kestrel | X-CDN: Imperva
OPTIONS    https://api.ksef.mf.gov.pl/          → 405 | Server: Kestrel | X-CDN: Imperva

TRACE      https://api.ksef.mf.gov.pl/docs/v2   → 405 | Server: Microsoft-Azure-Application-Gateway/v2 | X-CDN: Imperva
HEAD       https://api.ksef.mf.gov.pl/docs/v2   → 404 | Server: Kestrel | X-CDN: Imperva
OPTIONS    https://api.ksef.mf.gov.pl/docs/v2   → 404 | Server: Kestrel | X-CDN: Imperva

8.3 Interpretacja

Wynik jest powtarzalny i spójny na obu ścieżkach. Ujawnia trójwarstwową architekturę edge KSeF.

Metody HEAD i OPTIONS zwracają Server: Kestrel — potwierdzając backend ASP.NET Core widoczny przez warstwę Impervy. Metoda TRACE na obu ścieżkach zwraca natomiast Server: Microsoft-Azure-Application-Gateway/v2 przy jednoczesnej obecności X-CDN: Imperva. Oznacza to, że żądanie TRACE przeszło przez Impervę (X-CDN widoczny), lecz odpowiedź 405 zwróciła wewnętrzna warstwa identyfikująca się jako Azure Application Gateway v2 — ujawniając swoją obecność między Impervą a backendem Kestrel.

Metoda Ścieżka Kod Server Interpretacja
HEAD / i /docs/v2 405 / 404 Kestrel Backend ASP.NET Core widoczny przez warstwę Impervy
OPTIONS / i /docs/v2 405 / 404 Kestrel Backend ASP.NET Core widoczny przez warstwę Impervy
TRACE / i /docs/v2 405 Microsoft-Azure-Application-Gateway/v2 Wewnętrzna warstwa Azure ujawnia się — obecna między Impervą a Kestrel

Różnica w zachowaniu między TRACE a HEAD/OPTIONS wynika z tego, jak poszczególne warstwy obsługują różne metody HTTP. HEAD i OPTIONS są przepuszczane do backendu Kestrel, który odpowiada bezpośrednio. TRACE jest obsługiwany przez Azure Application Gateway przed dotarciem do Kestrel — co powoduje, że to właśnie ta warstwa ujawnia się w odpowiedzi.


9. Zestawienie dowodów

# Dowód Wartość Znaczenie
1 CNAME hju8yoo.ng.impervadns.net DNS wskazuje na chmurową warstwę edge Impervy,  a nie lokalny front on-premises
2 Spójność DNS 3/3 resolverów — identyczny wynik Wyklucza tymczasowe lub lokalne przekierowanie
3 X-CDN: Imperva Nagłówek HTTP odpowiedzi Jawny fingerprint warstwy edge Impervy
4 Ciasteczka incap_* visid_incap_3296082, incap_ses_* Charakterystyczne dla platformy Incapsula/Imperva
5 X-Iinfo Nagłówek warstwy pośredniej Dodatkowy fingerprint pojawiający się razem ze śladami Impervy
6 Certyfikat TLS CN=*.ksef.mf.gov.pl, O=MINISTERSTWO FINANSÓW Warstwa edge prezentuje certyfikat domeny MF — spójne z modelem cloud WAF
7 Blok IP tranzytowy 131.125.128.0/17 — Imperva Ltd. (IL) Węzeł tranzytowy należy do spółki Impervy zarejestrowanej w Izraelu
8 Blok IP edge 45.60.0.0/16 — Incapsula Inc (USA), AS19551 Węzeł końcowy należy do spółki Impervy zarejestrowanej w USA
9 Server: Kestrel przy HEAD/OPTIONS Nagłówki przy HEAD i OPTIONS Backend MF oparty na ASP.NET Core — widoczny przez warstwę Impervy
10 POST CONTROL → 404 / Kestrel CONTROL JSON i XML Poprawne żądania docierają do backendu MF
11 POST PROBE → brak odpowiedzi PROBE SQLi, PROBE XSS Połączenie zerwane — backend MF nie był osiągany
12 POST PROBE PATH → 302 / brak Server PROBE path traversal Warstwa pośrednia odpowiada samodzielnie — backend niewidoczny
13 TRACE → Azure App Gateway Server: Microsoft-Azure-Application-Gateway/v2 + X-CDN: Imperva (powtarzalny na / i /docs/v2) Potwierdzona dodatkowa warstwa między Impervą a backendem Kestrel

10. Podsumowanie i wnioski

10.1 Odpowiedź na pytanie audytowe

Audyt wykazał, że api.ksef.mf.gov.pl, czyli produkcyjne API KSeF 2.0, jest wystawione przez chmurową warstwę Impervy. Warstwa ta nie jest biernym wpisem DNS ani ozdobnym CDN-em — aktywnie pośredniczy w ruchu HTTP do backendu KSeF i filtruje część żądań. W widocznej z zewnątrz ścieżce sieciowej pojawiają się adresy IP z bloków przypisanych w rejestrze RIPE do podmiotów Impervy zarejestrowanych w Izraelu i w USA. Powtarzalne testy metodą TRACE ujawniły ponadto dodatkową warstwę infrastruktury identyfikującą się jako Microsoft Azure Application Gateway v2, obecną między Impervą a backendem Kestrel.

10.2 Architektura edge KSeF

[Podatnik / System ERP]
        │  HTTPS
        ▼
[Play Polska → Arelion/Telia — sieć tranzytowa]
        │
        ▼
[Imperva Cloud WAF]           rejestracja: USA (Incapsula Inc) + Izrael (Imperva Ltd.)
   fingerprint: X-CDN: Imperva, visid_incap_*, incap_ses_*, X-Iinfo
   aktywna filtracja:
     SQLi / XSS     → połączenie zerwane, backend nieosiągany
     path traversal → w tym teście: 302 challenge, Server i X-CDN nieobecne w odpowiedzi
        │
        ▼  ← ujawniony przez TRACE (powtarzalny na / i /docs/v2)
[Azure Application Gateway v2]
   Server: Microsoft-Azure-Application-Gateway/v2
        │
        ▼
[Kestrel / ASP.NET Core — backend KSeF]
   widoczny przy HEAD/OPTIONS i poprawnych POST: Server: Kestrel

10.3 Granice audytu

Audyt obejmuje wyłącznie publicznie dostępną warstwę edge infrastruktury KSeF, zbadaną metodami pasywnego rekonesansu sieciowego uzupełnionymi o aktywne testy filtracji HTTP. Audyt nie weryfikuje architektury wewnętrznej backendu MF, treści umów kontraktowych, faktycznej zawartości przetwarzanych danych ani wewnętrznych polityk bezpieczeństwa MF. Wszystkie wnioski opierają się wyłącznie na dowodach zebranych z publicznie dostępnych źródeł sieciowych.

Ograniczenie metodologiczne: użyta klasa HttpWebRequest negocjuje połączenia przez HTTP/1.1. Infrastruktura Impervy obsługuje HTTP/2 i HTTP/3 (QUIC) — testy z użyciem nowoczesnego klienta (np. curl --http2) mogłyby ujawnić dodatkowe nagłówki specyficzne dla tych protokołów, stanowiąc naturalne rozszerzenie niniejszego audytu.

Wykonanie audytu: Grzegorz GPS Świderski. Sformatowanie tekstu: Sonnet 4.6 Extended.

Data:
Kategoria: Gospodarka
Tagi: #KSeF #gps65

Grzegorz Świderski

Pupilla Libertatis - https://www.mpolska24.pl/blog/gps111

Sarmatolibertarianin, bloger, żeglarz, informatyk, trajkkarz, futurysta AI. Myślę, polemizuję, argumentuję, dyskutuję, filozofuję, politykuję, uzasadniam, prowokuję.

Komentarze 0 skomentuj »
Musisz być zalogowany, aby publikować komentarze.
Dziękujemy za wizytę.

Cieszymy się, że odwiedziłeś naszą stronę. Polub nas na Facebooku lub obserwuj na Twitterze.