Przejdź do głównej zawartości

Audyt bezpieczeństwa w Cursorze: skanery, agent i bramki CI

Audyt bezpieczeństwa w Cursorze łączy deterministyczne skanery z przeglądem wykonywanym przez agenta. Skanery zależności i sekretów idą pierwsze i dają powtarzalne dowody. Potem agent Cursora przegląda uwierzytelnianie, podatności typu injection i API, a każde znalezisko musi mieć test exploita, który nie przechodzi, zanim jakakolwiek poprawka trafi do kodu. Bramki CI pilnują, żeby naprawione klasy błędów nie wróciły.

Ten przewodnik jest dla programistów i tech leadów, których zespół już pracuje w Cursorze. Do premiery zostały trzy tygodnie, produkt przechowuje dane płatnicze i osobowe za publicznym API, a osoba odpowiedzialna za compliance chce oceny bezpieczeństwa do piątku. Budżetu na pentest nie ma, a nikt w zespole nie ma czasu czytać całej bazy kodu linijka po linijce.

Audyt z agentem nie zastępuje profesjonalnego testu penetracyjnego ani modelowania zagrożeń. Wyłapuje jednak błędy o powtarzalnym wzorcu, takie jak SQL sklejany z napisów, nieescapowany HTML, brakujące sprawdzenia uprawnień czy zacommitowane klucze, i zamienia każdy z nich w test, który da się uruchomić.

  • Punkt odniesienia ze skanerów (zależności, sekrety, analiza statyczna), który każdy może uruchomić ponownie i dostać ten sam wynik.
  • Dwa prompty przeglądowe, które każą agentowi raportować znaleziska jako dowody z plikiem, linią i ścieżką ataku, a nie jako opinie.
  • Prompt naprawczy, który najpierw pisze test exploita, więc każdą poprawkę potwierdza test przechodzący z czerwonego na zielony.
  • Workflow CI i regułę projektu, które nie pozwalają tym samym błędom wrócić.
  • Tabelę odbioru, która mówi tech leadowi, co sprawdzić zamiast czytania każdego diffa.

Trzy decyzje podjęte na starcie sprawiają, że sam audyt nie staje się incydentem bezpieczeństwa.

  1. Pracuj na gałęzi. Utwórz security-audit-2026-09 i trzymaj tam wszystkie zmiany aż do odbioru opisanego w ostatniej sekcji.
  2. Nie wpuszczaj sekretów do kontekstu agenta. Wszystko, co agent przeczyta, trafia do dostawcy modelu. Uruchom skaner sekretów z redakcją (krok 2) i nie wklejaj zawartości .env do czatu. Ustawienia Privacy Mode i obsługi danych w zespole sprawdzisz w artykule prywatność i bezpieczeństwo w Cursorze.
  3. Nie wyłączaj zatwierdzania komend. W trakcie audytu agent uruchamia testy i może proponować komendy. Ustaw wykonywanie komend w Cursorze na tryb, który czeka na twoją zgodę przy wszystkim spoza listy dozwolonych komend, i nigdy nie przełączaj wykonywania komend w tryb, który uruchamia każdą komendę bez pytania. Cursor grupuje te opcje w ustawieniach pod nazwą Run modes. Treść repozytorium to niezaufane wejście: OWASP LLM Top 10 2026 (opublikowany 2026-08-04) ostrzega, że atakujący podkładają instrukcje w „a public GitHub issue, a support ticket, or a malicious npm package”.

Krok 1: Sam uruchom skanery zależności i analizy statycznej

Dział zatytułowany „Krok 1: Sam uruchom skanery zależności i analizy statycznej”

Zacznij od narzędzi o deterministycznym wyniku. Znalezisko agenta to hipoteza, znalezisko skanera to powtarzalny dowód, który nie kosztuje ani jednego tokena. Uruchom te komendy w terminalu w katalogu głównym repozytorium i zachowaj pliki JSON dla agenta.

Okno terminala
# Zależności: wybierz linie dla swoich ekosystemów
npm audit --json > audit-npm.json
pip-audit -f json -o audit-pip.json # pip install pip-audit (2.10.1 na 2026-09-26)
cargo audit --json > audit-cargo.json # cargo install cargo-audit
# Analiza statyczna: zestaw reguł OWASP Top 10
pipx run semgrep scan --config p/owasp-top-ten --json -o semgrep.json

Następnie przekaż wyniki agentowi do segregacji. Prompt prosi o plan, a nie o zmiany, bo to właśnie aktualizacje zależności najczęściej psują działający kod w trakcie audytu.

Linia „prove it exists” nie jest przypadkowa. Wpis LLM04 w OWASP 2026 opisuje slopsquatting: asystenci podsuwają wiarygodnie brzmiące nazwy pakietów, które nie istnieją, a atakujący rejestrują je zawczasu.

Krok 2: Przeskanuj historię gita pod kątem zacommitowanych sekretów

Dział zatytułowany „Krok 2: Przeskanuj historię gita pod kątem zacommitowanych sekretów”

Klucz usunięty z drzewa roboczego nadal siedzi w historii gita, więc skanuj historię, a nie tylko pliki. Robi to Gitleaks, a flaga --redact usuwa wartości sekretów z raportu. To ważne, bo ten raport za chwilę przeczyta agent.

Okno terminala
# brew install gitleaks albo obraz kontenera
gitleaks git --redact --report-path gitleaks.json
# docker run --rm -v "$PWD:/repo" ghcr.io/gitleaks/gitleaks:v8.30.1 git /repo --redact --report-path /repo/gitleaks.json

Usunięcie wyciekniętego klucza z kodu nie czyni go bezpiecznym. Najpierw zrotuj każdy klucz CRITICAL i HIGH, a historię przepisuj dopiero potem i tylko wtedy, gdy wymaga tego polityka firmy.

Krok 3: Przejrzyj z agentem uwierzytelnianie i autoryzację

Dział zatytułowany „Krok 3: Przejrzyj z agentem uwierzytelnianie i autoryzację”

Skanery słabo radzą sobie z błędami autoryzacji i tu przegląd agenta najbardziej się opłaca. Uruchom go w Plan Mode, żeby agent najpierw czytał i analizował, zanim będzie mógł cokolwiek edytować.

Tabela tras z punktu 5 to najcenniejszy produkt całego audytu. Recenzent przejrzy 60 wierszy w poszukiwaniu brakującego sprawdzenia właściciela w kilka minut, czyli znacznie szybciej, niż przeczytałby 60 handlerów.

Do obsługi danych wejściowych użyj drugiego, węższego promptu. Podział przeglądu utrzymuje każdy kontekst w skupieniu, a każdą listę znalezisk na tyle krótką, żeby dało się ją sprawdzić.

Porównanie z semgrep.json pokazuje, które znaleziska są nowe. Te, które zgłasza tylko agent, wymagają najdokładniejszej weryfikacji, bo to wśród nich kryją się fałszywe alarmy.

Krok 5: Udowodnij każde znalezisko testem, który nie przechodzi, i dopiero wtedy napraw

Dział zatytułowany „Krok 5: Udowodnij każde znalezisko testem, który nie przechodzi, i dopiero wtedy napraw”

Nie przyjmuj znaleziska ani poprawki na słowo agenta. Każde znalezisko CRITICAL i HIGH staje się testem, który przeprowadza atak na obecnym kodzie. Poprawka jest gotowa, gdy ten test przechodzi, a reszta zestawu testów nadal jest zielona.

Punkt 2 promptu to filtr fałszywych alarmów. Znalezisko, którego nie da się zamienić w nieprzechodzący test, albo nie jest podatnością, albo nie zostało jeszcze zrozumiane. W żadnym z tych przypadków nie powinno prowadzić do zmiany kodu. Szerszy wzorzec opisuje TDD w Cursorze.

Jednorazowy audyt dezaktualizuje się przy kolejnych stu commitach napisanych przez agenta. Aktualność zapewniają trzy warstwy.

Bramka CI. Dodaj workflow, który blokuje pull request, gdy wnosi on trafienie z reguł OWASP albo sekret, oraz zawsze wtedy, gdy w drzewie zależności jest podatność HIGH lub CRITICAL. Token ma tylko uprawnienia do odczytu, checkout nie zachowuje poświadczeń, a każde narzędzie ma przypiętą wersję. Przy pull_request GitHub uruchamia ten plik workflow z merge refa pull requesta, więc zmiana, która edytuje security.yml (także zmiana agenta), może osłabić albo usunąć bramkę w tym samym pull requeście. Obejmij /.github/ wpisem w CODEOWNERS z wymaganą akceptacją właściciela kodu w ochronie gałęzi albo w rulesecie i ustaw job scan jako wymagany status check.

.github/workflows/security.yml
name: security
on: [pull_request]
permissions:
contents: read
jobs:
scan:
runs-on: ubuntu-latest
steps:
# Pin actions to a full commit SHA in your own repo; a tag can be moved.
- uses: actions/checkout@v7
with:
fetch-depth: 0
persist-credentials: false
# Fails on ANY high advisory, old or new. npm audit has no baseline.
- run: npm audit --audit-level=high
# Semgrep and Gitleaks report only what this pull request adds.
- env:
BASE_REF: ${{ github.base_ref }}
run: >-
pipx run semgrep==1.178.0 scan --config p/owasp-top-ten --error
--baseline-commit "origin/$BASE_REF"
- env:
BASE_REF: ${{ github.base_ref }}
run: >-
docker run --rm -v "$PWD:/repo" ghcr.io/gitleaks/gitleaks:v8.30.1
git /repo --redact --log-opts="origin/$BASE_REF..HEAD"

Trzy skanery różnie traktują istniejące znaleziska, więc sprawdź każdy z nich względem kroków 1 i 2:

  • Semgrep porównuje wynik z gałęzią bazową dzięki --baseline-commit, więc znalezisko zamknięte w kroku 5 jako fałszywy alarm nie blokuje każdego kolejnego pull requesta. Wycisz je też w kodzie komentarzem nosemgrep w tej linii, żeby pełny skan z kroku 1 dawał ten sam wynik.
  • Gitleaks dzięki --log-opts skanuje tylko commity z pull requesta. Klucze z kroku 2 zostają w historii także po rotacji, więc skan całej historii blokowałby każdy pull request na zawsze. Jeśli wolisz skanować całą historię, zacommituj raport z kroku 2 sporządzony po rotacji i przekaż go jako --baseline-path gitleaks-baseline.json.
  • npm audit nie ma punktu odniesienia i kończy się błędem przy każdej podatności HIGH lub CRITICAL w drzewie, także tej zaakceptowanej w kroku 1. Bramka zazieleni się dopiero wtedy, gdy każda taka podatność zostanie naprawiona albo pakiet wymieniony. Zapisz każdą zaakceptowaną podatność w security-findings.md z jej identyfikatorem, właścicielem i datą przeglądu, żeby czerwony krok był znaną decyzją z datą, a nie powodem do wyłączenia bramki.

Dodaj też hook pre-commit z Gitleaks, żeby commit z kluczem został zablokowany już na laptopie, zanim dotrze do CI. Konfigurację znajdziesz w README Gitleaks. TruffleHog, Snyka i wtyczkę Semgrep Guardian opisuje artykuł bramki bezpieczeństwa dla kodu pisanego przez agentów.

Reguła projektu. Poproś agenta o regułę bezpieczeństwa opartą na audycie, żeby nowy kod trzymał się wprowadzonych poprawek. Reguły Cursora opisuje artykuł o regułach projektu.

Przegląd pull requestów. Bugbot w Cursorze „reviews pull requests and identifies bugs, security issues, and code quality problems”, a Security Agents „scan your code for security bugs, risky patterns, and vulnerabilities” (dokumentacja Cursora, sprawdzone 2026-08-28). Traktuj każde z nich jako dodatkowego recenzenta, a nie bramkę: recenzent oparty na LLM może przeoczyć to, co wyłapie deterministyczny skaner. Konfigurację i kompromisy opisują artykuły code review w Cursorze oraz porównanie botów do AI code review.

Jeśli chcesz dostawać znaleziska już w trakcie pisania kodu przez agenta, a nie dopiero przy pull requeście, serwer MCP Semgrepa jest wbudowany w binarkę semgrep. Najpierw zainstaluj ją poleceniem pipx install semgrep (albo brew install semgrep), żeby semgrep był w PATH; pipx run z kroku 1 go tam nie umieszcza. Potem dodaj serwer do .cursor/mcp.json:

{
"mcpServers": {
"semgrep": { "command": "semgrep", "args": ["mcp"] }
}
}

Jak odebrać audyt bezpieczeństwa w Cursorze bez czytania każdej linii?

Dział zatytułowany „Jak odebrać audyt bezpieczeństwa w Cursorze bez czytania każdej linii?”

Tech lead zatwierdza audyt na podstawie dowodów, a nie diffa. Każdy wiersz ma artefakt, który może sprawdzić ktoś inny niż agent.

TwierdzenieDowód do sprawdzeniaKto sprawdza
Brak znanych podatnych zależnościnpm audit --audit-level=high (i pip-audit) kończą się kodem 0 w CI albo każda pozostała podatność jest zaakceptowanym ryzykiem z właścicielem i datąCI oraz tech lead dla zaakceptowanych ryzyk
Brak sekretów w kodzie i historiiGitleaks kończy się kodem 0 na commitach każdego pull requesta (albo względem zacommitowanego punktu odniesienia); każde znalezisko z raportu z kroku 2 zrotowane, a rotacja potwierdzonaWłaściciel każdego konta u dostawcy
Każda trasa sprawdza właścicielaTabela tras z kroku 3, przejrzana wiersz po wierszuTech lead
Każda poprawka zamyka znaleziskoTest exploita nie przechodził przed zmianą i przechodzi po niej; cały zestaw zielonyCI oraz recenzent, który wyrywkowo sprawdza dwa testy
Nic nowego się nie prześlizgujeWorkflow bezpieczeństwa wymagany na gałęzi domyślnej; reguła zacommitowanaTech lead

Wszystko oznaczone w security-findings.md jako „needs human check” pozostaje otwarte, dopóki nie zamknie tego człowiek. Zachowaj ten plik razem z informacjami o wydaniu: to jest ocena, o którą prosiła osoba od compliance.

Agent raportuje czysty wynik. „No vulnerabilities found” oznacza tylko, że nie pasował żaden znany wzorzec. Błędy logiki biznesowej, na przykład cena ustawiana przez klienta albo klucze API, które przeżywają usunięcie konta, wymagają modelowania zagrożeń. Co zrobić: zapytaj w Plan Mode: „You are an attacker who wants free orders from this checkout. List five attempts, and the file and line each one targets.” Każdą wiarygodną próbę zamień potem w test.

Mnożą się fałszywe alarmy. Wywołanie ORM potrafi wyglądać jak SQL sklejany z napisów. Co zrobić: zasada nieprzechodzącego testu z kroku 5. Jeśli test exploita przechodzi na niezmienionym kodzie, zamknij znalezisko jako fałszywy alarm z testem jako dowodem i nie zmieniaj kodu.

Poprawka psuje prawdziwą funkcję. Tokeny CSRF psują klientów API, którzy nigdy ich nie wysyłali, a ścisła lista CORS blokuje frontend na stagingu. Co zrobić: po każdej poprawce uruchamia się cały zestaw testów, a każda poprawka jest osobną zmianą, więc możesz wycofać jedną bez utraty pozostałych. Zanim spróbujesz ponownie, dodaj zepsutego klienta do testów.

Aktualizacja zależności psuje build. Podbicie wersji głównej zmienia API. Co zrobić: aktualizacje z grupy (a) z kroku 1 wprowadź razem, a każde podbicie wersji głównej osobno, z pełnym zestawem testów. Jeśli podbicie jest zablokowane, zapisz mitygację i analizę osiągalności z kroku 1 jako zaakceptowane ryzyko z właścicielem i datą.

Agent dodaje pakiet, który nie istnieje albo nie jest tym, o który chodziło. Nazwa różniąca się o literę może należeć do pakietu ze slopsquattingu. Co zrobić: odrzucaj każdą nową zależność, której agent nie zweryfikował w rejestrze, samodzielnie sprawdź wydawcę i historię pobrań, a npm audit i diff lockfile’a trzymaj w przeglądzie.

Tekst w repozytorium steruje agentem. Komentarz, fixture albo README z „ignore previous instructions” celuje w audytora. Co zrobić: nie wyłączaj zatwierdzania komend, przerwij sesję, gdy agent proponuje działanie, o które prompt nie prosił, i zgłoś ten plik jako osobne znalezisko.

Wróć do przeglądu sekcji Eksploatacja w Cursorze.