How to view artifacts: Main server logic in express_server.js; helper functions in helpers.js; views in /views folder.
Result snapshot: Full-stack web application with authentication, authorization, password hashing, and session management.
Quick review:
- Security focus: bcrypt password hashing, cookie-based sessions, authorization controls, input validation
- Key files:
express_server.js(server + security controls),helpers.js(utilities) - Start with: Review authentication and authorization middleware implementation
TinyApp is a full-stack web application built with Node.js and Express that allows users to shorten long URLs (similar to bit.ly). The project demonstrates fundamental web application security concepts including authentication, authorization, password hashing, session management, and access control.
Developed during: Lighthouse Labs Web Development Bootcamp (March 2021)
Career Timeline: Early Learning → Web Development Foundations (2021)
Skills Demonstrated: Authentication architecture, password security, session management, authorization controls, secure coding practices
Related Projects:
- See LightBnB for database security (SQL injection prevention)
- See Interview Scheduler for React security patterns
- Builds on fundamentals from Lotide (testing & algorithms)
Why This Matters for Employers:
Web applications remain a primary attack vector, with authentication flaws consistently appearing in the OWASP Top 10. This project proves I understand authentication vulnerabilities from a developer's perspective, making me more effective at:
- Identifying authentication issues during security assessments
- Communicating security findings to engineering teams in their language
- Reviewing code for security anti-patterns
- Understanding how authentication bypasses actually work
As a security analyst with development experience, I can bridge the gap between security and engineering teams—speaking both languages fluently and understanding the constraints developers face.
This bootcamp project involved minimal AI assistance, limited to:
- Syntax Reference: Quick lookups for Express.js and EJS syntax
- Template Snippets: Basic HTML/EJS structure patterns
All core implementation is original work demonstrating hands-on learning.
- Core Architecture: Server structure, routing design, and middleware organization
- Security Implementation: bcrypt password hashing, session management, authorization logic (100% original)
- Authentication Flow: Login/registration logic, cookie handling, user validation
- Testing & Validation: All test cases and edge case handling
This project represents fundamental hands-on learning of web security concepts. The minimal LLM usage reflects the bootcamp learning environment where understanding core concepts through implementation was essential.
- bcrypt password hashing with salt rounds for secure credential storage
- Password comparison using timing-safe bcrypt.compare() to prevent timing attacks
- Secure password storage - plaintext passwords never stored in database
- Demonstrates understanding of cryptographic hashing vs. encryption
- Industry-standard password security implementation
- cookie-session middleware for server-side session handling
- Signed cookies with secret keys prevent tampering
- Session expiration with configurable maxAge (24 hours)
- httpOnly flags prevent XSS-based session theft (implicit in cookie-session)
- Proper session lifecycle management (creation, validation, destruction)
- User-specific resource access - users can only view/edit/delete their own URLs
- Authorization checks on every sensitive endpoint
- 401 Unauthorized responses for access violations
- Proper error messages that don't leak information about other users' data
- Demonstrates principle of least privilege and defense in depth
- URL validation prevents empty or malformed submissions
- Parameter validation for route parameters (short URL codes)
- Error status codes (400 Bad Request, 401 Unauthorized, 404 Not Found)
- Safe error messages that inform users without exposing system internals
- Redirect validation prevents open redirect vulnerabilities
- Random ID generation using cryptographically appropriate methods
- User enumeration protection - login errors don't reveal if email exists
- Dependency management with security-focused packages (bcrypt >=2.0.0)
- Separation of concerns - helpers module isolates security-critical functions
- Code organization facilitates security review and testing
- Implement secure user authentication from scratch
- Create authorization controls for resource access
- Build RESTful API with proper HTTP methods and status codes
- Demonstrate password hashing and session management
- Handle errors securely without information disclosure
- Express.js for routing and middleware architecture
- EJS templating for server-side rendering
- bcrypt for password hashing and verification
- cookie-session for encrypted session management
- Mocha & Chai for unit testing security-critical functions
- User Registration: Email-based account creation with hashed passwords
- User Login: Secure authentication with bcrypt password verification
- Session Management: Persistent sessions with secure cookies
- URL Shortening: Generate short codes for long URLs
- URL Management: Edit and delete owned URLs
- Access Control: Users can only manage their own URLs
- Error Handling: Appropriate status codes and user-friendly messages
- Backend: Node.js, Express.js 4.17
- Templating: EJS (Embedded JavaScript)
- Security: bcrypt >=2.0.0, cookie-session 1.4
- Utilities: body-parser, lodash 4.17.21 (security patched)
- Testing: Mocha, Chai
- Development: nodemon for hot reloading
- Password hashing is non-negotiable: Never store plaintext passwords; bcrypt's adaptive hashing provides future-proof security
- Session management requires layered security: Signed cookies, expiration, and proper validation all work together
- Authorization is separate from authentication: Being logged in doesn't mean access to all resources
- Error messages are a security feature: Balancing user experience with preventing information disclosure requires careful design
- Dependencies introduce risk: Regular updates and version pinning (e.g., lodash >=4.17.21) prevent known vulnerabilities
- Input validation is everywhere: Client-side, server-side, and database-level validation all serve different security purposes
Core Application:
express_server.js- Main server with authentication and authorization logichelpers.js- Utility functions including random ID generation and user lookuppackage.json- Dependencies with security-conscious versioning
Views (EJS Templates):
views/urls_index.ejs- User's URL dashboardviews/urls_show.ejs- Individual URL edit pageviews/urls_new.ejs- Create new short URL formviews/login.ejs- Login formviews/register.ejs- User registration formviews/partials/_header.ejs- Navigation with session state
Testing:
test/helpersTest.js- Unit tests for security-critical helper functions
- Node.js (v10.x or higher)
- npm (v6.x or higher)
-
Clone the repository
git clone https://github.com/VioletFigueroa/tinyapp.git cd tinyapp -
Install dependencies
npm install
-
Configure session secrets (Production)
- Edit
express_server.jsline 18 - Replace placeholder key with cryptographically random string:
keys: ["your-secret-key-here"]
- Edit
-
Start the server
npm start
The application will be available at
http://localhost:8080
npm testAs an avid twitter poster: I want to be able to shorten links so that I can fit more non-link text in my tweets.
As a twitter reader: I want to be able to visit sites via shortened links so that I can read interesting content.
Secure login interface with password hashing
URL management dashboard with authorization controls
- Navigate to
/register - Enter email and password
- Password is automatically hashed with bcrypt
- Navigate to
/login - Enter credentials
- Session cookie established on successful authentication
- Click "Create New URL"
- Paste long URL
- Receive short URL (format:
/u/:shortCode)
- View all:
/urlsshows your URL dashboard - Edit: Click edit on any URL you own
- Delete: Remove URLs from your collection
- Share: Short URLs work for anyone (public access)
Demo users (for testing only):
- Email:
user@example.com/ Password:purple-monkey-dinosaur - Email:
user2@example.com/ Password:dishwasher-funk
- Login as user1, create a URL (e.g.,
/u/b6UTxQ) - Note the short URL ID
- Logout and login as user2
- Try to access
/urls/b6UTxQ - Expected: 401 Unauthorized - demonstrates access control
- Login and note your session cookie
- Clear cookies (logout)
- Try to access
/urls/new - Expected: Redirect to login - demonstrates session validation
- Stored passwords in
usersobject are bcrypt hashes - Format:
$2b$10$...indicates bcrypt with 10 salt rounds - Never stored in plaintext
This project demonstrates several AppSec fundamentals:
- Authentication Security: Implementing industry-standard password hashing and session management
- Authorization Controls: Enforcing access controls and principle of least privilege
- Secure Coding: Following OWASP guidelines for session management and authentication
- Threat Awareness: Understanding common web vulnerabilities (session hijacking, password storage, open redirects)
- Security Testing: Writing tests to validate security assumptions
The skills developed here translate directly to application security work:
- Code Review: Identifying authentication/authorization flaws in codebases
- Security Testing: Testing login flows, session handling, and access controls
- Threat Modeling: Understanding attack vectors against web applications
- Security Requirements: Defining security controls for new features
- Developer Training: Teaching secure coding practices to development teams
Author: Violet Figueroa
Contact: GitHub Profile
Career Focus: Application Security | Secure Software Development | Web Application Security

