Files
Gnuboard7/lang/en/language_packs.php
T
HeuJung c4beb116ad fix(security): outbound URL 내부주소·host 검증 전수 강화
서버가 외부 입력으로 목적지가 제어되는 outbound HTTP 요청을 보내는 지점을
전수 조사해, 내부망(사설 IP·루프백·링크로컬·메타데이터)과 host 위조를 차단한다.
KVE-2026-1546(이니시스 인증 URL 접두사 매칭 우회)과 동일 클래스의
지점(언어팩 URL 설치, 스케줄 URL 호출, 배송비 계산 API, GitHub URL 판정)을
코어 공용 유틸 App\Support\OutboundUrlValidator 로 수렴시켰다.

- 접두사 매칭을 host 완전일치로 교체 — userinfo(@) 위장과 접미사 확장 도메인
 우회 벡터 차단.
- 사내 서버 호출이 정당한 관리자 지점(스케줄·외부 API)은 신규 설정
 security.allow_internal_outbound_urls(기본 off)로 옵트인.
- 언어팩 URL 설치는 원격 코드 다운로드라 옵트인과 무관하게 내부 주소 항상 차단.
- 웹소켓 연결 테스트는 localhost·사설 IP 가 정상 구성이므로 구조적 위조만 차단.

각 지점에 red 재현 → 수정 → green 회귀 테스트 + 실브라우저 E2E 로 검증.
수기 API 문서가 자동 재생성으로 소실되는 사고를 막는 PreToolUse 훅을 함께 추가한다.
2026-07-14 09:17:00 +09:00

65 lines
4.2 KiB
PHP

<?php
return [
'fetch_success' => 'Language pack list retrieved.',
'fetch_failed' => 'Failed to load language pack list: :error',
'not_found' => 'Language pack not found.',
'install_success' => 'Language pack installed.',
'install_failed' => 'Failed to install language pack: :error',
'activate_success' => 'Language pack activated.',
'activate_failed' => 'Failed to activate language pack: :error',
'deactivate_success' => 'Language pack deactivated.',
'deactivate_failed' => 'Failed to deactivate language pack: :error',
'uninstall_success' => 'Language pack removed.',
'uninstall_failed' => 'Failed to remove language pack: :error',
'manifest_invalid' => 'language-pack.json validation failed.',
'check_updates_success' => 'Update check completed.',
'check_updates_failed' => 'Failed to check updates: :error',
'update_success' => 'Language pack updated.',
'update_failed' => 'Failed to update language pack: :error',
'refresh_cache_success' => 'Language pack cache refreshed.',
'refresh_cache_failed' => 'Failed to refresh language pack cache: :error',
'preview_success' => 'Manifest preview completed.',
'preview_failed' => 'Failed to preview manifest: :error',
'errors' => [
'manifest_not_found' => 'language-pack.json file not found in archive.',
'manifest_invalid_json' => 'language-pack.json contains invalid JSON.',
'php_outside_backend' => 'PHP file detected outside the backend/ directory (:file).',
'unsafe_php_pattern' => 'Disallowed code pattern detected in PHP file (:file).',
'core_locale_missing' => 'A core language pack for ":locale" must be active first.',
'target_not_installed' => 'Target :scope (":target") is not installed.',
'target_inactive' => 'Target :scope (":target") is inactive. Activate it first.',
'target_version_too_old' => 'Target :scope (":target") version does not satisfy the required constraint (:constraint).',
'downgrade_blocked' => 'Downgrade blocked (:from → :to).',
'protected_pack' => 'Protected language packs cannot be deactivated or removed.',
'download_failed' => 'Failed to download from URL: :url',
'download_url_not_public' => 'Language packs cannot be downloaded from internal network addresses (private IPs, localhost, etc.). Use a publicly reachable https address.',
'checksum_mismatch' => 'Checksum mismatch.',
'update_no_source' => 'No update source available (only GitHub-sourced packs can be updated).',
'update_already_latest' => 'Already on the latest version.',
'preview_invalid_manifest' => 'Manifest preview failed: invalid manifest file.',
'operation_in_progress' => 'Another operation is in progress for language pack (:identifier). Please try again after it completes.',
'bundled_not_found' => 'Bundled directory (lang-packs/_bundled/:identifier) does not exist.',
'slot_conflict' => 'Slot already has an active language pack (:current). Confirm replacement with :target.',
'directory_not_writable' => 'The language pack install directory (:path) is not writable. Grant write permission to the web server user (e.g. www-data). Example: sudo chgrp www-data :path && sudo chmod g+w :path',
'identifier_not_found' => 'Language pack not found (:identifier).',
'unsupported_source' => 'Unsupported source (:source) — use one of bundled, github, url.',
],
'validation' => [
'file_required' => 'Upload a language pack ZIP file.',
'file_invalid' => 'Uploaded file is not valid.',
'file_too_large' => 'File size must not exceed 10 MB.',
'file_not_zip' => 'Only ZIP archives are accepted.',
'github_url_required' => 'Enter a GitHub URL.',
'github_url_invalid' => 'Enter a valid URL.',
'github_url_format' => 'Must be a GitHub repository URL (e.g. https://github.com/owner/repo).',
'url_required' => 'Enter a download URL.',
'url_invalid' => 'Enter a valid URL.',
'checksum_invalid' => 'SHA-256 checksum must be 64 hex characters.',
'identifier_required' => 'Enter the language pack identifier.',
'identifier_invalid' => 'Identifier may contain letters, numbers, dots, underscores and hyphens only.',
],
];