This article will cover the security risks of using localhost for the callback in development and production environments with apps running on the local machine or apps that are not public.
The main reason it is recommended not to have
localhost in the Allowed Callback URLs is due to the User consent implementation.
localhost is not a verifiable first-party because any malicious application may run on localhost for a user. That’s why the consent dialogue is always displayed for applications running on localhost or even if the
localhost is configured in the Allowed Callback URLs. This is documented here.
An attacker can hijack a local host via /etc/hosts (or the equivalent) or by killing a listening process and putting their own there. That makes it insecure. Consider a callback URL: https://localhost:1234/callback?code=blah. An app is running on localhost at port 1234.
An attacker changes the /etc/hosts and does ‘localhost 22.214.171.124’. This will then redirect the code not to 127.0.0.1 but to 1234.
The attacker finds the app, kills it, and runs their own listening on 127.0.0.1 port 1234.
In addition, auth code flow requires a secure backend, and localhost cannot be considered a secure backend (it is actually the same as the frontend).