mirror of
				https://github.com/karl0ss/homepage.git
				synced 2025-10-31 14:34:00 +00:00 
			
		
		
		
	[BREAKING] Enhancement: require host validation (#4744)
This commit is contained in:
		
							parent
							
								
									91d5fc8e42
								
							
						
					
					
						commit
						05af70d11b
					
				| @ -15,6 +15,8 @@ services: | ||||
|     volumes: | ||||
|       - /path/to/config:/app/config # Make sure your local config directory exists | ||||
|       - /var/run/docker.sock:/var/run/docker.sock # (optional) For docker integrations | ||||
|     environment: | ||||
|       HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev # required when deploying via public URL | ||||
| ``` | ||||
| 
 | ||||
| ### Running as non-root | ||||
| @ -36,6 +38,7 @@ services: | ||||
|       - /path/to/config:/app/config # Make sure your local config directory exists | ||||
|       - /var/run/docker.sock:/var/run/docker.sock # (optional) For docker integrations, see alternative methods | ||||
|     environment: | ||||
|       HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev # required when deploying via public URL | ||||
|       PUID: $PUID | ||||
|       PGID: $PGID | ||||
| ``` | ||||
| @ -43,7 +46,7 @@ services: | ||||
| ### With Docker Run | ||||
| 
 | ||||
| ```bash | ||||
| docker run -p 3000:3000 -v /path/to/config:/app/config -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/gethomepage/homepage:latest | ||||
| docker run -p 3000:3000 -e HOMEPAGE_ALLOWED_HOSTS=gethomepage.dev -v /path/to/config:/app/config -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/gethomepage/homepage:latest | ||||
| ``` | ||||
| 
 | ||||
| ### Using Environment Secrets | ||||
|  | ||||
| @ -21,7 +21,7 @@ If this is your first time starting, copy the `src/skeleton` directory to `confi | ||||
| Finally, run the server: | ||||
| 
 | ||||
| ```bash | ||||
| pnpm start | ||||
| HOMEPAGE_ALLOWED_HOSTS=gethomepage.dev pnpm start | ||||
| ``` | ||||
| 
 | ||||
| When updating homepage versions you will need to re-build the static files i.e. repeat the process above. | ||||
|  | ||||
							
								
								
									
										23
									
								
								src/middleware.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/middleware.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| import { NextResponse } from "next/server"; | ||||
| 
 | ||||
| export function middleware(req) { | ||||
|   // Check the Host header, if HOMEPAGE_ALLOWED_HOSTS is set
 | ||||
|   const host = req.headers.get("host"); | ||||
|   const port = process.env.PORT || 3000; | ||||
|   let allowedHosts = [`localhost:${port}`]; | ||||
|   if (process.env.HOMEPAGE_ALLOWED_HOSTS) { | ||||
|     allowedHosts = allowedHosts.concat(process.env.HOMEPAGE_ALLOWED_HOSTS.split(",")); | ||||
|   } | ||||
|   if (!host || !allowedHosts.includes(host)) { | ||||
|     // eslint-disable-next-line no-console
 | ||||
|     console.error( | ||||
|       `Host validation failed for: ${host}. Hint: Set HOMEPAGE_ALLOWED_HOSTS to allow requests from this host.`, | ||||
|     ); | ||||
|     return NextResponse.json({ error: "Host validation failed. See logs for more details." }, { status: 400 }); | ||||
|   } | ||||
|   return NextResponse.next(); | ||||
| } | ||||
| 
 | ||||
| export const config = { | ||||
|   matcher: "/api/:path*", | ||||
| }; | ||||
| @ -86,6 +86,7 @@ function Index({ initialSettings, fallback }) { | ||||
|   const windowFocused = useWindowFocus(); | ||||
|   const [stale, setStale] = useState(false); | ||||
|   const { data: errorsData } = useSWR("/api/validate"); | ||||
|   const { error: validateError } = errorsData || {}; | ||||
|   const { data: hashData, mutate: mutateHash } = useSWR("/api/hash"); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
| @ -117,6 +118,24 @@ function Index({ initialSettings, fallback }) { | ||||
|     } | ||||
|   }, [hashData]); | ||||
| 
 | ||||
|   if (validateError) { | ||||
|     return ( | ||||
|       <div className="w-full h-screen container m-auto justify-center p-10 pointer-events-none"> | ||||
|         <div className="flex flex-col"> | ||||
|           <div className="basis-1/2 bg-theme-500 dark:bg-theme-600 text-theme-600 dark:text-theme-300 m-2 rounded-md font-mono shadow-md border-4 border-transparent"> | ||||
|             <div className="bg-rose-200 text-rose-800 dark:text-rose-200 dark:bg-rose-800 p-2 rounded-md font-bold"> | ||||
|               <BiError className="float-right w-6 h-6" /> | ||||
|               Error | ||||
|             </div> | ||||
|             <div className="p-2 text-theme-100 dark:text-theme-200"> | ||||
|               <pre className="opacity-50 font-bold pb-2">{validateError}</pre> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   if (stale) { | ||||
|     return ( | ||||
|       <div className="flex items-center justify-center h-screen"> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 shamoon
						shamoon