mirror of
https://github.com/openappsec/openappsec.git
synced 2025-11-16 17:31:52 +03:00
Compare commits
30 Commits
Mar_17_202
...
1.1.25
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d703f16e35 | ||
|
|
692c430e8a | ||
|
|
72c5594b10 | ||
|
|
2c6b6baa3b | ||
|
|
37d0f1c45f | ||
|
|
52c93ad574 | ||
|
|
bd3a53041e | ||
|
|
44f40fbd1b | ||
|
|
0691f9b9cd | ||
|
|
0891dcd251 | ||
|
|
7669f0c89c | ||
|
|
39d7884bed | ||
|
|
b8783c3065 | ||
|
|
37dc9f14b4 | ||
|
|
9a1f1b5966 | ||
|
|
b0bfd3077c | ||
|
|
0469f5aa1f | ||
|
|
3578797214 | ||
|
|
16a72fdf3e | ||
|
|
87d257f268 | ||
|
|
36d8006c26 | ||
|
|
8d47795d4d | ||
|
|
f3656712b0 | ||
|
|
b1781234fd | ||
|
|
f71dca2bfa | ||
|
|
bd333818ad | ||
|
|
95e776d7a4 | ||
|
|
919921f6d3 | ||
|
|
e9098e2845 | ||
|
|
97d042589b |
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
name: "Bug Report"
|
||||||
|
about: "Report a bug with open-appsec"
|
||||||
|
labels: [bug]
|
||||||
|
---
|
||||||
|
|
||||||
|
**Checklist**
|
||||||
|
- Have you checked the open-appsec troubleshooting guides - https://docs.openappsec.io/troubleshooting/troubleshooting
|
||||||
|
- Yes / No
|
||||||
|
- Have you checked the existing issues and discussions in github for the same issue
|
||||||
|
- Yes / No
|
||||||
|
- Have you checked the knwon limitations same issue - https://docs.openappsec.io/release-notes#limitations
|
||||||
|
- Yes / No
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Run '...'
|
||||||
|
3. See error '...'
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots or Logs**
|
||||||
|
If applicable, add screenshots or logs to help explain the issue.
|
||||||
|
|
||||||
|
**Environment (please complete the following information):**
|
||||||
|
- open-appsec version:
|
||||||
|
- Deployment type (Docker, Kubernetes, etc.):
|
||||||
|
- OS:
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: "Documentation & Troubleshooting"
|
||||||
|
url: "https://docs.openappsec.io/"
|
||||||
|
about: "Check the documentation before submitting an issue."
|
||||||
|
- name: "Feature Requests & Discussions"
|
||||||
|
url: "https://github.com/openappsec/openappsec/discussions"
|
||||||
|
about: "Please open a discussion for feature requests."
|
||||||
17
.github/ISSUE_TEMPLATE/nginx_version_support.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/nginx_version_support.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
name: "Nginx Version Support Request"
|
||||||
|
about: "Request for a specific Nginx version to be supported"
|
||||||
|
---
|
||||||
|
|
||||||
|
**Nginx & OS Version:**
|
||||||
|
Which Nginx and OS version are you using?
|
||||||
|
|
||||||
|
**Output of nginx -V**
|
||||||
|
Share the output of nginx -v
|
||||||
|
|
||||||
|
**Expected Behavior:**
|
||||||
|
What do you expect to happen with this version?
|
||||||
|
|
||||||
|
**Checklist**
|
||||||
|
- Have you considered a docker based deployment - find more information here https://docs.openappsec.io/getting-started/start-with-docker?
|
||||||
|
- Yes / No
|
||||||
@@ -177,7 +177,7 @@ open-appsec code was audited by an independent third party in September-October
|
|||||||
See the [full report](https://github.com/openappsec/openappsec/blob/main/LEXFO-CHP20221014-Report-Code_audit-OPEN-APPSEC-v1.2.pdf).
|
See the [full report](https://github.com/openappsec/openappsec/blob/main/LEXFO-CHP20221014-Report-Code_audit-OPEN-APPSEC-v1.2.pdf).
|
||||||
|
|
||||||
### Reporting security vulnerabilities
|
### Reporting security vulnerabilities
|
||||||
If you've found a vulnerability or a potential vulnerability in open-appsec please let us know at securityalert@openappsec.io. We'll send a confirmation email to acknowledge your report within 24 hours, and we'll send an additional email when we've identified the issue positively or negatively.
|
If you've found a vulnerability or a potential vulnerability in open-appsec please let us know at security-alert@openappsec.io. We'll send a confirmation email to acknowledge your report within 24 hours, and we'll send an additional email when we've identified the issue positively or negatively.
|
||||||
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
install(FILES Dockerfile entry.sh install-cp-agent-intelligence-service.sh install-cp-crowdsec-aux.sh DESTINATION .)
|
install(FILES Dockerfile entry.sh install-cp-agent-intelligence-service.sh install-cp-crowdsec-aux.sh self_managed_openappsec_manifest.json DESTINATION .)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${CMAKE_INSTALL_PREFIX}/agent-docker.img
|
OUTPUT ${CMAKE_INSTALL_PREFIX}/agent-docker.img
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
FROM alpine
|
FROM alpine
|
||||||
|
|
||||||
|
ENV OPENAPPSEC_NANO_AGENT=TRUE
|
||||||
|
|
||||||
RUN apk add --no-cache -u busybox
|
RUN apk add --no-cache -u busybox
|
||||||
RUN apk add --no-cache -u zlib
|
RUN apk add --no-cache -u zlib
|
||||||
RUN apk add --no-cache bash
|
RUN apk add --no-cache bash
|
||||||
@@ -13,6 +15,8 @@ RUN apk add --no-cache libxml2
|
|||||||
RUN apk add --no-cache pcre2
|
RUN apk add --no-cache pcre2
|
||||||
RUN apk add --update coreutils
|
RUN apk add --update coreutils
|
||||||
|
|
||||||
|
COPY self_managed_openappsec_manifest.json /tmp/self_managed_openappsec_manifest.json
|
||||||
|
|
||||||
COPY install*.sh /nano-service-installers/
|
COPY install*.sh /nano-service-installers/
|
||||||
COPY entry.sh /entry.sh
|
COPY entry.sh /entry.sh
|
||||||
|
|
||||||
|
|||||||
@@ -1093,12 +1093,9 @@ void Waf2Transaction::add_request_hdr(const char* name, int name_len, const char
|
|||||||
void Waf2Transaction::end_request_hdrs() {
|
void Waf2Transaction::end_request_hdrs() {
|
||||||
dbgFlow(D_WAAP) << "[transaction:" << this << "] end_request_hdrs";
|
dbgFlow(D_WAAP) << "[transaction:" << this << "] end_request_hdrs";
|
||||||
m_isScanningRequired = setCurrentAssetContext();
|
m_isScanningRequired = setCurrentAssetContext();
|
||||||
if (m_siteConfig != NULL)
|
|
||||||
{
|
extractEnvSourceIdentifier();
|
||||||
// getOverrideState also extracts the source identifier and populates m_source_identifier
|
|
||||||
// but the State itself is not needed now
|
|
||||||
Waap::Override::State overrideState = getOverrideState(m_siteConfig);
|
|
||||||
}
|
|
||||||
m_pWaapAssetState->m_requestsMonitor->logSourceHit(m_source_identifier);
|
m_pWaapAssetState->m_requestsMonitor->logSourceHit(m_source_identifier);
|
||||||
IdentifiersEvent ids(m_source_identifier, m_pWaapAssetState->m_assetId);
|
IdentifiersEvent ids(m_source_identifier, m_pWaapAssetState->m_assetId);
|
||||||
ids.notify();
|
ids.notify();
|
||||||
|
|||||||
@@ -594,8 +594,6 @@ Waap::Override::State Waf2Transaction::getOverrideState(IWaapConfig* sitePolicy)
|
|||||||
overrideState.applyOverride(*overridePolicy, WaapOverrideFunctor(*this), m_matchedOverrideIds, true);
|
overrideState.applyOverride(*overridePolicy, WaapOverrideFunctor(*this), m_matchedOverrideIds, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
extractEnvSourceIdentifier();
|
|
||||||
|
|
||||||
if (overridePolicy) { // later we will run response overrides
|
if (overridePolicy) { // later we will run response overrides
|
||||||
m_overrideState.applyOverride(*overridePolicy, WaapOverrideFunctor(*this), m_matchedOverrideIds, false);
|
m_overrideState.applyOverride(*overridePolicy, WaapOverrideFunctor(*this), m_matchedOverrideIds, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ spec:
|
|||||||
responseCode: true
|
responseCode: true
|
||||||
logDestination:
|
logDestination:
|
||||||
cloud: true
|
cloud: true
|
||||||
logToAgent: false
|
logToAgent: true
|
||||||
stdout:
|
stdout:
|
||||||
format: json
|
format: json
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ COMPOSE_PROFILES=
|
|||||||
## Make sure to also adjust the envoy.yaml file in ENVOY_CONFIG path
|
## Make sure to also adjust the envoy.yaml file in ENVOY_CONFIG path
|
||||||
## to add a routing configuration for forwarding external traffic on e.g. port 80 to the juiceshop-backend container
|
## to add a routing configuration for forwarding external traffic on e.g. port 80 to the juiceshop-backend container
|
||||||
## you can use the example file available here:
|
## you can use the example file available here:
|
||||||
## https://raw.githubusercontent.com/openappsec/openappsec/examples/juiceshop/envoy/envoy.yaml
|
## https://raw.githubusercontent.com/openappsec/openappsec/main/examples/juiceshop/envoy/envoy.yaml
|
||||||
## place the file above in ENVOY_CONFIG path
|
## place the file above in ENVOY_CONFIG path
|
||||||
## note that juiceshop container listens on HTTP port 3000 by default
|
## note that juiceshop container listens on HTTP port 3000 by default
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ services:
|
|||||||
- ${APPSEC_DATA}:/etc/cp/data
|
- ${APPSEC_DATA}:/etc/cp/data
|
||||||
- ${APPSEC_LOGS}:/var/log/nano_agent
|
- ${APPSEC_LOGS}:/var/log/nano_agent
|
||||||
- ${APPSEC_LOCALCONFIG}:/ext/appsec
|
- ${APPSEC_LOCALCONFIG}:/ext/appsec
|
||||||
|
- shm-volume:/dev/shm/check-point
|
||||||
command: /cp-nano-agent
|
command: /cp-nano-agent
|
||||||
|
|
||||||
appsec-nginx:
|
appsec-nginx:
|
||||||
@@ -45,7 +46,7 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ${NGINX_CONFIG}:/etc/nginx/conf.d
|
- ${NGINX_CONFIG}:/etc/nginx/conf.d
|
||||||
|
- shm-volume:/dev/shm/check-point
|
||||||
## advanced configuration - volume mount for nginx.conf file:
|
## advanced configuration - volume mount for nginx.conf file:
|
||||||
## To change global instructions it's possible to also mount your own nginx.conf file by uncommenting the line below
|
## To change global instructions it's possible to also mount your own nginx.conf file by uncommenting the line below
|
||||||
## then specify a desired local folder for NGINX_CONF_FILE in the .env file.
|
## then specify a desired local folder for NGINX_CONF_FILE in the .env file.
|
||||||
@@ -123,6 +124,13 @@ services:
|
|||||||
profiles:
|
profiles:
|
||||||
- juiceshop
|
- juiceshop
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
shm-volume:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: tmpfs
|
||||||
|
device: tmpfs
|
||||||
|
|
||||||
## advanced configuration: learning_nfs volume for nfs storage in shared_storage container
|
## advanced configuration: learning_nfs volume for nfs storage in shared_storage container
|
||||||
##
|
##
|
||||||
## when configuring nfs storage in shared_storage container configuration above, make sure to also specify learning_nfs volume (see example below for using AWS EFS storage)
|
## when configuring nfs storage in shared_storage container configuration above, make sure to also specify learning_nfs volume (see example below for using AWS EFS storage)
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ done
|
|||||||
# VS ID argument is available only on install, for other actions, extract it from the package location
|
# VS ID argument is available only on install, for other actions, extract it from the package location
|
||||||
if [ -z "$VS_ID" ]; then
|
if [ -z "$VS_ID" ]; then
|
||||||
parent_pid=$PPID
|
parent_pid=$PPID
|
||||||
parent_cmdline=$(ps -o cmd= -p "$parent_pid")
|
parent_cmdline=$(cat /proc/"$parent_pid"/cmdline | tr '\0' ' ')
|
||||||
parent_dir=$(dirname "$parent_cmdline")
|
parent_dir=$(dirname "$parent_cmdline")
|
||||||
packages_folder=$(dirname "$parent_dir")
|
packages_folder=$(dirname "$parent_dir")
|
||||||
vs_folder=$(dirname "$packages_folder")
|
vs_folder=$(dirname "$packages_folder")
|
||||||
@@ -500,26 +500,26 @@ cp_copy() # Initials - cc
|
|||||||
cp_print "Destination md5, after the copy:\n$DEST_AFTER_COPY"
|
cp_print "Destination md5, after the copy:\n$DEST_AFTER_COPY"
|
||||||
}
|
}
|
||||||
|
|
||||||
update_cloudguard_appsec_manifest()
|
update_openappsec_manifest()
|
||||||
{
|
{
|
||||||
if [ -z ${INFINITY_NEXT_NANO_AGENT} ] && { [ -z ${CLOUDGUARD_APPSEC_STANDALONE} ] || [ -z ${DOCKER_RPM_ENABLED} ]; }; then
|
if [ -z ${OPENAPPSEC_NANO_AGENT} ] && { [ -z ${CLOUDGUARD_APPSEC_STANDALONE} ] || [ -z ${DOCKER_RPM_ENABLED} ]; }; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
selected_cloudguard_appsec_manifest_path="${TMP_FOLDER}/cloudguard_appsec_manifest.json"
|
selected_openappsec_manifest_path="${TMP_FOLDER}/openappsec_manifest.json"
|
||||||
if [ "${DOCKER_RPM_ENABLED}" = "false" ] || [ "${INFINITY_NEXT_NANO_AGENT}" = "TRUE" ]; then
|
if [ "${DOCKER_RPM_ENABLED}" = "false" ] || [ "${OPENAPPSEC_NANO_AGENT}" = "TRUE" ]; then
|
||||||
selected_cloudguard_appsec_manifest_path="${TMP_FOLDER}/self_managed_cloudguard_appsec_manifest.json"
|
selected_openappsec_manifest_path="${TMP_FOLDER}/self_managed_openappsec_manifest.json"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "$selected_cloudguard_appsec_manifest_path" ]; then
|
if [ ! -f "$selected_openappsec_manifest_path" ]; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cloudguard_appsec_manifest_path="${selected_cloudguard_appsec_manifest_path}.used"
|
openappsec_manifest_path="${selected_openappsec_manifest_path}.used"
|
||||||
mv "$selected_cloudguard_appsec_manifest_path" "$cloudguard_appsec_manifest_path"
|
mv "$selected_openappsec_manifest_path" "$openappsec_manifest_path"
|
||||||
fog_host=$(echo "$var_fog_address" | sed 's/https\?:\/\///')
|
fog_host=$(echo "$var_fog_address" | sed 's/https\?:\/\///')
|
||||||
fog_host=${fog_host%/}
|
fog_host=${fog_host%/}
|
||||||
sed "s/namespace/${fog_host}/g" ${cloudguard_appsec_manifest_path} > "${FILESYSTEM_PATH}/${CONF_PATH}/manifest.json"
|
sed "s/namespace/${fog_host}/g" ${openappsec_manifest_path} > "${FILESYSTEM_PATH}/${CONF_PATH}/manifest.json"
|
||||||
}
|
}
|
||||||
|
|
||||||
set_cloud_storage()
|
set_cloud_storage()
|
||||||
@@ -785,6 +785,7 @@ upgrade_conf_if_needed()
|
|||||||
|
|
||||||
[ -f "${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg" ] && . "${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg"
|
[ -f "${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg" ] && . "${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg"
|
||||||
|
|
||||||
|
[ -f "${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg" ] && \
|
||||||
previous_mode=$(cat ${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg | grep "orchestration-mode" | cut -d = -f 3 | sed 's/"//')
|
previous_mode=$(cat ${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg | grep "orchestration-mode" | cut -d = -f 3 | sed 's/"//')
|
||||||
if ! [ -z "$previous_mode" ]; then
|
if ! [ -z "$previous_mode" ]; then
|
||||||
var_orchestration_mode=${previous_mode}
|
var_orchestration_mode=${previous_mode}
|
||||||
@@ -1020,6 +1021,8 @@ install_orchestration()
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
[ -f "${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg" ] && . "${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg"
|
[ -f "${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg" ] && . "${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg"
|
||||||
|
|
||||||
|
[ -f "${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg" ] && \
|
||||||
previous_mode=$(cat ${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg | grep "orchestration-mode" | cut -d = -f 3 | sed 's/"//')
|
previous_mode=$(cat ${FILESYSTEM_PATH}/${SERVICE_PATH}/${ORCHESTRATION_FILE_NAME}.cfg | grep "orchestration-mode" | cut -d = -f 3 | sed 's/"//')
|
||||||
|
|
||||||
if ! [ -z "$previous_mode" ]; then
|
if ! [ -z "$previous_mode" ]; then
|
||||||
@@ -1044,6 +1047,7 @@ install_orchestration()
|
|||||||
rm -f "${FILESYSTEM_PATH}/${CONF_PATH}/default_orchestration_flags"
|
rm -f "${FILESYSTEM_PATH}/${CONF_PATH}/default_orchestration_flags"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
update_openappsec_manifest
|
||||||
upgrade_conf_if_needed
|
upgrade_conf_if_needed
|
||||||
|
|
||||||
cp_exec "${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --un-register ${FILESYSTEM_PATH}/${SERVICE_PATH}/cp-nano-orchestration $var_arch_flag"
|
cp_exec "${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --un-register ${FILESYSTEM_PATH}/${SERVICE_PATH}/cp-nano-orchestration $var_arch_flag"
|
||||||
@@ -1100,7 +1104,7 @@ install_orchestration()
|
|||||||
cp_exec "mkdir -p ${LOG_FILE_PATH}/${LOG_PATH}"
|
cp_exec "mkdir -p ${LOG_FILE_PATH}/${LOG_PATH}"
|
||||||
cp_exec "mkdir -p ${FILESYSTEM_PATH}/${DATA_PATH}"
|
cp_exec "mkdir -p ${FILESYSTEM_PATH}/${DATA_PATH}"
|
||||||
|
|
||||||
update_cloudguard_appsec_manifest
|
update_openappsec_manifest
|
||||||
|
|
||||||
if [ ! -f ${FILESYSTEM_PATH}/${DEFAULT_SETTINGS_PATH} ]; then
|
if [ ! -f ${FILESYSTEM_PATH}/${DEFAULT_SETTINGS_PATH} ]; then
|
||||||
echo "{\"agentSettings\": []}" > ${FILESYSTEM_PATH}/${DEFAULT_SETTINGS_PATH}
|
echo "{\"agentSettings\": []}" > ${FILESYSTEM_PATH}/${DEFAULT_SETTINGS_PATH}
|
||||||
|
|||||||
@@ -53,7 +53,12 @@ var_upgarde=false
|
|||||||
get_profile_agent_setting_with_default() {
|
get_profile_agent_setting_with_default() {
|
||||||
key="$1"
|
key="$1"
|
||||||
default_value="$2"
|
default_value="$2"
|
||||||
value=$(grep -oP "\"key\":\s*\"$key\".*?\"value\":\s*\"[^\"]+\"" $SETTINGS_FILE | sed -E 's/.*"value":\s*"([^"]+)".*/\1/')
|
|
||||||
|
value=$(grep -o "\"key\":\s*\"$key\".*?\"value\":\s*\"[^\"]*\"" $SETTINGS_FILE | sed -E 's/.*"value":\s*"([^"]*)".*/\1/')
|
||||||
|
if [ -z "$value" ]; then
|
||||||
|
value=$(grep -o "\"$key\":\s*\"[^\"]*\"" $SETTINGS_FILE | sed -E 's/.*"'"$key"'":\s*"([^"]*)".*/\1/')
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$value" = "null" ] || [ -z "$value" ]; then
|
if [ "$value" = "null" ] || [ -z "$value" ]; then
|
||||||
echo "$default_value"
|
echo "$default_value"
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user