VNX-357: Destructive link or button without a confirmation step
Reports Rails link_to/button_to calls that send DELETE with no confirm/turbo_confirm, and anchors with data-method="delete" or data-turbo-method="delete" and no data-confirm, so one click destroys data without warning.
| Field | Value |
|---|---|
| Rule ID | VNX-357 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | Ruby, HTML |
| CWE | CWE-357 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L |
| Tags | insufficient-dangerous-op-warning rails confirmation cwe-357 |
| Source | internal/sast/rules/vnx-357.rego |
Overview
VNX-357 maps to CWE-357: Insufficient UI Warning of Dangerous Operations. It reports the one place where a missing warning is visible in markup: an element that issues a DELETE request in one click, in a framework that offers a confirmation on the same element, without using it.
- Rails views and helpers (
.erb,.haml,.slim,.rb):link_to/button_towithmethod: :delete,:method => :deleteordata: { turbo_method: :delete }, whose call (followed across continuation lines) has noconfirm:,data-confirmorturbo_confirm. - HTML and templates: an
<a ... data-method="delete">tag (rails-ujs, jquery-ujs) with nodata-confirmordata-turbo-confirm.
Not reported: elements that ask for confirmation, GET/PATCH/POST links, sign-out links (Devise’s destroy_user_session_path, logout_path: a DELETE of the session, not of data), prose, ERB and HTML comments, and buttons wired to a JavaScript handler (onclick=, (click)=, @click=), because whether that handler confirms is decided in code this rule does not see.
Why This Matters
A Delete link next to Edit or Show is one mis-click away from destroying a record, and a row that renders in the wrong place makes that more likely. A confirmation step is the framework’s standard answer, and leaving it off is usually an oversight.
What Gets Flagged
<%# FLAGGED %>
<%= link_to 'Destroy', post, method: :delete %>
<%= button_to "Delete account", user_path(@user), method: :delete %>
<!-- FLAGGED -->
<a href="/admin/users/7" data-method="delete" rel="nofollow">Delete</a>
<%# NOT FLAGGED %>
<%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %>
<%= link_to "Delete", post_path(post), data: { turbo_method: :delete, turbo_confirm: "Delete this post?" } %>
Remediation
- Add
data: { turbo_confirm: "..." }(Turbo), ordata: { confirm: "..." }/data-confirm(rails-ujs) to every destructive link or button. - For irreversible operations, consider a typed confirmation or an undo window instead of a single dialog.
References
- CWE-357: Insufficient UI Warning of Dangerous Operations
- Turbo Handbook: Requiring confirmation for a visit
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-357
// nosec vnx-357
Or record an ignore rule: vulnetix ignore add --rule vnx-357 --reason "...". See Suppressing findings.