Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38e9dfd0e6 | ||
|
|
b6102bddbc | ||
|
|
e22b0c499e | ||
|
|
969dfaf943 | ||
|
|
fb7e973d8b | ||
|
|
944a690d96 | ||
|
|
e7facc3bba | ||
|
|
aa83b62064 | ||
|
|
f9ee39dfd0 | ||
|
|
087b95388f |
No files matched your search
@@ -1,5 +1,19 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## 1.2.16 (2026-03-29)
|
||||||
|
|
||||||
|
- Fix regression in v1.2.15 that broke the device search component in the UI by
|
||||||
|
pinning Mithril dependency to v2.2.2 due to multiple unresolved regressions in
|
||||||
|
later versions.
|
||||||
|
|
||||||
|
## 1.2.15 (2026-03-26)
|
||||||
|
|
||||||
|
- Fix critical RCE vulnerability in /api/ping endpoint (follow-up to
|
||||||
|
CVE-2021-46704). Credit: JuHwiSang.
|
||||||
|
|
||||||
|
- Fix device IDs containing special characters (e.g., %) not being handled
|
||||||
|
correctly in the UI due to a regression in Mithril 2.3.8.
|
||||||
|
|
||||||
## 1.2.14 (2026-03-12)
|
## 1.2.14 (2026-03-12)
|
||||||
|
|
||||||
- Prevent UI crash when a malformed URL is sent to the server.
|
- Prevent UI crash when a malformed URL is sent to the server.
|
||||||
|
|||||||
+16
-7
@@ -1,6 +1,6 @@
|
|||||||
import { platform } from "node:os";
|
import { platform } from "node:os";
|
||||||
import { exec } from "node:child_process";
|
import { execFile } from "node:child_process";
|
||||||
import { domainToASCII } from "node:url";
|
import { domainToASCII, domainToUnicode } from "node:url";
|
||||||
|
|
||||||
export interface PingResult {
|
export interface PingResult {
|
||||||
packetsTransmitted: number;
|
packetsTransmitted: number;
|
||||||
@@ -16,9 +16,16 @@ function isValidHost(host: string): boolean {
|
|||||||
// Valid chars in IPv4, IPv6, domain names
|
// Valid chars in IPv4, IPv6, domain names
|
||||||
if (/^[a-zA-Z0-9\-.:[\]-]+$/.test(host)) return true;
|
if (/^[a-zA-Z0-9\-.:[\]-]+$/.test(host)) return true;
|
||||||
|
|
||||||
|
const lowercase = host.toLowerCase();
|
||||||
|
const ascii = domainToASCII(lowercase);
|
||||||
|
|
||||||
// Check if input is an IDN convert to Punycode
|
// Check if input is an IDN convert to Punycode
|
||||||
// Can't merge with above because domainToASCII doesn't accept IP addresses
|
// Can't merge with above because domainToASCII doesn't accept IP addresses
|
||||||
return /^[a-zA-Z0-9\-.:[\]-]+$/.test(domainToASCII(host));
|
if (!/^[a-zA-Z0-9\-.:[\]-]+$/.test(ascii)) return false;
|
||||||
|
|
||||||
|
// Round-trip to ensure the original host matches its normalized form.
|
||||||
|
// This prevents bypasses where domainToASCII strips paths (e.g. "example.com/;cmd").
|
||||||
|
return lowercase === domainToUnicode(ascii);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parsePing(osPlatform: string, stdout: string): PingResult {
|
export function parsePing(osPlatform: string, stdout: string): PingResult {
|
||||||
@@ -73,24 +80,26 @@ export function ping(
|
|||||||
): void {
|
): void {
|
||||||
// Validate input to prevent possible remote code execution
|
// Validate input to prevent possible remote code execution
|
||||||
// Credit to Alex Hordijk for reporting this vulnerability
|
// Credit to Alex Hordijk for reporting this vulnerability
|
||||||
|
// Credit to JuHwiSang for reporting a follow-up vulnerability
|
||||||
if (!isValidHost(host)) return callback(new Error("Invalid host"));
|
if (!isValidHost(host)) return callback(new Error("Invalid host"));
|
||||||
host = host.replace("[", "").replace("]", "");
|
host = host.replace("[", "").replace("]", "");
|
||||||
let cmd: string;
|
let args: string[];
|
||||||
|
|
||||||
switch (platform()) {
|
switch (platform()) {
|
||||||
case "linux":
|
case "linux":
|
||||||
cmd = `ping -w 1 -i 0.2 -c 3 ${host}`;
|
args = ["-w", "1", "-i", "0.2", "-c", "3", "--", host];
|
||||||
break;
|
break;
|
||||||
case "freebsd":
|
case "freebsd":
|
||||||
// Send a single packet because on FreeBSD only superuser can send
|
// Send a single packet because on FreeBSD only superuser can send
|
||||||
// packets that are only 200 ms apart.
|
// packets that are only 200 ms apart.
|
||||||
cmd = `ping -t 1 -c 3 ${host}`;
|
args = ["-t", "1", "-c", "3", "--", host];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return callback(new Error("Platform not supported"));
|
return callback(new Error("Platform not supported"));
|
||||||
}
|
}
|
||||||
|
|
||||||
exec(cmd, (err, stdout) => {
|
// Use execFile instead of exec to avoid shell interpretation of the host
|
||||||
|
execFile("ping", args, (err, stdout) => {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
const parsed: PingResult = parsePing(platform(), stdout);
|
const parsed: PingResult = parsePing(platform(), stdout);
|
||||||
return callback(err, parsed, stdout);
|
return callback(err, parsed, stdout);
|
||||||
|
|||||||
Generated
+760
-728
File diff suppressed because it is too large.
Load diff
+5
-5
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "genieacs",
|
"name": "genieacs",
|
||||||
"version": "1.2.14",
|
"version": "1.2.16",
|
||||||
"description": "A TR-069 Auto Configuration Server (ACS)",
|
"description": "A TR-069 Auto Configuration Server (ACS)",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
"ipaddr.js": "^2.3.0",
|
"ipaddr.js": "^2.3.0",
|
||||||
"jsonwebtoken": "^9.0.3",
|
"jsonwebtoken": "^9.0.3",
|
||||||
"koa": "^2.16.4",
|
"koa": "^2.16.4",
|
||||||
"koa-compress": "^5.2.0",
|
"koa-compress": "^5.2.1",
|
||||||
"koa-jwt": "^4.0.3",
|
"koa-jwt": "^4.0.3",
|
||||||
"koa-send": "^5.0.1",
|
"koa-send": "^5.0.1",
|
||||||
"mongodb": "^4.16.0",
|
"mongodb": "^4.16.0",
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
"@types/jsonwebtoken": "^9.0.10",
|
"@types/jsonwebtoken": "^9.0.10",
|
||||||
"@types/koa": "^2.15.0",
|
"@types/koa": "^2.15.0",
|
||||||
"@types/koa-compress": "^4.0.7",
|
"@types/koa-compress": "^4.0.7",
|
||||||
"@types/mithril": "^2.2.7",
|
"@types/mithril": "^2.2.6",
|
||||||
"@types/node": "^20.19.37",
|
"@types/node": "^20.19.37",
|
||||||
"@types/parsimmon": "^1.10.9",
|
"@types/parsimmon": "^1.10.9",
|
||||||
"@types/seedrandom": "^3.0.8",
|
"@types/seedrandom": "^3.0.8",
|
||||||
@@ -56,12 +56,12 @@
|
|||||||
"esbuild": "^0.27.4",
|
"esbuild": "^0.27.4",
|
||||||
"eslint": "^8.57.1",
|
"eslint": "^8.57.1",
|
||||||
"eslint-config-prettier": "^9.1.2",
|
"eslint-config-prettier": "^9.1.2",
|
||||||
"mithril": "^2.3.8",
|
"mithril": "2.2.2",
|
||||||
"prettier": "^3.8.1",
|
"prettier": "^3.8.1",
|
||||||
"sql.js": "^1.14.1",
|
"sql.js": "^1.14.1",
|
||||||
"svgo": "^3.3.3",
|
"svgo": "^3.3.3",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"yaml": "^1.10.2"
|
"yaml": "^1.10.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12.13.0"
|
"node": ">=12.13.0"
|
||||||
|
|||||||
Reference in new issue
Block a user