1+ import ChallengesPage from '../pages/challengesPage'
2+
3+ describe ( 'Challenge 58 Database Connection String Exposure Tests' , ( ) => {
4+ // Challenge 58 specific selectors
5+ const DATABASE_CONTAINER = '#database-challenge-container'
6+ const ERROR_DEMO_LINK = 'a[href="/error-demo/database-connection"]'
7+
8+ beforeEach ( ( ) => {
9+ // Visit Challenge 58 page
10+ cy . visit ( '/challenge/challenge-58' )
11+
12+ // Verify the page loads correctly
13+ cy . dataCy ( ChallengesPage . CHALLENGE_TITLE ) . should ( 'contain' , 'Challenge 58' )
14+
15+ // Wait for database challenge container to be ready
16+ cy . get ( DATABASE_CONTAINER , { timeout : 10000 } ) . should ( 'be.visible' )
17+ } )
18+
19+ it ( 'Challenge interface displays correctly' , ( ) => {
20+ // Verify database container is present with correct structure
21+ cy . get ( DATABASE_CONTAINER ) . should ( 'be.visible' )
22+ cy . get ( DATABASE_CONTAINER ) . should ( 'contain' , 'Database Connection Error Demo' )
23+
24+ // Verify error demo link is present and functional
25+ cy . get ( ERROR_DEMO_LINK ) . should ( 'be.visible' ) . and ( 'not.be.disabled' )
26+ cy . get ( ERROR_DEMO_LINK ) . should ( 'contain' , 'Trigger Database Connection Error' )
27+
28+ // Verify instructional content
29+ cy . get ( DATABASE_CONTAINER ) . should ( 'contain' , 'This challenge demonstrates how database connection failures' )
30+ cy . get ( DATABASE_CONTAINER ) . should ( 'contain' , 'Look for the database password' )
31+ } )
32+
33+ it ( 'Error demo endpoint is accessible and returns error with exposed credentials' , ( ) => {
34+ // Click the error demo link
35+ cy . get ( ERROR_DEMO_LINK ) . click ( )
36+
37+ // Verify we're redirected to the error demo endpoint
38+ cy . url ( ) . should ( 'include' , '/error-demo/database-connection' )
39+
40+ // Wait for page to load and check for error content
41+ cy . get ( 'body' , { timeout : 10000 } ) . should ( 'be.visible' )
42+
43+ // The error page should contain database connection information
44+ cy . get ( 'body' ) . should ( ( $body ) => {
45+ const text = $body . text ( )
46+ // Look for typical database connection error patterns that might expose credentials
47+ const hasErrorIndicators = text . includes ( 'SuperSecretDB2024!' ) ||
48+ text . includes ( 'connection' ) ||
49+ text . includes ( 'database' ) ||
50+ text . includes ( 'error' ) ||
51+ text . includes ( 'failed' ) ||
52+ text . includes ( 'postgresql' ) ||
53+ text . includes ( 'jdbc' )
54+ expect ( hasErrorIndicators , 'Expected database error page with connection information' ) . to . be . true
55+ } )
56+ } )
57+
58+ it ( 'Database error exposes the target secret' , ( ) => {
59+ // Access the error demo endpoint
60+ cy . visit ( '/error-demo/database-connection' )
61+
62+ // Look for the specific secret in the page content
63+ cy . get ( 'body' , { timeout : 10000 } ) . should ( 'contain' , 'SuperSecretDB2024!' )
64+ } )
65+
66+ it ( 'Can solve the challenge using the exposed database password' , ( ) => {
67+ // First, trigger the database error to find the secret
68+ cy . get ( ERROR_DEMO_LINK ) . click ( )
69+
70+ // Wait for error page and extract the secret
71+ cy . get ( 'body' , { timeout : 10000 } ) . should ( 'contain' , 'SuperSecretDB2024!' )
72+
73+ // Navigate back to the challenge page
74+ cy . visit ( '/challenge/challenge-58' )
75+
76+ // Use the secret to solve the challenge
77+ cy . dataCy ( ChallengesPage . ANSWER_TEXTBOX ) . type ( 'SuperSecretDB2024!' )
78+ cy . dataCy ( ChallengesPage . SUBMIT_TEXTBOX_BTN ) . click ( )
79+
80+ // Verify success
81+ cy . dataCy ( ChallengesPage . SUCCESS_ALERT ) . should ( 'contain' , 'Your answer is correct!' )
82+ } )
83+
84+ it ( 'Challenge follows WrongSecrets standard structure' , ( ) => {
85+ // Verify standard WrongSecrets challenge elements
86+ cy . dataCy ( ChallengesPage . CHALLENGE_TITLE ) . should ( 'be.visible' )
87+ cy . dataCy ( ChallengesPage . ANSWER_TEXTBOX ) . should ( 'be.visible' )
88+ cy . dataCy ( ChallengesPage . SUBMIT_TEXTBOX_BTN ) . should ( 'be.visible' )
89+
90+ // Verify Challenge 58 specific database container
91+ cy . get ( DATABASE_CONTAINER ) . should ( 'be.visible' )
92+ cy . get ( DATABASE_CONTAINER ) . should ( 'contain' , 'Database Connection Error Demo' )
93+ cy . get ( DATABASE_CONTAINER ) . should ( 'contain' , 'database connection failures' )
94+
95+ // Verify error demo link is present
96+ cy . get ( ERROR_DEMO_LINK ) . should ( 'be.visible' )
97+ } )
98+
99+ it ( 'Validates the educational objective of database credential exposure' , ( ) => {
100+ // This test emphasizes the learning goal following WrongSecrets educational patterns
101+ cy . log ( 'Challenge 58 demonstrates database connection string credential exposure through error handling' )
102+
103+ // Verify the error endpoint exposes credentials (educational success criteria)
104+ cy . visit ( '/error-demo/database-connection' )
105+ cy . get ( 'body' , { timeout : 10000 } ) . should ( 'contain' , 'SuperSecretDB2024!' )
106+
107+ // This demonstrates how poor error handling can expose database credentials
108+ cy . log ( 'Successfully demonstrated database credential exposure - users learn how error handling can leak sensitive connection information' )
109+
110+ // Verify this allows solving the challenge
111+ cy . visit ( '/challenge/challenge-58' )
112+ cy . dataCy ( ChallengesPage . ANSWER_TEXTBOX ) . type ( 'SuperSecretDB2024!' )
113+ cy . dataCy ( ChallengesPage . SUBMIT_TEXTBOX_BTN ) . click ( )
114+ cy . dataCy ( ChallengesPage . SUCCESS_ALERT ) . should ( 'contain' , 'Your answer is correct!' )
115+ } )
116+
117+ it ( 'Demonstrates realistic database error scenario for learning' , ( ) => {
118+ // Educational test showing how database errors expose credentials in real applications
119+ cy . log ( 'Testing realistic database connection failure scenario' )
120+
121+ // Access the error endpoint
122+ cy . visit ( '/error-demo/database-connection' )
123+
124+ // Verify error content contains realistic database connection information
125+ cy . get ( 'body' ) . should ( ( $body ) => {
126+ const text = $body . text ( )
127+ // Look for realistic database connection error patterns
128+ const hasRealisticError = text . includes ( 'connection' ) ||
129+ text . includes ( 'database' ) ||
130+ text . includes ( 'failed' ) ||
131+ text . includes ( 'timeout' ) ||
132+ text . includes ( 'refused' ) ||
133+ text . includes ( 'unable' )
134+ expect ( hasRealisticError , 'Expected realistic database connection error message' ) . to . be . true
135+ } )
136+
137+ // Most importantly, verify the credentials are exposed
138+ cy . get ( 'body' ) . should ( 'contain' , 'SuperSecretDB2024!' )
139+
140+ cy . log ( 'Educational objective achieved: Database credentials exposed through error handling demonstrate real-world vulnerability' )
141+ } )
142+
143+ it ( 'Error endpoint demonstrates common logging/error disclosure patterns' , ( ) => {
144+ // Test that the error endpoint demonstrates realistic error disclosure
145+ cy . visit ( '/error-demo/database-connection' )
146+
147+ // Check for common error patterns that expose secrets
148+ cy . get ( 'body' ) . should ( ( $body ) => {
149+ const content = $body . text ( )
150+ // Look for patterns typical in database connection errors
151+ const hasConnectionString = content . includes ( 'jdbc:' ) ||
152+ content . includes ( 'postgresql://' ) ||
153+ content . includes ( 'connection string' ) ||
154+ content . includes ( 'SuperSecretDB2024!' )
155+ expect ( hasConnectionString , 'Expected database connection string or credential exposure' ) . to . be . true
156+ } )
157+ } )
158+
159+ it ( 'Challenge page provides proper educational guidance' , ( ) => {
160+ // Verify the challenge provides educational context
161+ cy . get ( DATABASE_CONTAINER ) . should ( 'contain' , 'database connection failures can expose sensitive credentials' )
162+ cy . get ( DATABASE_CONTAINER ) . should ( 'contain' , 'Look for the database password' )
163+
164+ // Verify the demo section explains the vulnerability
165+ cy . get ( DATABASE_CONTAINER ) . should ( 'contain' , 'Click the button below to trigger a database connection error' )
166+ cy . get ( DATABASE_CONTAINER ) . should ( 'contain' , 'exposes the connection string with embedded credentials' )
167+ } )
168+ } )
0 commit comments