본문 바로가기

공지사항

공지사항을 알려드립니다.

일반공고 sirsoft-board 정책 제한값 하드코딩 문제

페이지 정보

profile_image
작성자 관리자
조회 24회 작성일 26-07-18 18:09

본문

게시판부분만 점검해 봤습니다.  전체적으로 점검해봐야할 문제라 생각 됩니다. 



# sirsoft-board 정책 제한값 하드코딩 1차 감사 보고서


> 제안 이슈 제목: `[sirsoft-board] 설정 제한값 하드코딩과 정책 불일치로 검증·서비스·UI 계약이 분리됨`


## 결론


**첨부파일 최대 20개 한 건의 문제가 아니라, 설정 가능한 정책값이 검증 요청, 서비스, JSON UI, 다국어 문구, API 문서에 중복 하드코딩되어 실제 계약이 분리된 구조적 결함입니다.**


**본 보고서는 확인된 제한값 관련 경로를 대상으로 한 일부 감사입니다. 이번 결과만으로 `sirsoft-board` 전체 또는 그누보드7 전체에 하드코딩 문제가 없다고 판단할 수 없으며, 정식 출시 전 별도의 전수 감사가 필요합니다.**


중앙 설정이 일부 존재하지만 적용 범위가 일관되지 않아 다음 문제가 이미 발생하고 있습니다.


확인된 핵심 위험은 다음과 같습니다.


| 우선순위 | 문제 | 현재 영향 |

|---|---|---|

| 높음 | 대댓글 저장 깊이가 서비스에서 `5`로 고정됨 | 설정값 `6~10`에서 깊이 제한과 계층 표현이 깨짐 |

| 높음 | 중앙 길이 제한과 관리자 기본설정 API의 검증값이 다름 | UI가 허용하는 `0`을 저장 API가 거부함 |

| 높음 | 비동기 첨부 연결 경로에 게시판별 개수 상한이 없음 | `max_file_count`를 초과한 첨부 연결 가능 |

| 중간 | 자동 숨김 `0=비활성` 정책과 UI 최소값이 다름 | API는 `0`을 허용하지만 관리자 UI는 입력을 막음 |

| 중간 | 답변 깊이 상한이 코드와 문서에서 `10`과 `5`로 분리됨 | 관리자 안내와 API 계약이 실제 검증 규칙과 다름 |

| 낮음 | 표시용 깊이와 첨부 안내 문구가 숫자를 직접 보유함 | 정책 변경 시 화면과 번역 리소스가 다시 어긋날 수 있음 |


최대 첨부 개수 `20`이라는 정책 자체가 결함인 것은 아닙니다. 문제는 이 값을 한 곳에서 변경해도 모든 검증과 UI가 함께 변경되지 않으며, 일부 실제 처리 경로는 해당 정책을 강제하지 않는 구조입니다.


## 감사 범위와 추가 필요성


이번 감사는 `sirsoft-board`에서 제한값 불일치가 확인된 게시판 설정, 댓글·답변 깊이, 첨부파일, 신고·스팸 설정과 직접 연결된 코드만 우선 대조한 1차 표본 감사입니다.


다음 범위는 전수 확인하지 않았으므로 추가 감사가 필요합니다.


- `sirsoft-board` 전체 Controller, Request, Service, Repository, Listener, Job, migration, JSON UI 및 문서

- 숫자 제한 외 상태값, 문자열 Enum, 기본값, 캐시 TTL, 페이지 크기, 재시도 횟수와 배치 크기

- 코어와 다른 번들 모듈·플러그인의 설정값 중복 및 모듈 간 계약 불일치

- 환경설정 변경 시 API, 관리자 UI, 사용자 UI, CLI·Queue가 동일하게 반영되는지에 대한 경계값 테스트


따라서 본 보고서의 확인 항목을 수정하는 것과 별개로, 저장소 전체를 대상으로 정책값 출처와 소비 지점을 자동 대조하는 전수 감사 작업을 진행해야 합니다.


## 확인 기준


| 항목 | 값 |

|---|---|

| 그누보드 버전 | `7.0.4` |

| 원본 게시판 모듈 버전 | `sirsoft-board 1.1.3` |

| 확인 커밋 | `348efa2e98df22b00d30d3a4e267d0305f201758` |

| 확인일 | `2026-07-17` |

| 분석 범위 | 확인된 제한값 관련 config, defaults, FormRequest, Service/Rule, JSON UI, lang, API 문서의 일부 경로 |


현재 작업트리의 별도 첨부 개선 코드와 버전 변경은 원본 결함 근거에서 제외하고, 위 커밋의 원본 코드만 대조했습니다. 본 보고서는 정적 소스 감사 결과이며 원본 코드는 수정하지 않았습니다.


## 상세 결과


### H-01. 대댓글 깊이가 서비스에서 5로 고정됨


중앙 설정은 대댓글 깊이를 `0~10`으로 정의하고 기본값도 `10`으로 지정합니다.


- `modules/_bundled/sirsoft-board/config/board.php:151`

- `modules/_bundled/sirsoft-board/config/settings/defaults.json:18`


검증 규칙도 게시판의 `max_comment_depth`를 사용합니다.


- `modules/_bundled/sirsoft-board/src/Rules/CommentValidationRule.php:114`


그러나 실제 저장 깊이는 다음 서비스 코드에서 `5`로 잘립니다.


```php

$data['depth'] = min(($parentComment->depth ?? 0) + 1, 5);

```


- `modules/_bundled/sirsoft-board/src/Services/CommentService.php:257`


이 때문에 설정값이 `6~10`이면 검증은 더 깊은 대댓글을 허용해도 저장된 `depth`는 계속 5가 됩니다. 이후 검증 역시 부모의 저장 깊이 5를 기준으로 판단하므로 설정 상한이 사실상 무력화될 수 있습니다.


### H-02. 중앙 길이 제한과 관리자 기본설정 API가 불일치함


중앙 제한값은 최소 제목 및 최소 댓글 길이에 `0`을 허용합니다.


```php

'min_title_length_min' => 0,

'min_comment_length_min' => 0,

```


- `modules/_bundled/sirsoft-board/config/board.php:121`

- `modules/_bundled/sirsoft-board/config/board.php:133`


게시판 생성·수정 요청과 관리자 JSON UI는 이 중앙 값을 사용합니다.


- `modules/_bundled/sirsoft-board/src/Http/Requests/StoreBoardRequest.php:116`

- `modules/_bundled/sirsoft-board/src/Http/Requests/UpdateBoardRequest.php:95`

- `modules/_bundled/sirsoft-board/resources/layouts/admin/partials/admin_board_settings/_tab_board_settings_post.json:120`

- `modules/_bundled/sirsoft-board/resources/layouts/admin/partials/admin_board_settings/_tab_board_settings_comment.json:372`


반면 관리자 기본설정 저장 요청은 두 최소값을 직접 `1`로 고정합니다.


```php

'basic_defaults.min_title_length' => ['nullable', 'integer', 'min:1', 'max:200'],

'basic_defaults.min_comment_length' => ['nullable', 'integer', 'min:1', 'max:1000'],

```


- `modules/_bundled/sirsoft-board/src/Http/Requests/Admin/StoreBoardSettingsRequest.php:151`

- `modules/_bundled/sirsoft-board/src/Http/Requests/Admin/StoreBoardSettingsRequest.php:155`


동일한 설정값이 화면에서는 유효하지만 저장 API에서는 422가 되는 계약 불일치입니다.


### H-03. 첨부 개수 정책이 중복되고 비동기 연결 경로에서는 강제되지 않음


게시판 설정의 허용 범위는 중앙 config에 `1~20`으로 정의되어 있습니다.


- `modules/_bundled/sirsoft-board/config/board.php:141`


게시판 생성·수정 요청은 중앙 상한을 사용하지만, 관리자 기본설정 저장 요청은 `20`을 다시 직접 보유합니다.


```php

'basic_defaults.max_file_count' => ['nullable', 'integer', 'min:1', 'max:20'],

```


- `modules/_bundled/sirsoft-board/src/Http/Requests/Admin/StoreBoardSettingsRequest.php:159`


더 큰 문제는 실제 게시글 저장 API의 비동기 첨부 경로입니다. 원본 요청 검증은 `attachment_ids`가 배열과 정수인지 확인할 뿐 게시판의 `max_file_count`를 적용하지 않습니다.


- `modules/_bundled/sirsoft-board/src/Http/Requests/StorePostRequest.php:89`

- `modules/_bundled/sirsoft-board/src/Http/Requests/UpdatePostRequest.php:64`

- `modules/_bundled/sirsoft-board/src/Http/Requests/User/StorePostRequest.php:109`

- `modules/_bundled/sirsoft-board/src/Http/Requests/User/UpdatePostRequest.php:74`


단일 파일 업로드 요청도 파일 크기와 확장자만 검증하며 누적 개수는 확인하지 않습니다.


- `modules/_bundled/sirsoft-board/src/Http/Requests/UploadAttachmentRequest.php:42`


서비스는 전달받은 ID 또는 같은 `temp_key`의 첨부를 개수 확인 없이 연결합니다.


- `modules/_bundled/sirsoft-board/src/Services/PostService.php:830`

- `modules/_bundled/sirsoft-board/src/Services/PostService.php:844`

- `modules/_bundled/sirsoft-board/src/Services/AttachmentService.php:184`


따라서 UI의 `FileUploader` 제한을 우회한 API 요청에서는 게시판별 최대 첨부 개수가 서버의 최종 불변조건으로 보장되지 않습니다.


### M-01. 자동 숨김 비활성 값이 UI와 백엔드에서 다름


백엔드 검증은 `auto_hide_threshold`에 `0~100`을 허용합니다.


- `modules/_bundled/sirsoft-board/src/Http/Requests/Admin/StoreBoardSettingsRequest.php:178`


서비스와 테스트는 `0`을 자동 숨김 비활성 값으로 명시합니다.


- `modules/_bundled/sirsoft-board/src/Services/ReportService.php:732`

- `modules/_bundled/sirsoft-board/tests/Feature/Admin/AutoHideTest.php:184`


그러나 관리자 JSON UI는 최소값을 `1`로 고정합니다.


```json

"min": 1,

"max": 100

```


- `modules/_bundled/sirsoft-board/resources/layouts/admin/partials/admin_board_settings/_tab_report_policy.json:81`


결과적으로 지원되는 비활성 설정을 관리자 화면에서 정상적으로 입력할 수 없습니다.


### M-02. 답변 깊이 계약이 코드와 문서에서 10과 5로 분리됨


현재 검증 상한은 config 기준 `10`이며, 관련 회귀 테스트도 10을 기대합니다.


- `modules/_bundled/sirsoft-board/config/board.php:148`

- `modules/_bundled/sirsoft-board/tests/Feature/Admin/BoardSettingsControllerTest.php:427`

- `modules/_bundled/sirsoft-board/tests/Playwright/specs/admin/board-settings-range-hints.spec.ts:48`


하지만 다음 원본 자료는 여전히 `1~5`로 안내합니다.


- `modules/_bundled/sirsoft-board/database/migrations/2026_04_01_000002_create_boards_table.php:32`

- `modules/_bundled/sirsoft-board/resources/lang/partial/ko/admin.json:905`

- `modules/_bundled/sirsoft-board/resources/lang/partial/ko/admin.json:977`

- `modules/_bundled/sirsoft-board/resources/lang/partial/en/admin.json:977`

- `modules/_bundled/sirsoft-board/docs/api/boards.md:60`


API 문서 안에서도 요청 검증 상한과 응답 필드 설명이 서로 다를 수 있어 외부 클라이언트가 어느 값을 계약으로 따라야 하는지 불명확합니다.


### M-03. 중앙 목록에 없는 운영 정책값이 백엔드와 JSON UI에 반복됨


`new_display_hours`, 신고 정책, 스팸 제한값은 운영자가 변경하는 설정이지만 `config('sirsoft-board.limits')`에 포함되지 않습니다. 같은 숫자가 FormRequest와 JSON UI에 각각 반복됩니다.


대표 사례:


| 설정 | 백엔드 | JSON UI |

|---|---|---|

| 신규 표시 시간 | `1~720` | `1~720` |

| 일일 신고 제한 | `0~100` | `0~100` |

| 신고 거절 횟수 | `0~50` | `0~50` |

| 신고 거절 기간 | `1~365` | `1~365` |

| 글·댓글·신고 쿨다운 | `0~3600` | `0~3600` |

| 조회수 캐시 TTL | `60~604800` | `60~604800` |


근거:


- `modules/_bundled/sirsoft-board/src/Http/Requests/Admin/StoreBoardSettingsRequest.php:168`

- `modules/_bundled/sirsoft-board/src/Http/Requests/Admin/StoreBoardSettingsRequest.php:178`

- `modules/_bundled/sirsoft-board/src/Http/Requests/Admin/StoreBoardSettingsRequest.php:211`

- `modules/_bundled/sirsoft-board/resources/layouts/admin/partials/admin_board_settings/_tab_board_settings_post.json:581`

- `modules/_bundled/sirsoft-board/resources/layouts/admin/partials/admin_board_settings/_tab_report_policy.json:223`

- `modules/_bundled/sirsoft-board/resources/layouts/admin/partials/admin_board_settings/_tab_spam_security.json:73`


현재 값이 일치하더라도 어느 한쪽만 수정하면 즉시 계약이 분리됩니다. M-01은 이 구조가 이미 실제 오류로 이어진 사례입니다.


### L-01. 표시 상한과 정적 안내 문구도 정책 숫자를 직접 보유함


댓글과 답변글 들여쓰기는 화면에서 깊이를 `10`으로 직접 제한합니다.


- `templates/_bundled/sirsoft-basic/layouts/partials/board/show/_comment_item.json:11`

- `templates/_bundled/sirsoft-basic/layouts/partials/board/types/basic/index.json:281`

- `modules/_bundled/sirsoft-board/resources/layouts/admin/partials/admin_board_post_detail/_comments.json:72`


현재 서버 상한과는 일치하지만 상한을 변경하면 데이터 깊이와 화면 표현이 분리됩니다. 표시 상한이 의도된 별도 UX 정책이라면 이름 있는 설정으로 분리해야 합니다.


또한 현재 레이아웃 사용처는 확인되지 않았지만 다국어 리소스에는 여전히 `최대 5개, 10MB` 문구가 남아 있습니다.


- `modules/_bundled/sirsoft-board/resources/lang/partial/ko/admin.json:723`

- `modules/_bundled/sirsoft-board/resources/lang/partial/en/admin.json:722`


사용되지 않는 문구라도 다시 참조되면 게시판별 설정과 다른 안내가 노출될 수 있으므로 제거하거나 동적 치환 방식으로 통일해야 합니다.