Created
March 21, 2026 16:46
-
-
Save daveh/cb43f7df2ce7381726a37d7c89b97269 to your computer and use it in GitHub Desktop.
OWASP Top 10 #1: Broken Access Control (source code to accompany https://youtu.be/mzrP73oKDpY)
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
| <?php | |
| use Psr\Http\Message\ResponseInterface as Response; | |
| use Psr\Http\Message\ServerRequestInterface as Request; | |
| use Slim\Factory\AppFactory; | |
| use Psr\Http\Server\RequestHandlerInterface as RequestHandler; | |
| require dirname(__DIR__) . '/vendor/autoload.php'; | |
| $app = AppFactory::create(); | |
| /** | |
| * Add middleware to include JSON response header in all responses | |
| */ | |
| $addHeadersMiddleware = function (Request $request, | |
| RequestHandler $handler): Response { | |
| $response = $handler->handle($request); | |
| return $response->withHeader('Content-Type', 'application/json'); | |
| }; | |
| $app->add($addHeadersMiddleware); | |
| /** | |
| * Endpoint for an individual order | |
| */ | |
| $app->get('/api/orders/{id}', function (Request $request, | |
| Response $response, | |
| array $args): Response | |
| { | |
| /** | |
| * Invalid request if no API key | |
| */ | |
| if ( ! $request->hasHeader('X-API-Key')) { | |
| return $response->withStatus(400); | |
| } | |
| $users = [ | |
| [ | |
| 'id' => 1, | |
| 'name' => 'Dave', | |
| 'apiKey' => 'secret', | |
| 'isAdmin' => false | |
| ], | |
| [ | |
| 'id' => 2, | |
| 'name' => 'Mary', | |
| 'apiKey' => 'Louvre', | |
| 'isAdmin' => true | |
| ] | |
| ]; | |
| /** | |
| * Authenticate user by API key | |
| */ | |
| $key = $request->getHeaderLine('X-API-Key'); | |
| $user = array_find($users, function ($value) use ($key) { | |
| return $value['apiKey'] === $key; | |
| }); | |
| if ($user === null) { | |
| return $response->withStatus(401); | |
| } | |
| /** | |
| * Get order by ID | |
| */ | |
| $orders = [ | |
| [ | |
| 'id' => '1001', | |
| 'date' => '2026-03-20', | |
| 'userId' => 1, | |
| 'total' => 6.99 | |
| ], | |
| [ | |
| 'id' => '1002', | |
| 'date' => '2026-03-25', | |
| 'userId' => 2, | |
| 'total' => 23.20 | |
| ], | |
| [ | |
| 'id' => '1003', | |
| 'date' => '2026-06-20', | |
| 'userId' => 1, | |
| 'total' => 9.00 | |
| ] | |
| ]; | |
| $id = $args['id']; | |
| $order = array_find($orders, function ($value) use ($id) { | |
| return $value['id'] === $id; | |
| }); | |
| if ($order === null) { | |
| return $response->withStatus(404); | |
| } | |
| /** | |
| * Prevent user from seeing other orders unless admin | |
| */ | |
| if ( ! $user['isAdmin']) { | |
| if ($order['userId'] !== $user['id']) { | |
| return $response->withStatus(404); | |
| } | |
| } | |
| $response->getBody()->write(json_encode($order)); | |
| return $response; | |
| }); | |
| $app->run(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment