Repository navigation
Issue #120 (ginkelsoft-development/buildora): onderzoeken of store/update in BuildoraController kwetsbaar is voor mass assignment via velden buiten defineFields(), en indien nodig fixen. - #187
Open
zyra-ginkelsoft[bot] wants to merge 1 commit into
Open
zyra-ginkelsoft[bot] wants to merge 1 commit into
zyra-ginkelsoft[bot] wants to merge 1 commit into
Conversation
BuildoraController::store()/update() beperkten kolom-mass-assignment al correct tot de velden uit Resource::defineFields(). handleRelationships() gebruikte echter ongefilterd $request->all(), waardoor elke public, parameterloze modelmethode die een Eloquent-relatie teruggeeft (bv. een niet-geëxposeerde "roles" BelongsToMany) alsnog gesynchroniseerd of geassocieerd kon worden door simpelweg een gelijknamig veld mee te sturen. Dat is mass assignment op relatieniveau, los van defineFields(). Fix: geef alleen $request->only($fields) door aan handleRelationships(), zodat relaties enkel aangepast kunnen worden als ze expliciet als veld in defineFields() staan. Regressietest voegt een niet-geëxposeerde BelongsToMany-relatie toe en bevestigt dat deze niet meer via de request gesynchroniseerd wordt, terwijl een wél gedefinieerde relatie blijft werken. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Goed, proef.sh bestaat al en past bij deze package-structuur (Testbench). Nu de controller bekijken.Confirmed:
$this->fieldsis derived fromdefineFields()in the constructor, andresolveFields()returns these prepared fields. So$fieldsarray in store()/update() only contains field names defined viadefineFields(). Nu kijken naar tests om te zien of dit al eerder getest is, en of er een gat is.Nu is duidelijk waar het echte gat zit. Laat me het bevestigen door de fixture/testopzet te bouwen en een falende PoC-test te schrijven vóór de fix.Nu bouw ik de test fixture en de regressietest.Nu schrijf ik de regressietest inclusief fixtures (model, resource) binnen één testbestand.Nu draai ik de nieuwe test tegen de huidige (ongewijzigde) code om de kwetsbaarheid te bevestigen.Model moet deHasBuildoratrait gebruiken. Ik voeg die toe.Ik voegHasBuildoratoe aan mijn testmodel.Kwetsbaarheid bevestigd: de "roles"-relatie (niet indefineFields()) wordt wél gesynchroniseerd viastore()/update(). Nu de fix toepassen in de controller.Nu de testsuite opnieuw draaien.Fix bevestigd. Nu de volledige testsuite, lint en typecheck draaien.Alle 39 tests slagen. Nu lint (phpcs) en typecheck (phpstan).Nu controleer ik dat phpstan geen nieuwe fouten in de controller introduceert (59 fouten waren al aanwezig vóór mijn wijziging — dus geen regressie). Laten we ook.zyra/proef.shkort testen.Poort was door de vorige (nog draaiende) achtergrondinstantie bezet; nu vrij. Nieuwe poging op een andere poort om zeker te zijn.proef.sh werkt (HTTP 200 op/buildora/install). Server stoppen en opruimen.Server gestopt, poort vrij. Nu committen.Laatste check: volledige testsuite nogmaals draaien om zeker te zijn dat alles nog groen is na de commit.Alles groen (39/39; de "deprecations" zijn bestaande PHPUnit-attribuutwaarschuwingen, niet gerelateerd aan mijn wijziging).Samenvatting (voor de PR)
Wat: Onderzocht of
BuildoraController::store()/update()kwetsbaar zijn voor mass assignment via velden buitendefineFields().Bevinding: Deels kwetsbaar.
::create()/->update()) was al veilig:$filteredDatawordt altijd teruggebracht totarray_intersect_key(..., array_flip($fields)), waarbij$fieldsafkomstig is uitresolveFields()→defineFields(). Een extra fillable kolom die niet indefineFields()staat, komt hier niet doorheen.handleRelationships()gaf echter ongefilterd$request->all()door. Elke publieke, parameterloze modelmethode die een Eloquent-relatie retourneert (bv. een niet indefineFields()opgenomenroles()BelongsToMany) kon zo gesynchroniseerd of geassocieerd worden door simpelweg een gelijknamig veld in de POST/PUT-body mee te sturen — ook al was die relatie nooit bedoeld als bewerkbaar veld op dat formulier. Bij eenBelongsTo-relatie zetassociate()bovendien de foreign key rechtstreeks (buiten$fillableom), wat het risico op privilege-escalatie (bv. rol- of tenant-toewijzing) reëel maakt.Fix:
store()enupdate()geven nu$request->only($fields)(dezelfde whitelist uitdefineFields(), ongeacht readonly) door aanhandleRelationships()in plaats van$request->all(). Relaties kunnen dus alleen nog aangepast worden als ze expliciet als veld indefineFields()staan.Getest:
tests/Feature/BuildoraControllerMassAssignmentTest.phpmet een op maat gemaakt model + relatie (rolesBelongsToMany) en twee resources: één dierolesniet definieert, één die dat wel doet.phpcs --standard=PSR12op het gewijzigde bestand: schoon.phpstan analyse level=5: 59 fouten, identiek aantal vóór en na mijn wijziging (allemaal pre-existing, elders in de codebase; geen nieuwe fouten inBuildoraController.php)..zyra/proef.shhandmatig gedraaid (Testbench-app op poort 8199): start correct,/buildora/installgeeft HTTP 200.Open/niet meegenomen:
InlineRelationController) die mogelijk hetzelfde patroon gebruiken — de mens kan overwegen of issue Security audit: mass assignment in store/update flow #120 daar ook geldt.