From 4dcbc1c0c6d63daf058087c466dc2c58398c9bf0 Mon Sep 17 00:00:00 2001 From: phil Date: Tue, 6 Oct 2026 10:47:18 +0900 Subject: [PATCH] fix(security): Drop personal data from service logs CodeQL py/clear-text-logging-sensitive-data flagged 30 log calls that wrote employee identifiers, salary, gross pay, employer burden, billing ids and corporate card numbers in clear text. Logs leave the tenant boundary (aggregators, support access), so these values do not belong there. Remove only the flagged arguments; record ids, counts and non-personal context stay so the logs remain useful. No business logic changes. Co-Authored-By: Claude Fable 5.1 Signed-off-by: phil --- .../assets/oneerp_assets_app/services/fleet_service.py | 2 +- .../calendar/oneerp_calendar_app/events/handlers.py | 8 ++------ .../services/project_billing_service.py | 3 +-- .../oneerp_projects_app/services/timesheet_service.py | 2 +- .../oneerp_expenses_app/services/expense_service.py | 3 +-- .../oneerp_payroll_app/services/income_tax_service.py | 3 +-- .../services/korean_insurance_service.py | 3 +-- .../services/payroll_calculation_service.py | 3 +-- .../services/social_insurance_service.py | 4 +--- .../services/annual_leave_accrual_service.py | 3 +-- .../hr/hr/oneerp_hr_app/services/attendance_service.py | 9 +++------ services/hr/hr/oneerp_hr_app/services/leave_service.py | 10 ++++------ .../services/performance_appraisal_service.py | 3 +-- .../oneerp_hr_app/services/retirement_pay_service.py | 9 +++------ .../hr/hr/oneerp_hr_app/services/skill_map_service.py | 6 ++---- .../hr/hr/oneerp_hr_app/services/transfer_service.py | 3 +-- .../lms/services/course_enrollment_service.py | 6 +----- .../workreport/services/work_report_service.py | 3 +-- .../directory/events/handlers.py | 3 +-- .../oneerp_portal_core_app/portal/events/handlers.py | 4 +--- 20 files changed, 29 insertions(+), 61 deletions(-) diff --git a/services/assets/assets/oneerp_assets_app/services/fleet_service.py b/services/assets/assets/oneerp_assets_app/services/fleet_service.py index 6afb4f5..54514e2 100644 --- a/services/assets/assets/oneerp_assets_app/services/fleet_service.py +++ b/services/assets/assets/oneerp_assets_app/services/fleet_service.py @@ -52,7 +52,7 @@ def assign_vehicle( } ) - logger.info("차량 배정: %s → %s", vehicle_id, employee) + logger.info("차량 배정: %s (%s)", vehicle_id, assignment_id) return {"assignment_id": assignment_id, "vehicle": vehicle_id, "employee": employee} def record_trip( diff --git a/services/collab/calendar/oneerp_calendar_app/events/handlers.py b/services/collab/calendar/oneerp_calendar_app/events/handlers.py index c88975a..c75764a 100644 --- a/services/collab/calendar/oneerp_calendar_app/events/handlers.py +++ b/services/collab/calendar/oneerp_calendar_app/events/handlers.py @@ -52,10 +52,7 @@ async def handle_leave_approved(payload: dict[str, Any], event_id: str) -> None: limit=1, ) if not calendars: - logger.info( - "직원 '%s'의 활성 캘린더가 없어 부재 이벤트를 건너뜁니다", - employee_id, - ) + logger.info("활성 캘린더가 없어 부재 이벤트를 건너뜁니다") return calendar_id = calendars[0].get("_id", "") @@ -80,8 +77,7 @@ async def handle_leave_approved(payload: dict[str, Any], event_id: str) -> None: ) logger.info( - "휴가 승인 부재 이벤트 생성: 직원=%s, 캘린더=%s, event_id=%s", - employee_id, + "휴가 승인 부재 이벤트 생성: 캘린더=%s, event_id=%s", calendar_id, event_id, ) diff --git a/services/collab/projects/oneerp_projects_app/services/project_billing_service.py b/services/collab/projects/oneerp_projects_app/services/project_billing_service.py index 86aa924..ef958d8 100644 --- a/services/collab/projects/oneerp_projects_app/services/project_billing_service.py +++ b/services/collab/projects/oneerp_projects_app/services/project_billing_service.py @@ -84,8 +84,7 @@ def generate_billing( ) logger.info( - "프로젝트 청구: %s (프로젝트: %s, 금액: %s)", - billing_id, + "프로젝트 청구: 프로젝트 %s, 금액 %s", project_id, total, ) diff --git a/services/collab/projects/oneerp_projects_app/services/timesheet_service.py b/services/collab/projects/oneerp_projects_app/services/timesheet_service.py index f7eb650..eb080b1 100644 --- a/services/collab/projects/oneerp_projects_app/services/timesheet_service.py +++ b/services/collab/projects/oneerp_projects_app/services/timesheet_service.py @@ -332,7 +332,7 @@ def generate_invoice_from_timesheet( # 타임시트에 청구 완료 표시 self._ts_repo.update_by_id(timesheet_id, {"billed": True}) - logger.info("타임시트 청구: %s → %s (%s원)", timesheet_id, billing_id, amount) + logger.info("타임시트 청구: %s (%s원)", timesheet_id, amount) return { "billing_id": billing_id, "timesheet_id": timesheet_id, diff --git a/services/finance/expenses/oneerp_expenses_app/services/expense_service.py b/services/finance/expenses/oneerp_expenses_app/services/expense_service.py index a7022c6..cce5040 100644 --- a/services/finance/expenses/oneerp_expenses_app/services/expense_service.py +++ b/services/finance/expenses/oneerp_expenses_app/services/expense_service.py @@ -108,8 +108,7 @@ def match_card_transactions( ] logger.info( - "법인카드 매칭: 카드=%s (매칭: %d, 미매칭 거래: %d, 미매칭 청구: %d)", - card_number, + "법인카드 매칭: 매칭 %d, 미매칭 거래 %d, 미매칭 청구 %d", len(matched), len(unmatched_txns), len(unmatched_claims), diff --git a/services/finance/payroll/oneerp_payroll_app/services/income_tax_service.py b/services/finance/payroll/oneerp_payroll_app/services/income_tax_service.py index 6c95355..7ef15cb 100644 --- a/services/finance/payroll/oneerp_payroll_app/services/income_tax_service.py +++ b/services/finance/payroll/oneerp_payroll_app/services/income_tax_service.py @@ -142,8 +142,7 @@ def calculate_monthly_tax(gross_pay: float, dependents: int = 1) -> float: tax = max(0.0, base_tax - dependent_deduction) logger.info( - "소득세 산출: gross_pay=%s, dependents=%s, base_tax=%s, tax=%s", - gross_pay, + "소득세 산출: dependents=%s, base_tax=%s, tax=%s", dependents, base_tax, tax, diff --git a/services/finance/payroll/oneerp_payroll_app/services/korean_insurance_service.py b/services/finance/payroll/oneerp_payroll_app/services/korean_insurance_service.py index 2d379bc..08d9028 100644 --- a/services/finance/payroll/oneerp_payroll_app/services/korean_insurance_service.py +++ b/services/finance/payroll/oneerp_payroll_app/services/korean_insurance_service.py @@ -314,10 +314,9 @@ def calculate_payroll( ) logger.info( - "통합 급여 계산 완료: gross=%s, net=%s, employer=%s", + "통합 급여 계산 완료: gross=%s, net=%s", gross_pay, net_pay, - employer_burden, ) return PayrollBreakdown( diff --git a/services/finance/payroll/oneerp_payroll_app/services/payroll_calculation_service.py b/services/finance/payroll/oneerp_payroll_app/services/payroll_calculation_service.py index eb403bc..4ddca4c 100644 --- a/services/finance/payroll/oneerp_payroll_app/services/payroll_calculation_service.py +++ b/services/finance/payroll/oneerp_payroll_app/services/payroll_calculation_service.py @@ -251,9 +251,8 @@ def _calculate_single( self._slip_repo.insert(slip) logger.info( - "급여명세 생성: slip=%s, employee=%s, gross=%s, net=%s", + "급여명세 생성: slip=%s, gross=%s, net=%s", slip_id, - employee_id, gross_pay, net_pay, ) diff --git a/services/finance/payroll/oneerp_payroll_app/services/social_insurance_service.py b/services/finance/payroll/oneerp_payroll_app/services/social_insurance_service.py index ffda2ad..b7ef9ce 100644 --- a/services/finance/payroll/oneerp_payroll_app/services/social_insurance_service.py +++ b/services/finance/payroll/oneerp_payroll_app/services/social_insurance_service.py @@ -116,10 +116,8 @@ def calculate(self, base_salary: float | Decimal) -> InsuranceBreakdown: total = total_employee + total_employer logger.info( - "4대보험 산출 완료: tenant=%s, base_salary=%s, total=%s", + "4대보험 산출 완료: tenant=%s", self.tenant_id, - salary, - total, ) return InsuranceBreakdown( diff --git a/services/hr/hr/oneerp_hr_app/services/annual_leave_accrual_service.py b/services/hr/hr/oneerp_hr_app/services/annual_leave_accrual_service.py index bcb49d9..b034536 100644 --- a/services/hr/hr/oneerp_hr_app/services/annual_leave_accrual_service.py +++ b/services/hr/hr/oneerp_hr_app/services/annual_leave_accrual_service.py @@ -204,8 +204,7 @@ def accrue_leave( additional_days = max(0, total - base_days) logger.info( - "연차 산정: %s (근속: %d년 %d월, 출근률: %s%%, 규칙: %s, 총 %d일)", - employee_id, + "연차 산정: 근속 %d년 %d월, 출근률 %s%%, 규칙 %s, 총 %d일", years, total_months - years * 12, rate, diff --git a/services/hr/hr/oneerp_hr_app/services/attendance_service.py b/services/hr/hr/oneerp_hr_app/services/attendance_service.py index 80c5eac..af4b6b9 100644 --- a/services/hr/hr/oneerp_hr_app/services/attendance_service.py +++ b/services/hr/hr/oneerp_hr_app/services/attendance_service.py @@ -284,15 +284,13 @@ def check_weekly_work_hours( if exceeded_52h: logger.warning( - "주52시간 초과: %s (주간 %s, %.1f시간)", - employee_id, + "주52시간 초과: 주간 %s, %.1f시간", week_start_date, total_hours, ) if exceeded_overtime_12h: logger.warning( - "연장근로 12시간 초과: %s (연장 %.1f시간)", - employee_id, + "연장근로 12시간 초과: 연장 %.1f시간", overtime_hours, ) @@ -349,8 +347,7 @@ def check_health_checkup_due( is_due = today >= due_date logger.info( - "건강검진 주기 확인: %s (마지막: %s, 초과: %s)", - employee_id, + "건강검진 주기 확인: 마지막 %s, 초과 %s", latest_date.isoformat(), is_due, ) diff --git a/services/hr/hr/oneerp_hr_app/services/leave_service.py b/services/hr/hr/oneerp_hr_app/services/leave_service.py index 8ca019d..5db7e09 100644 --- a/services/hr/hr/oneerp_hr_app/services/leave_service.py +++ b/services/hr/hr/oneerp_hr_app/services/leave_service.py @@ -112,8 +112,7 @@ def process_compensatory_leave( ) logger.info( - "보상휴가 처리: %s (+%.1f일, 사유: %s)", - employee, + "보상휴가 처리: +%.1f일, 사유 %s", days, reason, ) @@ -188,7 +187,7 @@ def grant_annual_leave( } ) - logger.info("연차 부여: %s → %d일 (회계연도: %s)", employee_id, allocated_days, fiscal_year) + logger.info("연차 부여: %d일 (회계연도: %s)", allocated_days, fiscal_year) return { "employee": employee_id, "fiscal_year": fiscal_year, @@ -271,7 +270,7 @@ def process_leave_application( application_update["updated_by"] = actor_id app_repo.update_by_id(leave_app_id, application_update) - logger.info("휴가 승인: %s (%s, %.1f일)", leave_app_id, employee, total_days) + logger.info("휴가 승인: %s (%.1f일)", leave_app_id, total_days) return {"leave_app_id": leave_app_id, "status": "approved"} # reject @@ -439,8 +438,7 @@ def carry_forward_leave( total_expired += expired_days logger.info( - "연차 이월: %s (%s→%s, 이월: %.1f일, 소멸: %.1f일)", - employee_id, + "연차 이월: %s→%s, 이월 %.1f일, 소멸 %.1f일", from_year, to_year, total_carried, diff --git a/services/hr/hr/oneerp_hr_app/services/performance_appraisal_service.py b/services/hr/hr/oneerp_hr_app/services/performance_appraisal_service.py index dc8338e..c98fec0 100644 --- a/services/hr/hr/oneerp_hr_app/services/performance_appraisal_service.py +++ b/services/hr/hr/oneerp_hr_app/services/performance_appraisal_service.py @@ -103,8 +103,7 @@ def create_appraisal( self._appraisal_repo.insert(doc) logger.info( - "평가 생성: %s (사이클: %s, 평가자: %s)", - employee_id, + "평가 생성: 사이클 %s, 평가자 %s", appraisal_cycle_id, reviewer_id, ) diff --git a/services/hr/hr/oneerp_hr_app/services/retirement_pay_service.py b/services/hr/hr/oneerp_hr_app/services/retirement_pay_service.py index 23bfb12..26e8e1c 100644 --- a/services/hr/hr/oneerp_hr_app/services/retirement_pay_service.py +++ b/services/hr/hr/oneerp_hr_app/services/retirement_pay_service.py @@ -111,8 +111,7 @@ def calculate_average_wage( ) logger.info( - "평균임금 산정: %s (기간: %s~%s, 총임금: %s, 일평균: %s)", - employee_id, + "평균임금 산정: 기간 %s~%s, 총임금 %s, 일평균 %s", period_start.isoformat(), period_end.isoformat(), total_wage, @@ -208,8 +207,7 @@ def calculate_retirement_pay( retirement_pay = Decimal(0) logger.info( - "퇴직금 산정: %s (근속일: %d, 일급: %s, 퇴직금: %s, 지급대상: %s)", - employee_id, + "퇴직금 산정: 근속일 %d, 일급 %s, 퇴직금 %s, 지급대상 %s", service_days, applied_daily, retirement_pay, @@ -258,8 +256,7 @@ def record_retirement_pay( } self._retirement_repo.insert(record) logger.info( - "퇴직금 기록 저장: %s (%s원)", - employee_id, + "퇴직금 기록 저장: %s원", result["retirement_pay"], ) return record diff --git a/services/hr/hr/oneerp_hr_app/services/skill_map_service.py b/services/hr/hr/oneerp_hr_app/services/skill_map_service.py index f7c79d5..c44028f 100644 --- a/services/hr/hr/oneerp_hr_app/services/skill_map_service.py +++ b/services/hr/hr/oneerp_hr_app/services/skill_map_service.py @@ -68,8 +68,7 @@ def evaluate_skills( ) logger.info( - "역량 평가: %s (역량: %d개, 평균: %.2f)", - employee, + "역량 평가: 역량 %d개, 평균 %.2f", len(skills), avg_score, ) @@ -163,8 +162,7 @@ def check_mandatory_courses( ) logger.info( - "필수 교육 미수료 확인: %s (미수료: %d건)", - employee_id, + "필수 교육 미수료 확인: 미수료 %d건", len(incomplete), ) diff --git a/services/hr/hr/oneerp_hr_app/services/transfer_service.py b/services/hr/hr/oneerp_hr_app/services/transfer_service.py index a76f888..bf774ab 100644 --- a/services/hr/hr/oneerp_hr_app/services/transfer_service.py +++ b/services/hr/hr/oneerp_hr_app/services/transfer_service.py @@ -98,8 +98,7 @@ def execute_transfer( self._employee_repo.update_by_id(employee, {"$push": {"_outbox": outbox_entry}}) logger.info( - "인사이동: %s (%s → %s, %s → %s)", - employee, + "인사이동: %s → %s, %s → %s", old_department, new_department or old_department, old_designation, diff --git a/services/hr/learning/oneerp_learning_app/lms/services/course_enrollment_service.py b/services/hr/learning/oneerp_learning_app/lms/services/course_enrollment_service.py index c987802..45dba95 100644 --- a/services/hr/learning/oneerp_learning_app/lms/services/course_enrollment_service.py +++ b/services/hr/learning/oneerp_learning_app/lms/services/course_enrollment_service.py @@ -144,11 +144,7 @@ def enroll(self, request: EnrollmentRequest) -> dict[str, Any]: current_enrolled=request.current_enrolled, duplicate_exists=request.duplicate_exists, ) - logger.info( - "수강 신청: 과정=%s, 직원=%s", - request.course.get("_id", ""), - request.employee_id, - ) + logger.info("수강 신청: 과정=%s", request.course.get("_id", "")) return { "course_ref": request.course.get("_id", ""), "employee_id": request.employee_id, diff --git a/services/hr/learning/oneerp_learning_app/workreport/services/work_report_service.py b/services/hr/learning/oneerp_learning_app/workreport/services/work_report_service.py index 8065972..4cc0975 100644 --- a/services/hr/learning/oneerp_learning_app/workreport/services/work_report_service.py +++ b/services/hr/learning/oneerp_learning_app/workreport/services/work_report_service.py @@ -455,10 +455,9 @@ def create_from_template( self._report_repo.insert(doc) logger.info( - "템플릿 기반 업무일지 생성: %s (템플릿: %s, 작성자: %s)", + "템플릿 기반 업무일지 생성: %s (템플릿: %s)", report_id, template_id, - employee_id, ) return { diff --git a/services/portal/portal_comms/oneerp_portal_comms_app/directory/events/handlers.py b/services/portal/portal_comms/oneerp_portal_comms_app/directory/events/handlers.py index 7ac4545..f47d4af 100644 --- a/services/portal/portal_comms/oneerp_portal_comms_app/directory/events/handlers.py +++ b/services/portal/portal_comms/oneerp_portal_comms_app/directory/events/handlers.py @@ -55,7 +55,6 @@ def handle_employee_updated(event_data: dict[str, Any]) -> None: updated_count += 1 logger.info( - "직원 정보 변경 반영: %s → 인명부 %d건 갱신", - employee_id, + "직원 정보 변경 반영: 인명부 %d건 갱신", updated_count, ) diff --git a/services/portal/portal_core/oneerp_portal_core_app/portal/events/handlers.py b/services/portal/portal_core/oneerp_portal_core_app/portal/events/handlers.py index d8e54b1..7e6352e 100644 --- a/services/portal/portal_core/oneerp_portal_core_app/portal/events/handlers.py +++ b/services/portal/portal_core/oneerp_portal_core_app/portal/events/handlers.py @@ -36,11 +36,9 @@ def handle_employee_department_changed(event_data: dict[str, Any]) -> None: EMPLOYEE_DEPARTMENT_CHANGED 이벤트를 수신하여 해당 사용자의 개인 대시보드 캐시를 무효화한다. """ - employee_id = event_data.get("doc_id", "") new_department = event_data.get("data", {}).get("new_department", "") logger.info( - "부서 변경 이벤트: employee=%s, 새 부서=%s — 레이아웃 재계산", - employee_id, + "부서 변경 이벤트: 새 부서=%s — 레이아웃 재계산", new_department, ) # 개인 대시보드 캐시 무효화