Skip to content
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
33 changes: 33 additions & 0 deletions autobot-slm-backend/ansible/roles/slm_manager/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,39 @@
# ==========================================================
# Nginx configuration
# ==========================================================

# #6842: DRY security-headers via nginx snippets (avoids repeating 5 add_header
# lines at every location that overrides parent context).
- name: "SLM | Ensure nginx snippets directory exists"
ansible.builtin.file:
path: /etc/nginx/snippets
state: directory
mode: "0755"
become: yes
tags: ['slm', 'nginx']

- name: "SLM | Deploy strict security-headers nginx snippet (#6842)"
ansible.builtin.template:
src: autobot-security-headers-strict.conf.j2
dest: /etc/nginx/snippets/autobot-security-headers-strict.conf
mode: "0644"
become: yes
notify:
- test nginx config
- reload nginx
tags: ['slm', 'nginx']

- name: "SLM | Deploy iframe-host security-headers nginx snippet (#6842)"
ansible.builtin.template:
src: autobot-security-headers-iframe-host.conf.j2
dest: /etc/nginx/snippets/autobot-security-headers-iframe-host.conf
mode: "0644"
become: yes
notify:
- test nginx config
- reload nginx
tags: ['slm', 'nginx']

- name: "SLM | Deploy nginx configuration"
ansible.builtin.template:
src: autobot-slm.conf.j2
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# AutoBot - AI-Powered Automation Platform
# Copyright (c) 2025 mrveiss
# Author: mrveiss
#
# Permissive security headers for dashboard embedding locations (Grafana, Prometheus).
# Deployed by slm_manager Ansible role (#6842).
# Issue #1160: nginx add_header in location replaces parent context headers, so all re-declared.
# CSP: frame-ancestors 'self' allows SLM admin (same origin) to embed dashboards; unsafe-eval
# for Grafana's Angular/React runtime; blob: for chart rendering.
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' wss://$host; frame-ancestors 'self'; base-uri 'self';" always;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# AutoBot - AI-Powered Automation Platform
# Copyright (c) 2025 mrveiss
# Author: mrveiss
#
# Strict security headers — server default.
# Deployed by slm_manager Ansible role (#6842).
# CSP: no iframe embedding (frame-ancestors 'none'), no eval.
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self' wss://$host; frame-ancestors 'none'; base-uri 'self'; form-action 'self';" always;
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,8 @@ server {
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;

# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Issue #1015: Content Security Policy
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self' wss://$host; frame-ancestors 'none'; base-uri 'self'; form-action 'self';" always;
# Security headers (#6842: DRY — single source of truth in snippet)
include /etc/nginx/snippets/autobot-security-headers-strict.conf;

# Issue #1090: Allow SLM agent event sync payloads (typically 1.5-2MB)
client_max_body_size 10m;
Expand Down Expand Up @@ -294,12 +289,8 @@ server {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600;

# Issue #1160: Override server-level security headers for Grafana iframe embedding.
# nginx add_header in location replaces parent context headers, so all headers re-declared.
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' wss://$host; frame-ancestors 'self'; base-uri 'self';" always;
# #6842: DRY — headers in snippet; frame-ancestors 'self' allows dashboard embedding.
include /etc/nginx/snippets/autobot-security-headers-iframe-host.conf;
}

# Grafana reverse proxy (monitoring dashboards)
Expand All @@ -312,13 +303,8 @@ server {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# Issue #1160: Override server-level security headers for Grafana iframe embedding.
# nginx add_header in location replaces parent context headers, so all headers re-declared.
# frame-ancestors 'self' allows the SLM admin (same origin) to embed Grafana dashboards.
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' wss://$host; frame-ancestors 'self'; base-uri 'self';" always;
# #6842: DRY — headers in snippet; frame-ancestors 'self' allows dashboard embedding.
include /etc/nginx/snippets/autobot-security-headers-iframe-host.conf;
{% if grafana_enable_cors | default(false) %}

# CORS headers for external Grafana iframe embedding
Expand Down Expand Up @@ -396,6 +382,8 @@ server {
root {{ frontend_dist_dir }};
try_files $uri $uri/ /index.html;

# #6842: include strict security headers (nginx add_header in location replaces server-level)
include /etc/nginx/snippets/autobot-security-headers-strict.conf;
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Cross-Origin-Opener-Policy "same-origin" always;
Expand Down
Loading