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