The category of Broken Access Control includes cases where the attacker can act outside of their indented permissions.
Example (https://owasp.org/Top10/A01_2021-Broken_Access_Control/) :
- Violation of the principle of least privilege or deny by default, where access should only be granted for particular capabilities, roles, or users, but is available to anyone.
- Bypassing access control checks by modifying the URL (parameter tampering or force browsing), internal application state, or the HTML page, or by using an attack tool modifying API requests.
- Permitting viewing or editing someone else’s account, by providing its unique identifier (insecure direct object references).
- Elevation of privilege. Acting as a user without being logged in or acting as an admin when logged in as a user.
Object References : Path Traversal
https://myblog.org/index.php?entry=2025-03-17.html
The file index.php :
- Reads a plain HTML file (
2025-03-17.html) - Wraps it with navigation links, site styles
Question
What is the problem with such a design ?
https://myblog.org/index.php?entry=/etc/passwd
- Remote users can potentially visit any file on the system!
- Mistake motivates defence-in-depth:
- HTTP server should not serve just any file.
- use internal web server config (separate apps).
- and external OS config (e.g. nobody user, chroot).
- use of allow-lists (filter inputs against known, safe options)
- ⚠️A well-written app should only allow access to its own resources.
<form action="show-account.asp" method="get">
Account to display:
<select name="account">
<option value="1234.56.78901">1234.56.78901</option>
<option value="1234.65.43210">1234.65.43210</option>
</select>
<input type="submit" name="show" value="Show Account"/>
</form>Example from Innocent Code, based on a Norwegian newspaper story about a “17-year geek able to view anyone’s bank account”.
Question
What is the problem here ?
Object References : Solutions
- Re-validate
- Check authorisation again (e.g., does the user have access to that account)
- Obvious solution but duplicates effort
- Add a data indirection
- Session specific server side array of account numbers
- Use of databases/hash tables
<option value="1">1234.56.78901</option>
<option value="2">1234.65.43210</option>Object References : Too much information
- Passing potentially unnecessary information to the client
- And expecting it unmodified
<form action="/cgi-bin/cgimail.exe" method="post">
<input type="hidden" name="$File$"
value="\templates\feedback.txt">
<input type="hidden" name="$To$"
value="feedbacksomesite.example">
...
</form>Object References : Protecting information
- If you need to ensure information stays unmodified,
- add a MAC constructed with a server-side secret key.
<input type="hidden" name="pagemac"
value="bc9faaae1e35d52f3dea9651da12cd36627b8403"/>Functions
Hiding a link in the navigation for unauthorised users does not prevent them from visiting it!
Advices :
- Manage authorisation in a separate module
- have a single route through code
- can trace to make sure authorisation happens
- Make authorisation checks for each function
- Use deny-by-default policy