If the GitHub Actions temporary token does not have workflow-defined permissions scope, it defaults either to a permissive or restricted default scope based on the repository's setting. This setting can also be configured at the organization level to restrict all repos owned by the org.
Historically the only choice was permissive by default, so this is unfortunately the setting used by older organizations and repos.
When a new repo is created, the default is inherited from the parent organization, so this insecure default tends to stick around if nobody bothers to change it. (There is no user-wide setting, so new repos owned by a user will use the restricted default. I believe newly created orgs use the better default.)
[0]: https://docs.github.com/en/actions/security-for-github-actio...