File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -39,12 +39,14 @@ export class FileHandler {
3939
4040 }
4141
42- private getFileInfoFromUrl_ ( urlPath : string ) {
43- const splittedValue = urlPath . split ( "/" ) ;
42+ private getFileInfoFromUrl_ ( url : string ) {
43+ // normalize early
44+ const normalizedPath = path . posix . normalize ( url ) ; // use posix to handle forward
45+ const splittedValue = normalizedPath . split ( "/" ) ;
4446 const fileInfo = {
4547 file : ""
4648 } as IFileInfo ;
47- if ( splittedValue . length > 2 || ! isNullOrEmpty ( path . parse ( urlPath ) . ext ) ) {
49+ if ( splittedValue . length > 2 || ! isNullOrEmpty ( path . parse ( normalizedPath ) . ext ) ) {
4850 fileInfo . folder = splittedValue [ 1 ] ;
4951 fileInfo . file = splittedValue . splice ( 2 ) . join ( "/" ) ;
5052 return fileInfo ;
@@ -71,7 +73,14 @@ export class FileHandler {
7173 const getAbsPath = ( ) => {
7274 const folder = this . option . global [ 'folders_' ] . find ( qry => qry . alias === fileInfo . folder ) ;
7375 if ( folder != null ) {
74- return path . join ( folder . path , fileInfo . file ) ;
76+ const absPath = path . join ( folder . path , fileInfo . file ) ;
77+ const normalized = path . normalize ( absPath ) ;
78+
79+ // Security check: ensure path is inside allowed folder
80+ if ( ! normalized . startsWith ( folder . path ) ) {
81+ return null ; // prevent path traversal
82+ }
83+ return normalized ;
7584 }
7685 return null ;
7786 } ;
Original file line number Diff line number Diff line change @@ -53,6 +53,30 @@ describe("/static", () => {
5353 } ) ;
5454 } )
5555
56+ it ( "should prevent path traversal attack" , ( done ) => {
57+ request
58+ . get ( "/static/../../package.json" )
59+ . accept ( browserAccept )
60+ . end ( ( err , res ) => {
61+ expect ( err ) . to . be . null ;
62+ expect ( res ) . to . have . status ( 404 ) ; // should not expose package.json
63+ expect ( res . text ) . to . not . include ( "name" ) ; // package.json contents
64+ done ( ) ;
65+ } ) ;
66+ } ) ;
67+
68+ it ( "should prevent path traversal attack" , ( done ) => {
69+ request
70+ . get ( "/static/../package.json" )
71+ . accept ( browserAccept )
72+ . end ( ( err , res ) => {
73+ expect ( err ) . to . be . null ;
74+ expect ( res ) . to . have . status ( 404 ) ; // should not expose package.json
75+ expect ( res . text ) . to . not . include ( "name" ) ; // package.json contents
76+ done ( ) ;
77+ } ) ;
78+ } ) ;
79+
5680 let etagVal ;
5781
5882 it ( 'big file test' , async ( ) => {
You can’t perform that action at this time.
0 commit comments