Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
laravel-threat-detection — SQL 인젝션, XSS, RCE, 봇 스캐너 및 175개 이상의 공격 패턴을 탐지하고 기록하는 패시브 Laravel 미들웨어입니다. 내장 대시보드, Slack 알림, REST API 및 지리 정보 보강 기능을 갖추고 있습니다. WAF가 아닌 IDS입니다. | Kitploit
도구/GitHubGitHub/jay123anta/laravel-threat-detection
Defensive ToolsVulnerability ScannersWeb SecurityThreat IntelligenceIntrusion DetectionIncident ResponseAPI SecurityAnti-BotLog Analysis

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
GitHubjay123anta/laravel-threat-detection

laravel-threat-detection

SQL 인젝션, XSS, RCE, 봇 스캐너 및 175개 이상의 공격 패턴을 탐지하고 기록하는 패시브 Laravel 미들웨어입니다. 내장 대시보드, Slack 알림, REST API 및 지리 정보 보강 기능을 갖추고 있습니다. WAF가 아닌 IDS입니다.

저장소 보기웹사이트
3125620일 전Kitploit 검토 완료
<p align="center">
  <a href="https://packagist.org/packages/jayanta/laravel-threat-detection"><img src="https://img.shields.io/packagist/v/jayanta/laravel-threat-detection.svg?style=flat-square" alt="Latest Version"></a>
  <a href="https://github.com/jay123anta/laravel-threat-detection/actions/workflows/tests.yml"><img src="https://img.shields.io/github/actions/workflow/status/jay123anta/laravel-threat-detection/tests.yml?branch=main&amp;style=flat-square&amp;label=tests" alt="Tests"></a>
  <a href="https://github.com/jay123anta/laravel-threat-detection/actions/workflows/tests.yml"><img src="https://img.shields.io/badge/PHPStan-level%205-brightgreen?style=flat-square" alt="PHPStan Level 5"></a>
  <a href="https://github.com/jay123anta/laravel-threat-detection/actions/workflows/tests.yml"><img src="https://img.shields.io/badge/code%20style-Pint-orange?style=flat-square" alt="Code Style Pint"></a>
  <a href="https://packagist.org/packages/jayanta/laravel-threat-detection"><img src="https://img.shields.io/packagist/dt/jayanta/laravel-threat-detection.svg?style=flat-square" alt="Total Downloads"></a>
  <a href="https://packagist.org/packages/jayanta/laravel-threat-detection"><img src="https://img.shields.io/packagist/php-v/jayanta/laravel-threat-detection?style=flat-square" alt="PHP Version"></a>
  <a href="https://github.com/jay123anta/laravel-threat-detection/blob/main/LICENSE"><img src="https://img.shields.io/packagist/l/jayanta/laravel-threat-detection.svg?style=flat-square" alt="License"></a>
</p>

# Laravel Threat Detection

**Laravel를 위한 보안 모니터링 및 공격 로깅. SQL 인젝션,
XSS, RCE, 디렉터리 트래버설, 봇 스캐너 및 `/wp-admin` 스타일의 정찰 프로브를 탐지하고 기록합니다 —
모든 악의적인 요청이 전체 애플리케이션 컨텍스트와 함께 데이터베이스에 기록됩니다.
이것은 IDS이며 WAF가 아닙니다: 요청을 차단, 필터링 또는 수정하지 않습니다.**

<p align="center">
  <img src="https://raw.githubusercontent.com/jay123anta/laravel-threat-detection/main/art/demo.gif" alt="패키지를 설치하고 세 가지 공격 — SQL 인젝션, 디렉터리 트래버설, XSS — 을 전송합니다. 아무것도 차단되지 않기 때문에 모두 HTTP 200을 반환하며, 세 가지 모두 이미 threat-detection:stats에 집계되어 있습니다" width="100%">
</p>

### 다음과 같은 것을 보고 여기에 오셨나요?

```
GET /wp-admin/setup-config.php          404   — on a site that isn't WordPress
GET /.env                               404   — someone wants your database password
GET /?id=1' UNION SELECT password FROM  200   — SQL injection against a real route
GET /phpmyadmin/index.php               404   — scanning for an admin panel
```

이러한 요청들은 이미 Laravel 앱에 도달하고 있습니다. 액세스 로그에는 URL과 상태 코드만 표시될 뿐, 디코딩된 페이로드도, 어떤 라우트가 공격 대상이었는지도, 동일한 IP가 이번 시간에 다른 40가지 시도를 했는지도 알 수 없습니다.

이 패키지가 그 질문들에 답합니다. Laravel 10–13 앱 어디에든 설치하면 모든 HTTP 요청을 150개 이상의 공격 패턴과 대조해 스캔하기 시작하고, 각 일치 항목을 신뢰도에 따라 점수화하여 데이터베이스에 기록합니다 — 내장 대시보드, Slack 알림, 지리 정보 보강, fail2ban/차단 목록 내보내기 기능까지 갖추고 있습니다. 어떤 요청도 차단되지 않습니다. 자물쇠가 아니라 보안 카메라라고 생각하세요: 누가, 얼마나 자주, 어떤 기법으로 라우트를 탐색하는지 정확히 보여줍니다.

> 프로덕션 앱에서 추출되어 실제 트래픽에서 검증되었습니다. 2,400개 이상의 테스트, Laravel 자체 외 런타임 의존성 없음, 탐지에 인터넷 연결이 필요하지 않습니다.
>
> 업그레이드하시나요? [UPGRADING.md](https://github.com/jay123anta/laravel-threat-detection/blob/main/UPGRADING.md)를 참조하세요. 기여하시나요? [CONTRIBUTING.md](https://github.com/jay123anta/laravel-threat-detection/blob/main/CONTRIBUTING.md)를 참조하세요.

## 1분 이내에 시작하기

```bash
composer require jayanta/laravel-threat-detection
php artisan vendor:publish --tag=threat-detection-migrations
php artisan migrate
```

그런 다음 미들웨어를 `web` 그룹에 추가하세요 (Laravel 11+에서는 `bootstrap/app.php`에 한 줄, Laravel 10에서는 `app/Http/Kernel.php`에 한 줄) — 전체 스니펫은 아래 [Quick Start](#quick-start)에 있습니다.
이게 전부입니다. 탐지가 활성화됩니다.

```bash
php artisan threat-detection:doctor   # confirms it is actually recording
```

---

## 어디에 적합한가: IDS vs WAF vs 엣지

이 패키지는 **수동적, 애플리케이션 수준 IDS**입니다 — 감시하고 기록할 뿐,
차단하지 않습니다. WAF나 엣지 서비스를 *대체*하는 것이 아니라 *함께* 위치하도록
설계되었습니다. 각 계층은 다른 계층이 볼 수 없는 것을 봅니다:

| | **이 패키지** (앱 IDS) | **WAF** (ModSecurity + OWASP CRS, Cloudflare WAF) | **엣지 / CDN** (Cloudflare) |
|---|:---:|:---:|:---:|
| 악성 요청 차단 | ❌ 로그만 기록 | ✅ | ✅ |
| 전체 앱 컨텍스트 (정확한 URL, 디코딩된 페이로드, 인증된 사용자) | ✅ | ⚠️ 부분적 | ❌ |
| 내장 대시보드 + DB 내 위협 로그 | ✅ | ⚠️ 경우에 따라 다름 | ⚠️ 엣지만 |
| 앱 특화 탐지 (예: Aadhaar / PAN / IFSC PII) | ✅ 내장 + 사용자 정의 | ⚠️ 직접 규칙 작성 | ⚠️ 사용자 정의 규칙, 플랜 의존 |
| 오프라인 / 외부 서비스 불필요 | ✅ | ⚠️ 의존 | ❌ |
| 트래픽이 서버에 도달하기 전 차단 | ❌ | ⚠️ 클라우드 WAF만 | ✅ |
| 설정 | `composer require`, 마이그레이션, 미들웨어 한 줄 | 중간–높음 | 낮음–중간 |
| 비용 | 무료, MIT | 경우에 따라 다름 | 무료 티어 + 유료 |

**요약하자면:** 엣지/WAF는 문에 달린 자물쇠이고, 이것은 *내부*의 보안 카메라로,
어떤 라우트에 누가 얼마나 자주 무엇을 시도하는지 정확히 알려줄 앱 컨텍스트를
갖추고 있습니다. 엣지 계층이 결코 볼 수 없는 데이터로 실제 결정 — fail2ban 차단,
속도 제한, 지역 차단 — 을 내리는 데 활용하세요.

### 의도적으로 아닌 것

- **WAF가 아닙니다.** 요청을 차단, 필터링, 수정하지 않습니다. 강제 적용에는
  Cloudflare, mod_security 또는 실제 WAF를 사용하세요. (넘겨줄 엣지 계층이
  없나요? [운영자 측 헬퍼](#acting-on-the-data-operator-side-blocking)가
  패키지의 결정을 노출하므로 직접 다섯 줄짜리 차단 미들웨어를 작성할 수
  있습니다 — 강제 적용 코드는 패키지가 아닌 여러분의 것입니다.)
- **안전한 코딩을 대체하지 않습니다.** 매개변수화된 쿼리, 입력 검증, 출력
  이스케이프가 실제 방어입니다. 이 패키지는 여러분의 코드가 이미 안전하다고
  가정하고 *가시성*을 제공할 뿐, 보호를 제공하지 않습니다.
- **엣지 서비스가 아닙니다.** Cloudflare를 앞에 둘 수 있다면 두고, 그런 다음
  엣지 서비스가 볼 수 없는 애플리케이션 수준 세부 정보를 위해 이것을
  추가하세요.
- **완전한 탐지기가 아니며, 그럴 수도 없습니다.** 패턴 매칭은 *알려진 공격처럼
  보이는* 공격을 잡습니다. 새로운 기법이나 충분히 재작성된 익숙한 기법은
  기록되지 않고 통과할 것이며, 통과했다는 사실조차 알려지지 않습니다. 여기서의
  침묵은 "아무것도 일치하지 않았다"는 뜻이지 "아무 일도 일어나지 않았다"는
  뜻이 아닙니다. 이 패키지가 가치를 발휘하는 곳은 공개 Laravel 앱에 실제로
  도달하는 트래픽의 대부분을 차지하는 대량·저노력 트래픽입니다: 스캐너, 정찰
  프로브, 기성 주입 문자열, 자격 증명 스프레이. 조용한 로그를 증거의 부재로
  취급하지 말고, 부재의 증거로 취급하세요.

### 첫날부터 여러분의 자체 콘텐츠를 탐지할 것으로 예상하세요

튜닝되지 않은 설치 환경은 정상적인 콘텐츠에도 반응하며, 설치 후가 아니라 설치
전에 이를 알아야 합니다. 이는 가정이 아니라 측정된 결과입니다. 아래 행은
[`LegitimateTrafficCorpusTest`](https://github.com/jay123anta/laravel-threat-detection/blob/main/tests/Feature/LegitimateTrafficCorpusTest.php)가
고정한 하한선의 일부이며, 각 행은 해당 요청이 기록하는 *모든 것*을 나열하고,
[`ReadmeNoiseFloorTest`](https://github.com/jay123anta/laravel-threat-detection/blob/main/tests/Feature/ReadmeNoiseFloorTest.php)는
어떤 행이든 해당 스위트가 측정하는 것과 일치하지 않게 되면 빌드를
실패시킵니다.

<!-- noise-floor:start -->
| 완벽하게 정상적인 요청 | 튜닝되지 않은 설치가 기록하는 것 |
|---|---|
| 검색창에 입력한 `how to write a UNION SELECT in postgres` <!-- case: sql tutorial in a search box --> | `SQL Injection UNION` / high |
| `<script>window.dataLayer=[];</script>`를 포함한 블로그 게시물 <!-- case: javascript snippet in a blog post --> | `XSS Script Tag` / high · `Command Chain Injection` / medium |
| `SELECT * FROM users WHERE id = 1` 오류를 붙여넣은 지원 티켓 <!-- case: a pasted sql error in a support ticket --> | `SQLi Variant` / high · `SQL SELECT Query` / low |
| `../../etc/passwd`가 고전적인 트래버설 페이로드라고 설명하는 문서 <!-- case: a traversal explainer in documentation --> | `Directory Traversal` / medium · `Sensitive File Access` / medium |
| 실제 인도 휴대폰 번호와 PAN을 수집하는 프로필 양식 <!-- case: a profile form collecting genuine indian pii --> | `PAN Number Detected` / high · `Bank Account Number Detected` / high · `Mobile Number Detected` / low |
<!-- noise-floor:end -->

**이 중 어느 것도 버그가 아닙니다.** `<script>`를 포함한 블로그 게시물은 바이트
단위로 저장형 XSS 페이로드이고, `UNION SELECT` 검색은 그 시도와 구별할 수
없으며, 열 자리 휴대폰 번호는 그럴듯한 은행 계좌 번호이기도 합니다. 애플리케이션
컨텍스트 외에는 이들을 구분하는 것이 없으며, 어떤 패턴 엔진도 여러분을 위해 그
컨텍스트를 제공할 수 없습니다.

컨텍스트를 제공하는 것은 한 줄짜리 설정 변경입니다: 그러한 콘텐츠를 정당하게
담는 필드를 `safe_fields`에 (또는 중첩 JSON 내부의 한 경로에 대해서는
`safe_paths`에) 지정하면 더 이상 스캔되지 않습니다. 이것이 위의 행들을 조용하게
만드는 스위치이며 — 그리고 그것은 실제 트레이드오프입니다. 왜냐하면 그 필드를
통해 전달되는 공격도 보이지 않게 되기 때문입니다.

`content_paths`와 `relaxed` 모드는 다른 도구입니다. 이들은 낮음 및 중간 심각도
노이즈를 제거하고 **의도적으로 높은 심각도 일치를 계속 기록합니다** — 따라서
설계상 이 표의 높은 심각도 행들을 조용하게 만들지 않습니다. 언제 무엇을
사용해야 하는지는 [오탐 줄이기](#reducing-false-positives)를 참조하세요.

**여러분의 앱이 리치 텍스트, 코드 샘플 또는 검색 쿼리를 받아들인다면, 출력을
판단하기 전에 그렇게 하세요.** 기본값은 조용하고 불완전하기보다 의도적으로
시끄럽지만 정직합니다: 알려진 일치를 조용하게 만드는 것이 결코 발생하지 않은
일치를 발견하는 것보다 쉽습니다.

### 그래서 실제로 무엇을 하는가?

결코 차단하지 않는 탐지기에 대해 가장 흔한 질문입니다. 노력이 증가하는 순서로
네 가지 답이 있습니다:

| 원하는 것 | 사용 | 노력 |
|---|---|---|
| 무엇이 나를 공격하는지 보기 | [대시보드](#dashboard) 또는 `threat-detection:stats` | 없음, 이미 실행 중 |
| 방화벽에서 반복 위반자 차단 | [`threat-detection:export-fail2ban`](#artisan-commands) — cron으로 파이프 | 한 줄 |
| 웹 서버에서 거부 | [`threat-detection:export-blocklist`](#artisan-commands) → nginx/apache 지시문 | 한 줄 |
| 앱 내에서 요청 거부 | [운영자 측 헬퍼](#acting-on-the-data-operator-side-blocking) — `isBlocklisted()`, `isDdosThresholdExceeded()` | 직접 작성한 미들웨어 약 10줄 |
| 실시간 대응 | [`ThreatDetected` 이벤트](#threatdetected-event) — Telegram, SIEM, PagerDuty | 리스너 |

패키지는 인텔리전스를 제공하고, 여러분은 거부를 제공합니다. 이 분리는
의도적입니다 — 여러분의 앱에 있는 강제 적용 코드는 읽고, 테스트하고, 끌 수 있는
코드이며, 탐지 버그가 여러분의 사이트를 다운시킬 수 없다는 것을 의미합니다.


### 다른 Laravel 보안 패키지와의 비교

이들은 서로 다른 문제를 해결하며 잘 조합됩니다 — 이 표는 승자를 가리는 것이
아니라 올바른 도구를 고르는 것에 관한 것입니다.

| 패키지 | 하는 일 | 차단? | 사용 시기 |
|---|---|:---:|---|
| **이 패키지** | 모든 요청을 150개 이상의 패턴과 대조하여 스캔하고 전체 앱 컨텍스트와 함께 기록 | ❌ | 여러분의 앱에 무엇이 시도되는지 *보고* 싶을 때 |
| `spatie/laravel-honeypot` | 스팸 봇을 잡는 숨겨진 폼 필드 | ✅ 폼만 | 스팸이 들어오는 공개 폼이 있을 때 |
| `graham-campbell/security` | 입력에서 XSS 유사 마크업 제거 | ✅ 변경 | 순진한 입력 정화를 원할 때 |
| `spatie/laravel-csp` | Content-Security-Policy 헤더 전송 | ✅ 브라우저 | 브라우저가 로드하는 것을 제한하고 싶을 때 |
| `laravel/fortify` + 속도 제한 | 인증 스로틀링 및 잠금 | ✅ | 로그인에 무차별 대입 보호가 필요할 때 |
| Cloudflare / mod_security | 엣지 WAF, 앱 도달 전 차단 | ✅ | 트래픽이 도달하기 전에 중단되길 원할 때 |

정직한 요약: 허니팟은 폼 스팸을 잡고, WAF는 알려진 악성 트래픽을 엣지에서
차단하며, CSP는 브라우저를 제한합니다. **어느 것도 공격자가 여러분의 특정
라우트에 대해 무엇을 시도했는지, 페이로드가 디코딩되고 인증된 사용자가 첨부된
상태로 알려주지 않습니다.** 이 패키지가 채우는 것이 바로 그 간극이며 — 이것이
패키지가 의도적으로 차단하지 않는 이유입니다: 위의 모든 것과 함께 실행해도
서로 충돌하지 않습니다.

---

## 요구 사항

- PHP 8.2+ (Laravel 13은 PHP 8.3+ 필요)
- Laravel 10.x, 11.x, 12.x 또는 13.x
- Laravel이 지원하는 모든 데이터베이스 (MySQL, PostgreSQL, SQLite, SQL Server)
- 모든 캐시 드라이버 - **Redis나 큐 워커가 필요하지 않습니다**. Redis/Memcached는
  선택적 DDoS 검사(비원자적 드라이버에서는 자동 비활성화됨)를 활성화하기 위해
  *권장*될 뿐입니다. 큐 기반 쓰기는 선택 사항이며 기본적으로 꺼져 있습니다.

---

## 작동 방식

1. 미들웨어가 모든 수신 HTTP 요청을 스캔합니다
2. 요청은 SQL 인젝션, XSS, RCE, 파일 트래버설, SSRF, LDAP, XPath, SSTI 등을 포함하는 158개의 정규식 패턴과 대조됩니다
3. 위협 패턴이 일치하면 IP, URL, 위협 유형, 심각도 수준, 신뢰도 점수와 함께 `threat_logs` 데이터베이스 테이블에 레코드가 기록됩니다
4. 선택적으로 높은 심각도 위협에 대해 Slack 알림이 전송됩니다
5. 요청은 정상적으로 진행됩니다 - **아무것도 차단되지 않습니다**

탐지에는 인터넷 연결이 필요하지 않습니다.

---

## 빠른 시작

### 1. 패키지 설치

```bash
composer require jayanta/laravel-threat-detection
```

### 2. 마이그레이션을 게시하고 실행하기

> **이 단계는 필수입니다.** 이 단계를 수행하지 않으면 패키지가 위협을 탐지하더라도 데이터베이스에 저장할 수 없습니다. 이 단계를 건너뛰면 `threat_logs` 테이블이 존재하지 않게 되어 모든 탐지 결과가 조용히 유실됩니다(`storage/logs/laravel.log`에서만 오류를 확인할 수 있습니다).

```bash
php artisan vendor:publish --tag=threat-detection-migrations
php artisan migrate
```

이렇게 하면 두 개의 테이블이 생성됩니다: `threat_logs`(탐지된 위협을 저장)와 `threat_exclusion_rules`(오탐 규칙을 저장).

**테이블이 생성되었는지 확인:**
```bash
php artisan migrate:status
```
`create_threat_logs_table`, `add_confidence_to_threat_logs_table`, `create_threat_exclusion_rules_table`를 찾으세요 - 모두 `Ran`으로 표시되어야 합니다.

### 3. 미들웨어 등록

미들웨어는 요청을 스캔하는 역할을 합니다. 이를 `web` 미들웨어 그룹에 추가해야 합니다.

**Laravel 11 또는 12를 사용하는 경우** - `bootstrap/app.php`를 여세요:

```php
->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        \JayAnta\ThreatDetection\Http\Middleware\ThreatDetectionMiddleware::class,
    ]);
})
```

> **Laravel 버전 확인 방법:** 터미널에서 `php artisan --version`을 실행하세요.

**Laravel 10을 사용하는 경우** - `app/Http/Kernel.php`를 여세요:

```php
protected $middlewareGroups = [
    'web' => [
        // ... existing middleware
        \JayAnta\ThreatDetection\Http\Middleware\ThreatDetectionMiddleware::class,
    ],
];
```

### 4. (선택 사항) 구성 파일 게시

```bash
php artisan vendor:publish --tag=threat-detection-config
```

패키지는 합리적인 기본값으로 작동합니다. 설정을 게시하면 탐지 패턴, 민감도 모드, Slack 알림 등을 사용자 정의할 수 있습니다. 이 단계를 건너뛰어도 모든 것이 여전히 작동합니다.

**이게 전부입니다.** 이제 앱이 위협을 탐지하고 있습니다.

---

## 작동하는지 확인하기

설치 후 테스트 위협을 트리거하고 기록되었는지 확인하세요.

### 1단계: 앱 시작하기

```bash
php artisan serve
```

### 2단계: 브라우저에서 테스트 URL 열기

앱의 **기존 라우트**(홈페이지, 제품 페이지 등)에 악성 쿼리 파라미터를 추가하세요. 예를 들어:

**SQL 인젝션:**
```
http://localhost:8000/?q=' UNION SELECT * FROM users--
```

**XSS (크로스 사이트 스크립팅):**
```
http://localhost:8000/?q=<script>alert(1)</script>
```

**디렉터리 순회:**
```
http://localhost:8000/?file=../../etc/passwd
```

**RCE (원격 코드 실행):**
```
http://localhost:8000/?cmd=system('ls -la')
```

**Shellshock (CVE-2014-6271):**
```
http://localhost:8000/?cmd=() { :;}; /bin/bash
```

**Windows 명령어 인젝션:**
```
http://localhost:8000/?cmd=powershell -c whoami
```

**DROP TABLE (SQL DDL):**
```
http://localhost:8000/?q=DROP TABLE users
```

> 앱에 실제로 존재하는 경로(예: `/`)를 사용하세요. URL이 404를 반환하면 미들웨어가 실행되지 않았을 수 있습니다.

### 3단계: 위협이 기록되었는지 확인

**옵션 A - Artisan 명령(가장 빠름):**
```bash
php artisan threat-detection:stats
```
`Recorded Detections`, 심각도 카운트, 상위 IP가 포함된 테이블이 표시되어야 합니다. 이 숫자는 *행*을 세는 것이지 시도 횟수를 세는 것이 아닙니다. 탐지는 IP당, 위협 유형당, 5분당 한 번 기록되며, 해당 윈도우 내에서 반복되는 항목은 다시 카운트되지 않고 중복 제거됩니다.

**옵션 B - Tinker:**
```bash
php artisan tinker
```
```php
DB::table('threat_logs')->latest()->take(5)->get(['ip_address', 'type', 'threat_level', 'confidence_score']);
```

**옵션 C - Laravel 로그 파일:**
탐지된 각 위협은 `storage/logs/laravel.log`에 경고로 기록됩니다:
```
[high] Threat Detected: [middleware] SQL Injection UNION from 127.0.0.1 (http://localhost:8000/?q=...) [confidence: 50%]
```

### 테스트 시 알아야 할 사항

| 동작 | 설명 |
|----------|-------------|
| 동일한 위협은 5분에 한 번만 로그됨 | 중복 제거: 동일한 IP + 동일한 위협 유형은 5분 동안 캐시됩니다. 각 테스트마다 **다른 공격 유형**을 사용하거나 테스트 사이에 대기하세요. |
| `curl` 요청은 추가 탐지를 유발함 | `curl`을 사용하면 "cURL Command" 사용자 에이전트 탐지(낮은 심각도)도 로그됩니다. 이는 예상된 동작입니다 - 패키지가 자동화 도구를 탐지합니다. |
| 패키지는 요청을 차단하지 않음 | 앱은 정상적으로 계속 작동합니다. 탐지는 수동적입니다. |
| Slack 설정이 필요 없음 | 알림은 기본적으로 꺼져 있습니다. |
| 인터넷 연결이 필요 없음 | 핵심 탐지는 100% 로컬입니다. 선택적 `threat-detection:enrich` 명령만 지리 데이터를 위해 외부 API를 호출합니다. |

### 문제 해결

**여기서 시작하세요 — 하나의 명령으로 대부분의 문제가 해결됩니다:**

```bash
php artisan threat-detection:doctor
```

대시보드가 비어 있는 상태로 남아 "공격 없음"과 구별되지 않는, 즉 *조용히* 탐지를 실패하게 만드는 요소들을 점검하고 각각에 대한 정확한 해결책을 출력합니다. 실제 실패 시 0이 아닌 코드로 종료하므로 CI나 배포 단계에서 실행해도 안전합니다.

```
  Threat Detection — health check

  PASS  Detection is enabled for this environment
  FAIL  'threat_logs' is missing confidence_label — EVERY threat is being discarded
        Run: php artisan vendor:publish --tag=threat-detection-migrations && php artisan migrate
  WARN  1 custom pattern(s) shadow a built-in: Localhost SSRF
        Your copy runs instead of the maintained one, so later fixes to it never reach you.
```

다루는 내용: 이 환경에서 탐지가 활성화되어 있는지, 작성자에게 필요한 모든 컬럼(하나라도 누락되면 **모든** 위협이 버려짐), 대시보드/API 컬럼, 제외 규칙 테이블, 미들웨어가 실제로 라우트나 그룹에 연결되어 있는지, 이 버전보다 오래된 게시된 설정, 내장 패턴을 가리는 사용자 정의 패턴, DDoS 카운팅을 할 수 없는 캐시 드라이버, 그리고 인증 없이 열려 있는 대시보드나 API.

**"테스트했는데 `threat-detection:stats`에 위협이 0으로 표시됨" / "위협이 데이터베이스에 저장되지 않음"**

doctor가 통과했다면 설치는 정상이며 문제는 테스트 요청 자체에 있습니다. doctor가 확인할 수 없는 세 가지가 있습니다:

| 확인 사항 | 검증 방법 |
|-------|---------------|
| IP가 화이트리스트에 없음 | `.env`에 `THREAT_DETECTION_WHITELISTED_IPS`를 추가했다면 테스트 중에는 제거하세요 |
| 기존 라우트를 사용했는지 | 테스트 URL은 실제 라우트(예: `/`)와 일치해야 합니다. 404는 미들웨어가 실행되지 않았다는 의미입니다 |
| 중복 제거 캐시 | 동일 IP + 동일 공격 유형은 5분 동안 캐시됩니다 - 다른 공격 유형을 시도해 보세요 |

> `php artisan migrate`만 실행하는 것으로는 절대 충분하지 않습니다: 마이그레이션 파일은
> 패키지 안에 있으며 먼저 앱의 `database/migrations/`에 게시해야 합니다.
> 이것이 문제일 때 doctor가 정확한 명령을 출력합니다.

**"API가 401 Unauthorized를 반환함"**

아래 [API 인증](#api-authentication)을 참조하세요.

**"대시보드가 404를 표시함"**

대시보드는 기본적으로 비활성화되어 있습니다. `.env`에 `THREAT_DETECTION_DASHBOARD=true`를 추가하고 라우트 캐시를 지우세요:
```bash
php artisan route:clear
```

---

## 기능

- **150개 이상의 탐지 패턴** - SQL 인젝션(UNION, DDL, DML, 파일 작업), XSS(script, SVG, CSS expression), RCE, 디렉터리 트래버설, SSRF, XXE, Log4Shell, NoSQL 인젝션, 명령 인젝션(Linux + Windows), LDAP 인젝션, XPath 인젝션, SSTI, CRLF 인젝션, Java 역직렬화 등
- **83개의 봇/스캐너 시그니처** - SQLMap, Nikto, Nmap, Burp Suite, FeroxBuster, FFUF, XSStrike, Dalfox, Netsparker 및 70개 이상의 기타 스캐너 및 봇 시그니처
- **AI 스크래퍼 탐지** - GPTBot, ClaudeBot, ByteSpider, Common Crawl 및 기타 AI 학습 봇
- **헤드리스 브라우저 탐지** - HeadlessChrome, PhantomJS, Selenium, Puppeteer, Playwright
- **404 프로브 추적** - 알려진 취약 경로(`/wp-admin`, `/.env`, `/phpmyadmin`, `/actuator` 등)를 타격하는 정찰 프로브를 탐지하며, 50개 이상의 기본 프로브 경로와 노출된 LLM 게이트웨이를 위한 옵트인 [AI 인프라 팩](#ai-infrastructure-probes-opt-in)을 제공합니다
- **DDoS 모니터링** - 구성 가능한 윈도우를 사용한 속도 기반 임계값 탐지
- **신뢰도 점수** - 각 위협은 패턴 수, 컨텍스트, 신호를 기반으로 0-100 신뢰도 점수를 받습니다
- **회피 저항** - 정규화 파이프라인이 패턴 매칭 전에 SQL 주석 삽입, 이중 URL 인코딩, HTML 엔티티 인코딩, 유니코드 이스케이프, 16진수 이스케이프, IIS `%uXXXX` 인코딩을 무력화합니다 — 페이로드가 더 이상 변하지 않을 때까지 반복되므로 두 가지 기법을 중첩해도 통과하지 못합니다
- **CVE 탐지** - Shellshock(CVE-2014-6271), Spring4Shell(CVE-2022-22965), PHPUnit RCE(CVE-2017-9841), Drupalgeddon, Log4Shell
- **컨텍스트 인식 탐지** - 쿼리 문자열에서 발견된 패턴은 요청 본문에서 발견된 것보다 높은 점수를 받습니다
- **요청 본문 스캔** - 폼 인코딩 및 JSON(`application/json`) 요청 본문 모두 검사됩니다
- **안전 필드** - 특정 폼 필드를 스캔에서 제외합니다(CMS 편집기, 코드 입력, 검색 필드용)
- **오탐 신고** - 대시보드에서 위협을 오탐으로 표시하면 제외 규칙이 자동 생성됩니다
- **세 가지 탐지 모드** - `strict`, `balanced`(기본값), `relaxed` - 조정 가능한 민감도
- **콘텐츠 경로 억제** - CMS/블로그 경로를 화이트리스트에 추가하여 리치 콘텐츠로 인한 낮음/중간 경고를 억제합니다
- **PII 탐지** - 민감 데이터 노출 패턴(지역별 구성 가능)
- **지리 정보 보강** - 무료 API를 통한 국가, 도시, ISP, 클라우드 제공자 식별
- **Slack 알림** - 높은 심각도 위협에 대한 실시간 알림(Laravel 10 및 11+에서 작동)
- **내장 대시보드** - 다크 모드 Blade 대시보드(Alpine.js 및 Tailwind, 스타일 사전 컴파일, 빌드 단계 없음)
- **대시보드 인증 가드** - 대시보드 및 API에 대한 구성 가능한 인증(none, auth, role 또는 IP 기반)
- **15개의 API 엔드포인트** - 사용자 정의 Vue/React/모바일 대시보드 구축을 위한 완전한 REST API
- **Fail2ban 내보내기** - 탐지된 IP를 fail2ban 호환 형식 또는 일반 차단 목록으로 내보내기
- **차단 목록 내보내기** - IP를 nginx deny, Apache deny, CSV 또는 일반 형식으로 내보내기
- **CSV 내보내기** - 원클릭 위협 로그 내보내기(최대 10,000행)
- **상관관계 분석** - IP 전반에 걸친 조정된 공격 및 공격 캠페인 탐지
- **성능 최적화** - 카테고리 기반 지연 패턴 로딩(관련 공격 카테고리에 대해서만 정규식 실행), 깨끗한 요청에 대한 조기 종료, 브라우저 UA 단락(일반 브라우저에 대해 70개 이상의 검사 건너뛰기), 프로브 경로 해시 조회, 배치 DB 삽입, 요청당 구성 가능한 최대 탐지 수
- **데이터베이스 독립적** - MySQL, PostgreSQL, SQLite, SQL Server
- **제로 구성** - 합리적인 기본값으로 즉시 작동
- **설계상 안전** - 미들웨어는 자체 오류를 포착합니다. 탐지가 실패해도 앱은 계속 실행됩니다. 요청은 절대 차단되지 않습니다.

---

## 구성

이 패키지는 `.env` 변경 없이 작동합니다. 아래의 모든 값은 선택 사항입니다 - 기본값을 재정의하려는 경우에만 추가하세요.

```env
# Enable/disable detection globally (default: true)
THREAT_DETECTION_ENABLED=true

# Detection sensitivity (default: balanced)
# Options: strict, balanced, relaxed
THREAT_DETECTION_MODE=balanced

# Custom table name (default: threat_logs)
# THREAT_DETECTION_TABLE=threat_logs

# Your ISO 3166-1 alpha-2 country code (default: IN)
# Drives the is_foreign flag on every enriched row — set this or every
# non-Indian address is reported as foreign.
# THREAT_DETECTION_HOME_COUNTRY=IN

# Geo-enrichment provider used by threat-detection:enrich (default shown).
# HTTPS since v1.8.0. A failed lookup is never retried over cleartext, and a
# run in which every lookup failed exits non-zero rather than reporting
# success. Enrichment is opt-in either way.
#
# ip-api.com's free tier rejects HTTPS, so on the free tier this command will
# now fail rather than quietly sending your visitors' IP addresses in the
# clear. Either point it at a provider you hold a key for, or set it back
# explicitly and accept the disclosure.
# THREAT_DETECTION_GEO_ENDPOINT=https://ip-api.com/json

# Dashboard URL path (default: threat-detection)
# THREAT_DETECTION_DASHBOARD_PATH=threat-detection

# API route prefix (default: api/threat-detection)
# THREAT_DETECTION_API_PREFIX=api/threat-detection

# Role required when the API guard is 'role' (default: admin)
# THREAT_DETECTION_API_ROLE=admin

# Allowed IPs when the API guard is 'ip'. Comma-separated, CIDR supported.
# THREAT_DETECTION_API_IPS=127.0.0.1,10.0.0.0/8

# Username shown on Slack alerts (default: ThreatBot)
# THREAT_DETECTION_SLACK_USERNAME=ThreatBot

# Whitelist IPs to skip detection entirely (default: empty)
# Supports CIDR notation. Comma-separated.
# THREAT_DETECTION_WHITELISTED_IPS=10.0.0.0/8,192.168.1.0/24

# Static operator denylist read by ThreatDetection::isBlocklisted() (default: empty)
# The package itself never blocks — see "Acting on the Data" for the
# enforcement recipe. Supports CIDR. Whitelist wins on overlap.
# THREAT_DETECTION_BLOCKLISTED_IPS=203.0.113.0/24,198.51.100.7

# DDoS detection thresholds (defaults shown)
# THREAT_DETECTION_DDOS_THRESHOLD=300
# THREAT_DETECTION_DDOS_WINDOW=60

# Minimum confidence score to log a threat (default: 0)
# Threats below this score are silently ignored.
# THREAT_DETECTION_MIN_CONFIDENCE=0

# Slack notifications (disabled by default)
# THREAT_DETECTION_NOTIFICATIONS=true
# THREAT_DETECTION_SLACK_WEBHOOK=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
# THREAT_DETECTION_SLACK_CHANNEL=#threat-alerts

# Dashboard (disabled by default)
# THREAT_DETECTION_DASHBOARD=true

# API endpoints (enabled by default)
# THREAT_DETECTION_API=true

# API rate limiting (default: 60 requests per minute)
# THREAT_DETECTION_API_THROTTLE=60,1

# Queue support -  offload DB writes to a queue (disabled by default).
# OPTIONAL: only enable if your app already runs a queue worker. When false
# (default), threats are written synchronously with a plain DB insert -  no
# Redis, no worker, nothing extra to run.
# THREAT_DETECTION_QUEUE=false
# THREAT_DETECTION_QUEUE_CONNECTION=redis
# THREAT_DETECTION_QUEUE_NAME=default

# Auto-purge old logs (disabled by default)
# Requires Laravel scheduler to be running.
# THREAT_DETECTION_RETENTION=false
# THREAT_DETECTION_RETENTION_DAYS=90

# 404 probe tracking (enabled by default)
# Detects bots hitting /wp-admin, /.env, /phpmyadmin, etc.
# THREAT_DETECTION_PROBE_TRACKING=true

# Max detections per request (default: 0 = unlimited)
# Stop scanning after N pattern matches per request.
# THREAT_DETECTION_MAX_DETECTIONS=0

# Dashboard auth guard (default: none)
# Options: none, auth, role, ip
# THREAT_DETECTION_DASHBOARD_GUARD=none
# THREAT_DETECTION_DASHBOARD_ROLE=admin
# THREAT_DETECTION_DASHBOARD_IPS=127.0.0.1

# API auth guard (default: none -  uses existing middleware config)
# THREAT_DETECTION_API_GUARD=none
```

### 탐지 모드

---

[Read more](https://github.com/jay123anta/laravel-threat-detection)
도구 다운로드