77import logging
88import argparse
99import yaml
10+ import html
1011import asyncio
1112from fastapi .responses import FileResponse , StreamingResponse
1213from fastapi .staticfiles import StaticFiles
@@ -638,11 +639,10 @@ def _get_stream_interface(self) -> str:
638639
639640 form_fields = self ._generate_form_fields ()
640641
641- return ( # nosec B608
642- f'''<!DOCTYPE html>
642+ return f'''<!DOCTYPE html>
643643 <html>
644644 <head>
645- <title>{ self .title } - Stream</title>
645+ <title>{ html . escape ( self .title ) } - Stream</title>
646646 <style>
647647 * {{
648648 margin: 0;
@@ -984,7 +984,7 @@ def _get_stream_interface(self) -> str:
984984 </head>
985985 <body>
986986 <div class="header">
987- <h1>{ self .form_config .title } </h1>
987+ <h1>{ html . escape ( self .form_config .title ) } </h1>
988988 </div>
989989
990990 <div class="main-container">
@@ -1170,7 +1170,7 @@ def _get_stream_interface(self) -> str:
11701170 }}
11711171
11721172 // Add user message to chat immediately for instant feedback
1173- const displayProperty = '{ self .display_property } ' || Object.keys(data)[0];
1173+ const displayProperty = '{ html . escape ( str ( self .display_property )) } ' || Object.keys(data)[0];
11741174 const userMessage = data[displayProperty] || JSON.stringify(data);
11751175 lastUserMessage = userMessage; // Store to detect duplicates from server
11761176 addMessage(userMessage, 'user', new Date().toISOString());
@@ -1228,8 +1228,7 @@ def _get_stream_interface(self) -> str:
12281228 </script>
12291229 </body>
12301230 </html>
1231- '''
1232- )
1231+ ''' # nosec B608
12331232
12341233 def _get_html_interface (self ) -> str :
12351234 """Generate HTML interface with configurable form"""
@@ -1272,11 +1271,11 @@ def _get_html_interface(self) -> str:
12721271
12731272 form_fields = self ._generate_form_fields ()
12741273
1275- return ( # nosec B608
1276- f'''<!DOCTYPE html>
1274+ # nosec B608 - HTML template with proper escaping, not SQL injection
1275+ return f'''<!DOCTYPE html>
12771276 <html>
12781277 <head>
1279- <title>{ self .title } </title>
1278+ <title>{ html . escape ( self .title ) } </title>
12801279 <style>
12811280 * {{
12821281 margin: 0;
@@ -1293,7 +1292,7 @@ def _get_html_interface(self) -> str:
12931292 }}
12941293
12951294 .main-content {{
1296- height: calc(100vh - { height } );
1295+ height: calc(100vh - { html . escape ( height ) } );
12971296 padding: 20px;
12981297 overflow-y: auto;
12991298 background-color: #f8f9fa;
@@ -1336,9 +1335,9 @@ def _get_html_interface(self) -> str:
13361335
13371336 .form-panel {{
13381337 position: fixed;
1339- { form_style }
1340- background-color: { input_bg } ;
1341- border: 1px solid { border_color } ;
1338+ { html . escape ( form_style ) }
1339+ background-color: { html . escape ( input_bg ) } ;
1340+ border: 1px solid { html . escape ( border_color ) } ;
13421341 padding: 20px;
13431342 box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
13441343 overflow-y: auto;
@@ -1355,7 +1354,7 @@ def _get_html_interface(self) -> str:
13551354 }}
13561355
13571356 .form-header h3 {{
1358- color: { text_color } ;
1357+ color: { html . escape ( text_color ) } ;
13591358 margin: 0;
13601359 }}
13611360
@@ -1485,9 +1484,9 @@ def _get_html_interface(self) -> str:
14851484 <body>
14861485 <div class="main-content">
14871486 <div class="info-section">
1488- <h1>{ self .title } </h1>
1487+ <h1>{ html . escape ( self .title ) } </h1>
14891488 <p>Submit JSON data using the form below or send POST requests to:</p>
1490- <div class="endpoint-info">POST http://{ self .host } :{ self .port } /process</div>
1489+ <div class="endpoint-info">POST http://{ html . escape ( self .host ) } :{ html . escape ( str ( self .port )) } /process</div>
14911490 { "<p>Authentication required: Include 'X-API-Key' header</p>" if self .require_auth else "" }
14921491 <p>View API documentation at: <a href="/docs">/docs</a></p>
14931492 <p>View streaming interface at: <a href="/stream">/stream</a></p>
@@ -1504,7 +1503,7 @@ def _get_html_interface(self) -> str:
15041503 <div class="form-panel" id="formPanel">
15051504 <div class="form-container">
15061505 <div class="form-header">
1507- <h3>{ self .form_config .title } </h3>
1506+ <h3>{ html . escape ( self .form_config .title ) } </h3>
15081507 </div>
15091508
15101509 { auth_header }
@@ -1644,9 +1643,8 @@ def _get_html_interface(self) -> str:
16441643 </script>
16451644 </body>
16461645 </html>
1647- '''
1648- )
1649-
1646+ ''' # nosec B608
1647+
16501648 def set_processor_function (self , func : Callable [[Dict [str , Any ]], Any ]):
16511649 """Set the function used to process incoming JSON data"""
16521650 self .processor_function = func
0 commit comments