-
Notifications
You must be signed in to change notification settings - Fork 0
Feat(#17): 문자 분석 통합 엔드포인트 및 3중 가중치 스코어링 시스템 구현 #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
8384f76
feat: extend Pydantic schemas for final score and contribution breakdown
pearseona 7991f7d
feat: implement triple-layered weighted scoring algorithm and risk gr…
pearseona 7970a56
feat: implement triple-layered weighted scoring algorithm and risk gr…
pearseona facfa6c
feat: create unified mobile message analysis endpoint
pearseona aefd2b5
feat: extract hybrid url engine and orchestrate pipelines asynchronou…
pearseona f01227b
feat: connect unified smishing analysis endpoint to pipeline
pearseona 97066a3
fix: resolve edge cases for messages without URLs and secure fail-saf…
pearseona 3cdfbf2
refactor: fix pipeline bugs and stabilize core smishing detection wor…
pearseona File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,49 +1,33 @@ | ||
| from fastapi import APIRouter, Depends, HTTPException, status | ||
| from app.dto.response import ApiResponse | ||
| from app.dto.request import AnalyzeRequest | ||
| from app.dto.schemas import URLScanResponse | ||
| from app.service.security.gemini_text_analyzer import analyze_text_with_gemini | ||
| import logging | ||
| from fastapi import APIRouter, Depends, status, HTTPException | ||
| from app.dto.schemas import URLScanRequest, SmishingAnalysisResponse | ||
| from app.service.scan_service import ScanService | ||
|
|
||
| # 문자 분석 전용 라우터 생성 | ||
| logger = logging.getLogger(__name__) | ||
|
|
||
| router = APIRouter(prefix="/analyze", tags=["Analyze"]) | ||
|
|
||
| # 서비스 인스턴스 생성 유틸 | ||
| def get_scan_service() -> ScanService: | ||
| return ScanService() | ||
|
|
||
| # 통합 스미싱 탐지 API | ||
| @router.post("", response_model=ApiResponse[dict], status_code=status.HTTP_200_OK) | ||
| @router.post( | ||
| "", | ||
| response_model=SmishingAnalysisResponse, | ||
| status_code=status.HTTP_200_OK, | ||
| summary="[메인 통합 엔진] 문자 본문 기반 3중 스미싱 통합 분석" | ||
| ) | ||
| async def analyze_smishing( | ||
| payload: AnalyzeRequest, | ||
| payload: URLScanRequest, | ||
| scan_service: ScanService = Depends(get_scan_service) | ||
| ): | ||
|
|
||
| try: | ||
| text_analysis = await analyze_text_with_gemini(payload.message) | ||
|
|
||
| url_scan_result: URLScanResponse = await scan_service.scan_message_text(payload.message) | ||
|
|
||
| real_url_analysis = { | ||
| "has_url": url_scan_result.has_url, | ||
| "is_shortened": url_scan_result.original_url != url_scan_result.traced_url if url_scan_result.has_url else False, | ||
| "origin_url": url_scan_result.traced_url, # 최종 목적지 URL | ||
| "original_url": url_scan_result.original_url, # 최초 추출 URL | ||
| "is_url_malicious": url_scan_result.is_url_malicious, | ||
| "url_risk_score": url_scan_result.url_risk_score, | ||
| "engine_source": url_scan_result.engine_source, | ||
| "error_message": url_scan_result.error_message | ||
| } | ||
| ) -> SmishingAnalysisResponse: | ||
|
|
||
| is_smishing_detected = (text_analysis.get("result", {}).get("grade") != "SAFE") or url_scan_result.is_url_malicious | ||
|
|
||
| result = { | ||
| "smishing_detected": is_smishing_detected, | ||
| "text_analysis": text_analysis, | ||
| "url_analysis": real_url_analysis | ||
| } | ||
|
|
||
| return ApiResponse.success(data=result, message="문자 분석이 완료되었습니다.") | ||
| logger.info(f"[Router] 통합 스미싱 분석 마스터 파이프라인 진입: {payload.text[:15]}...") | ||
|
|
||
| try: | ||
| return await scan_service.analyze_pipeline(payload.text) | ||
| except Exception as e: | ||
| return ApiResponse.error(message=f"통합 스미싱 탐지 중 서버 에러가 발생했습니다: {str(e)}") | ||
| logger.error(f"[Router] 스캔 처리 중 장애 발생: {str(e)}") | ||
| raise HTTPException( | ||
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | ||
| detail=f"서버 내부 스캔 파이프라인 연산 중 오류: {str(e)}" | ||
| ) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Insecure CORS: wildcard origin combined with credentials.
The CORS middleware configured below (per the static-analysis hint) pairs
allow_origins=["*"]withallow_credentials=Trueand wildcard methods/headers. With credentials enabled, Starlette/FastAPI reflects the requestOrigin, effectively allowing any site to make authenticated cross-origin requests (CWE-942 / OWASP A05:2021). Replace the wildcard with an explicit origin allowlist (your frontend and Spring Boot hosts) and enumerate allowed methods/headers when credentials are enabled.🔒️ Suggested direction
🧰 Tools
🪛 ast-grep (0.44.1)
[warning] 11-17: CORSMiddleware allows credentials together with a wildcard origin, methods, or headers, which lets any site issue authenticated cross-origin requests. Use an explicit origin allowlist and enumerate the allowed methods/headers when allow_credentials=True.
Context: app.add_middleware(
CORSMiddleware,
allow_origins=[""],
allow_credentials=True,
allow_methods=[""],
allow_headers=["*"],
)
Note: [CWE-942] Permissive Cross-domain Policy with Untrusted Domains. OWASP A05:2021 Security Misconfiguration. Starlette/FastAPI CORSMiddleware reflects the request Origin when credentials are enabled, so pairing allow_credentials=True with a wildcard origin/methods/headers exposes authenticated endpoints to any site.
(starlette-cors-credentials-wildcard-python)
🤖 Prompt for AI Agents
Source: Linters/SAST tools