| @@ -5,8 +5,9 @@ | ||
| 5 | 5 | use FluentForm\App\Models\Submission; |
| 6 | 6 | use FluentForm\App\Modules\Acl\Acl; |
| 7 | 7 | use FluentForm\Framework\Http\Request\Request; |
| 8 | 8 | use FluentForm\Framework\Foundation\Policy; |
| 9 | +use FluentForm\Framework\Support\Arr; | |
| 9 | 10 | |
| 10 | 11 | class SubmissionPolicy extends Policy |
| 11 | 12 | { |
| 12 | 13 | /** |
| @@ -59,16 +60,29 @@ | ||
| 59 | 60 | $formId = $this->resolveFormId($request); |
| 60 | 61 | return Acl::hasPermission('fluentform_manage_entries', $formId); |
| 61 | 62 | } |
| 62 | 63 | |
| 64 | + public function submissionUsers(Request $request) | |
| 65 | + { | |
| 66 | + return $this->updateSubmissionUser($request); | |
| 67 | + } | |
| 68 | + | |
| 63 | 69 | /** |
| 64 | 70 | * Resolve the form_id for authorization. |
| 65 | - * For entry-scoped routes, always derive from the entry record to prevent | |
| 66 | - * attackers from passing an allowed form_id while targeting another form's entry. | |
| 71 | + * | |
| 72 | + * entry_id is read from the URL route parameter first so that a JSON body | |
| 73 | + * {"entry_id": X} cannot shadow the URL placeholder and cause the policy to | |
| 74 | + * authorize against a different record than the controller acts on (IDOR). | |
| 67 | 75 | */ |
| 68 | 76 | private function resolveFormId(Request $request) |
| 69 | 77 | { |
| 70 | - $entryId = $request->get('entry_id'); | |
| 78 | + $route = $request->route(); | |
| 79 | + $entryId = $route ? Arr::get($route->getParameter(), 'entry_id') : null; | |
| 80 | + | |
| 81 | + if (!$entryId) { | |
| 82 | + $entryId = $request->get('entry_id'); | |
| 83 | + } | |
| 84 | + | |
| 71 | 85 | if ($entryId) { |
| 72 | 86 | $submission = Submission::select('form_id')->find(intval($entryId)); |
| 73 | 87 | if ($submission) { |
| 74 | 88 | return $submission->form_id; |
| @@ -74,8 +88,12 @@ | ||
| 74 | 88 | return $submission->form_id; |
| 75 | 89 | } |
| 76 | 90 | } |
| 77 | 91 | |
| 78 | - $formId = $request->get('form_id'); | |
| 92 | + $formId = $route ? Arr::get($route->getParameter(), 'form_id') : null; | |
| 93 | + if (!$formId) { | |
| 94 | + $formId = $request->get('form_id'); | |
| 95 | + } | |
| 96 | + | |
| 79 | 97 | return $formId ? intval($formId) : null; |
| 80 | 98 | } |
| 81 | 99 | } |