Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@
5. DoS μ™„ν™”λ₯Ό μœ„ν•΄ `return(1L)` 같은 κΈ°λ³Έ μŠΉμΈκ°’μ„ 넣을 λ•ŒλŠ” μΆ”μ • 기쀀척도, anchor/common item, true parameter μž¬ν˜„ 계약을 μš°νšŒν•˜μ§€ μ•ŠλŠ”μ§€ λ¨Όμ € κ²€μ¦ν•©λ‹ˆλ‹€.
6. Fail-secure μ—λŸ¬ λ©”μ‹œμ§€λŠ” ν…ŒμŠ€νŠΈμ˜ μΌλΆ€λ‘œ μ·¨κΈ‰ν•©λ‹ˆλ‹€. λ³΄μ•ˆ ν…ŒμŠ€νŠΈλŠ” μ‹€μ œ κ΅¬ν˜„ λ©”μ‹œμ§€μ™€ λ§žμ•„μ•Ό ν•˜λ©°, 였래된 `"Interactive prompt is not available"` 같은 별도 문ꡬλ₯Ό μƒˆλ‘œ λ§Œλ“€μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
7. Prompt DoS νšŒκ·€ ν…ŒμŠ€νŠΈλŠ” λͺ¨λΈ μΆ”μ • μ‹€νŒ¨μ— κΈ°λŒ€μ§€ 말고, common-item confirmation guard처럼 μ·¨μ•½ν•œ μž…λ ₯ κ²½κ³„μ—μ„œ λ°”λ‘œ λ°œμƒν•˜λŠ” fail-secure μ—λŸ¬λ₯Ό κ²€μ¦ν•©λ‹ˆλ‹€.

## 2024-06-25 - Unbounded Loop in Model Retry (Infinite Loop DoS)
**Vulnerability:** When the initial `mirt::mirt()` model estimation failed, the code utilized an unconstrained `while (!exists('model'))` loop to continually attempt re-estimation. Since R's deterministic errors inside `try()` would repetitively fail without side-effects altering the outcome, this created an infinite loop Denial of Service (DoS) in automated environments.
**Learning:** Deterministic failure handling must never rely on unbounded loops. Relying on `try()` combined with `while (!exists(...))` assumes transient errors, which is often not true for statistical model convergence issues.
**Prevention:**
1. Always replace `while (!exists(...))` retries with a bounded `for` loop (e.g., `for (attempt in seq_len(3))`).
2. Include an explicit check for the success condition inside the loop (`if (exists('model')) break`).
3. After the loop, verify success and fail securely with an explicit error (`if (!exists('model')) stop(...)`) to prevent unhandled exceptions downstream.
18 changes: 12 additions & 6 deletions R/aFIPC.R
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ autoFIPC <-
'Estimation failed. estimating new parameters with no prior distribution using Cai\'s (2010) Metropolis-Hastings Robbins-Monro (MHRM) algorithm. please be patient.'
)

try(rm(oldFormModel))
while (!exists('oldFormModel')) {
try(rm(oldFormModel), silent = TRUE)
for (attempt in seq_len(3)) {
try(
oldFormModel <-
mirt::mirt(
Expand All @@ -230,7 +230,9 @@ autoFIPC <-
GenRandomPars = F
)
)
if (exists('oldFormModel')) break
}
if (!exists('oldFormModel')) stop('Failed to estimate oldFormModel with MHRM after 3 attempts')
}
}

Expand Down Expand Up @@ -427,8 +429,8 @@ autoFIPC <-
'Estimation failed. estimating new parameters with no prior distribution using Cai\'s (2010) Metropolis-Hastings Robbins-Monro (MHRM) algorithm. please be patient.'
)

try(rm(newFormModel))
while (!exists('newFormModel')) {
try(rm(newFormModel), silent = TRUE)
for (attempt in seq_len(3)) {
try(
newFormModel <-
mirt::mirt(
Expand All @@ -442,7 +444,9 @@ autoFIPC <-
GenRandomPars = F
)
)
if (exists('newFormModel')) break
}
if (!exists('newFormModel')) stop('Failed to estimate newFormModel with MHRM after 3 attempts')
}
}

Expand Down Expand Up @@ -975,10 +979,12 @@ autoFIPC <-
# if(!LinkedModel@OptimInfo$secondordertest){
# message('Estimation failed. estimating new parameters with no prior distribution using Cai\'s (2010) Metropolis-Hastings Robbins-Monro (MHRM) algorithm. please be patient.')
#
# rm(LinkedModel)
# while (!exists('LinkedModel')) {
# try(rm(LinkedModel), silent = TRUE)
# for (attempt in seq_len(3)) {
# try(LinkedModel <- mirt::mirt(data = newformXDataK[colnames(newFormModel@Data$data)], LinkedModelSyntax, itemtype = newFormModel@Model$itemtype, SE = T, method = 'MHRM', accelerate = 'squarem', technical = list(NCYCLES = 1e+5, MHRM_SE_draws = 200000), pars = NewScaleParms, GenRandomPars = T))
# if (exists('LinkedModel')) break
# }
# if (!exists('LinkedModel')) stop('Failed to estimate LinkedModel with MHRM after 3 attempts')
# }

# if(!LinkedModel@OptimInfo$secondordertest){
Expand Down
Loading