Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow control characters in http basic auth username or password #160

Merged
merged 1 commit into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,11 @@

<div class="input_option">
<div class="label">{lang.option_httpAuthPassword} <a href="#" class="help_icon" aria-label="{lang.help}" onclick="helpInfo(event, 'httpAuthPassword', 'option')"><i class="material-icons" aria-hidden="true">help_outline</i></a></div>
<input type="text" id="httpAuthPassword" placeholder="" aria-label="{lang.option_httpAuthPassword}">
<input type="text" id="httpAuthPassword" placeholder="" oninput="httpAuthPasswordChange();reevaluateSectionHeights();" aria-label="{lang.option_httpAuthPassword}">
</div>

<div class="input_error">{lang.httpAuthPassword_invalid}</div>

<div class="input_option">
<div class="label">{lang.option_ipThrottling} <a href="#" class="help_icon" aria-label="{lang.help}" onclick="helpInfo(event, 'ipThrottling', 'option')"><i class="material-icons" aria-hidden="true">help_outline</i></a></div>
<input type="number" id="ipThrottling" placeholder="10" step="1" oninput="ipLimitChange();reevaluateSectionHeights()" style="width: 100px;" aria-label="{lang.option_ipThrottling}">
Expand Down
8 changes: 6 additions & 2 deletions lang.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ lang = {
"option_httpAuth": "Enable HTTP Basic authentication",
"option_httpAuth_description": "Require authentication using the HTTP Basic authentication protocol. Specify a username and password in the HTTP Basic auth username and HTTP Basic auth password options. If either the username or password option is missing or invalid, the web server will become inaccessible.",
"option_httpAuthUsername": "HTTP Basic auth username",
"option_httpAuthUsername_description": "Username for HTTP Basic authentication. Cannot contain a colon (<code>:</code>) character.",
"httpAuthUsername_invalid": "Username cannot contain <code>:</code>",
"option_httpAuthUsername_description": "Username for HTTP Basic authentication. Cannot contain a colon (<code>:</code>) character or control characters.",
"httpAuthUsername_invalid": "Username cannot contain <code>:</code> or control characters",
"httpAuthPassword_invalid": "Password cannot contain control characters",
"option_httpAuthPassword": "HTTP Basic auth password",
"option_httpAuthPassword_description": "Password for HTTP Basic authentication. Stored in plain text.",
"option_ipThrottling": "Maximum connections per IP address",
Expand Down Expand Up @@ -257,6 +258,7 @@ lang = {
"option_httpAuthUsername": "Имя пользователя HTTP Basic авторизации",
"option_httpAuthUsername_description": "Имя пользователя для HTTP Basic авторизации. Не может содержать двоеточия (<code>:</code>).",
"httpAuthUsername_invalid": "Имя пользователя не может содержать <code>:</code>",
"httpAuthPassword_invalid": "Password cannot contain control characters",
"option_httpAuthPassword": "Пароль HTTP Basic авторизации",
"option_httpAuthPassword_description": "Пароль для HTTP Basic авторизации. Хранится в чистом виде.",
"option_ipThrottling": "Предел соединений по IP адресу",
Expand Down Expand Up @@ -394,6 +396,7 @@ lang = {
"option_httpAuthUsername": "HTTP基本身份验证用户名",
"option_httpAuthUsername_description": "HTTP基本身份验证的用户名。不能包含冒号(<code>:</code>)字符。",
"httpAuthUsername_invalid": "用户名不能包含 <code>:</code>",
"httpAuthPassword_invalid": "Password cannot contain control characters",
"option_httpAuthPassword": "HTTP基本身份验证密码",
"option_httpAuthPassword_description": "HTTP基本身份验证的密码。以纯文本形式存储。",
"option_ipThrottling": "每个IP地址的最大连接数",
Expand Down Expand Up @@ -531,6 +534,7 @@ lang = {
"option_httpAuthUsername": "ベーシック認証ユーザー名",
"option_httpAuthUsername_description": "ベーシック認証のユーザー名。<code>:</code>を含んでいてはいけません。",
"httpAuthUsername_invalid": "ユーザー名に<code>:</code>を含めることはできません。",
"httpAuthPassword_invalid": "Password cannot contain control characters",
"option_httpAuthPassword": "ベーシック認証パスワード",
"option_httpAuthPassword_description": "ベーシック認証のパスワード。平文で保存されます。",
"option_ipThrottling": "IPアドレスごとの最大接続数",
Expand Down
32 changes: 31 additions & 1 deletion main.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ function addServer(editindex) {
document.querySelector("#httpAuthUsername").value = config.servers[editindex].httpAuthUsername || "";
httpAuthUsernameChange();
document.querySelector("#httpAuthPassword").value = config.servers[editindex].httpAuthPassword || "";
httpAuthPasswordChange();
document.querySelector("#ipThrottling").value = config.servers[editindex].ipThrottling || 10;
ipLimitChange();

Expand Down Expand Up @@ -457,6 +458,7 @@ function addServer(editindex) {
document.querySelector("#httpAuthUsername").value = "";
httpAuthUsernameChange();
document.querySelector("#httpAuthPassword").value = "";
httpAuthPasswordChange();
document.querySelector("#ipThrottling").value = 10;
ipLimitChange();

Expand Down Expand Up @@ -505,6 +507,17 @@ function submitAddServer() {
return;
}

if (!httpAuthPasswordValid()) {
document.querySelector("#httpAuthPassword").parentElement.nextElementSibling.style.display = "block";
if (!document.querySelector("#security_section").classList.contains("section_visible")) {
toggleSection(document.querySelector("#security_section"))
setTimeout(()=>document.querySelector("#httpAuthPassword").previousElementSibling.scrollIntoView({behavior: "smooth"}), 210);
} else {
document.querySelector("#httpAuthPassword").previousElementSibling.scrollIntoView({behavior: "smooth"});
}
return;
}

if (!ipLimitValid()) {
document.querySelector("#ipThrottling").parentElement.nextElementSibling.style.display = "block";
if (!document.querySelector("#security_section").classList.contains("section_visible")) {
Expand Down Expand Up @@ -704,8 +717,13 @@ function ipLimitChange() {
}
}

function stringContainsControlCharacters(str) {
const controlCharacterPattern = /[\x00-\x1F\x7F]/;
return controlCharacterPattern.test(str);
}

function httpAuthUsernameValid() {
return document.querySelector("#httpAuthUsername").value.indexOf(":") === -1;
return document.querySelector("#httpAuthUsername").value.indexOf(":") === -1 && !stringContainsControlCharacters(document.querySelector("#httpAuthUsername").value);
}

function httpAuthUsernameChange() {
Expand All @@ -716,6 +734,18 @@ function httpAuthUsernameChange() {
}
}

function httpAuthPasswordValid() {
return !stringContainsControlCharacters(document.querySelector("#httpAuthPassword").value);
}

function httpAuthPasswordChange() {
if (httpAuthPasswordValid()) {
document.querySelector("#httpAuthPassword").parentElement.nextElementSibling.style.display = "none";
} else {
document.querySelector("#httpAuthPassword").parentElement.nextElementSibling.style.display = "block";
}
}

function updateCurrentPath() {
if (current_path) {
document.querySelector("#path > div > span").innerText = current_path;
Expand Down
4 changes: 2 additions & 2 deletions website/src/docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,15 +261,15 @@ Require authentication using the HTTP Basic authentication protocol. Specify a u
- Type: string
- Default: -

Username for HTTP Basic authentication. Cannot contain a colon (`:`) character.
Username for HTTP Basic authentication. Cannot contain a colon (`:`) character or control characters.

### HTTP Basic auth password

- Name: `httpAuthPassword`
- Type: string
- Default: -

Password for HTTP Basic authentication. Stored in plain text.
Password for HTTP Basic authentication. Stored in plain text. Cannot contain control characters.

### Maximum connections per IP address

Expand Down