Sichere Webserver(konfiguration): Difference between revisions
Line 4: | Line 4: | ||
==== Content Security Policy ==== |
==== Content Security Policy ==== |
||
==== Cross-origin Resource Sharing ==== |
==== Cross-origin Resource Sharing ==== |
||
Der HTTP-Header "Access-Control-Allow-Origin" gibt an, welche anderen Domains auf den Inhalt der eigenen Domain über Scripte zugreifen dürfen. Dabei wird die Same-Origin-Policy <ref>https://de.wikipedia.org/wiki/Same-Origin-Policy</ref> bewusst umgangen, um z.B. über Domain-Grenzen hinweg Web-Applikationen in einer gemeinsamen Oberfläche zu kombinieren. Dieser Header sollte nur vorhanden sein, falls dies unbedingt benötigt wird und sollte auf so wenig Domains wie nötig beschränkt werden. Als Beispiel sollte ein Server, der eine Webseite und eine API betreibt und den Dienst XMLHttpRequest access auf einer Remote-Webseite anbietet, sollte nur die API den Access-Control-Allow-Origin Header |
Der HTTP-Header "Access-Control-Allow-Origin" gibt an, welche anderen Domains auf den Inhalt der eigenen Domain über Scripte zugreifen dürfen. Dabei wird die Same-Origin-Policy <ref>https://de.wikipedia.org/wiki/Same-Origin-Policy</ref> bewusst umgangen, um z.B. über Domain-Grenzen hinweg Web-Applikationen in einer gemeinsamen Oberfläche zu kombinieren. Dieser Header sollte nur vorhanden sein, falls dies unbedingt benötigt wird und sollte auf so wenig Domains wie nötig beschränkt werden. Als Beispiel sollte ein Server, der eine Webseite und eine API betreibt und den Dienst XMLHttpRequest access auf einer Remote-Webseite anbietet, sollte nur die API den Access-Control-Allow-Origin Header senden.<ref>https://wiki.mozilla.org/Security/Guidelines/Web_Security</ref> <br> |
||
Der Zugriff kann durch weitere Weitere Acces-Control-* Header eingeschränkt werden. |
Der Zugriff kann durch weitere Weitere Acces-Control-* Header eingeschränkt werden. |
||
<code> |
<code> |
Revision as of 16:42, 20 October 2016
Sichere Konfiguration
Allgemein
Sicherheitskonzepte
Content Security Policy
Cross-origin Resource Sharing
Der HTTP-Header "Access-Control-Allow-Origin" gibt an, welche anderen Domains auf den Inhalt der eigenen Domain über Scripte zugreifen dürfen. Dabei wird die Same-Origin-Policy <ref>https://de.wikipedia.org/wiki/Same-Origin-Policy</ref> bewusst umgangen, um z.B. über Domain-Grenzen hinweg Web-Applikationen in einer gemeinsamen Oberfläche zu kombinieren. Dieser Header sollte nur vorhanden sein, falls dies unbedingt benötigt wird und sollte auf so wenig Domains wie nötig beschränkt werden. Als Beispiel sollte ein Server, der eine Webseite und eine API betreibt und den Dienst XMLHttpRequest access auf einer Remote-Webseite anbietet, sollte nur die API den Access-Control-Allow-Origin Header senden.<ref>https://wiki.mozilla.org/Security/Guidelines/Web_Security</ref>
Der Zugriff kann durch weitere Weitere Acces-Control-* Header eingeschränkt werden.
# Allow https://random-dashboard.mozilla.org to read the returned results of this API
Access-Control-Allow-Origin: https://random-dashboard.mozilla.org
Access-Control-Allow-Methods: GET
HTTP Public Key Pinning
HTTP Strict Transport Security
Subresource Integrity
X-Content-Type-Options
X-Frame-Options
X-XSS-Protection
Beispiel Apache Konfiguration
--Debian apache 2.4
-enable mod_headers
sudo a2enmod headers
-insert into config file:
sudo vi /etc/apache2/conf-available/security.conf
-enable XFO
Header set X-Frame-Options: "sameorigin"
-enable CSP
Header set Content-Security-Policy: "object-src 'self'; frame-src 'self'; script-src 'self‘;"
-X-Content-Type-Options
Header set X-Content-Type-Options: „no sniff“
-Config for port 80 (redirect to https)
sudo a2enmod rewrite
-in Virtual Hosts file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</IfModule>
-Config for port 443
-enable SSL, e.g.
SSLEngine On
SSLCertificateFile /etc/ssl/localcerts/apache.pem
SSLCertificateKeyFile /etc/ssl/localcerts/apache.key
Mozilla Observatory
Beschreibung
Das Observatory von Mozilla ist ein kostenloses Tool um Webseiten auf ihre Sicherheit zu überprüfen. Damit sollen Webseitenbetreibern die Möglichkeit gegeben werden ihre Seite auf Schwachstellen zu prüfen. Dabei überprüft Observatory ob verschiedene Sicherheitsmechanismen vorhanden und wie gut diese implementiert sind. Damit sollen Entwicklern und System-Administratoren unterstütz werden, ihre Webseite sicher zu implementieren. <ref> https://pokeinthe.io/2016/08/25/observatory-by-mozilla-a-new-tool/ </ref>
Observatory überprüft dabei, ob die Site beispielsweise über Cookie-Secure-Flags verfügt oder die Integrität von Skripten überprüft (Subresource Integrity). Weitere Checks betreffen die Verschlüsselung von Inhalten per HTTPS (Redirections, HSTS, HTTP Public Key Pinning). Überprüft werden zudem die Einstellungen zu Cross-Origin Resource Sharing (CORS) und Content Security Policy (CSP), X-Frame-Optionen, X-Content-Type-Optionen und X-XSS-Protection. Die Auswertung startet bei 100 Punkten. Observatory vergibt dabei eine Wertung von A+ bis F. In den elf überprüften Bereichen können bis zu 50 Punkte abgezogen werden, wenn bestimmte Sicherheitsmerkmale nicht aktiviert oder falsch implementiert sind.<ref> https://pokeinthe.io/2016/08/25/observatory-by-mozilla-a-new-tool/ </ref> Die niedrigste Punktzahl liegt jedoch bei null Punkten.
Der Nutzer erhält vor dem Überprüfen die Option, die Webseite nicht mit in die Liste der öffentlich einsehbaren Webseiten zu übernehmen. Weiterhin wird die Möglichkeit geboten auf Third-party Anbieter zu verzichen. Dabei wird die Möglichkeit geboten, dass die Seite u. a. auf verfügbare cipher suites, handshake methods, supported protocols und Resistenz von TLS-Angriffen zu überprüfen. <ref>https://observatory.mozilla.org/faq.html </ref>
Weiterhin wurde ein Repository mit dem Tool für eine lokale Installation, unter der Mozilla Public License Version 2.0, veröffentlicht. <ref>https://github.com/mozilla/http-observatory</ref> Das Tool besteht aus drei Modulen. Zum einen wird mit "observatory-cli" das offizielle Node.js command line interface mitgeliefert. Des weiteren wird der Scanner und eine API bereitgestellt. Unabhängig davon kann die HTTP Observatory Webseite separat heruntergeladen werden. <ref>https://github.com/mozilla/http-observatory-website</ref>
Mit dem Scanner und der API kann Observatory auch lokal betrieben werden. Damit können Server bereits getestete werden, bevor sie der Öffentlichkeit im Internet zugänglich gemacht werden. Die Daten der getesteten Server liegt dabei in einer lokalen Postgres Datenbank.
Das command line interface kann unabhängig von der lokalen Installation betrieben werden, da es auf das von Mozilla zur Verfügung gestellte Observatory zugreift. Es wird also nicht die lokale Installation verwendet.
Lokale Installation
#how to install observatory (tested on Ubuntu 16.04 LTS)
sudo apt-get install -y git libpq-dev postgresql redis-server python3 python3-pip
cd /opt/
sudo git clone https://github.com/mozilla/http-observatory.git
sudo su - postgres
createdb http_observatory
psql http_observatory < /opt/http-observatory/httpobs/database/schema.sql
psql http_observatory
\password httpobsapi #passwort festlegen z.B. its
\password httpobsscanner #passwort festlegen z.B. its
#exit db (\q)
#exit psql user (exit)
sudo vi /etc/postgresql/9.5/main/postgresql.conf #set max_connections = 512, shared_buffers = 256MB
sudo service postgresql restart
sudo useradd -m httpobs
sudo su - httpobs
cd /opt/http-observatory
pip3 install .
pip3 install -r requirements.txt --upgrade
exit
#everything from here has to be done for every start - Starting from normal user
#start scanner
sudo install -m 750 -o httpobs -g httpobs -d /var/run/httpobs /var/log/httpobs
sudo su - httpobs
echo export HTTPOBS_API_URL="http://localhost:57001/api/v1" >> ~/.profile
cd /opt/http-observatory/
HTTPOBS_DATABASE_USER="httpobsscanner" HTTPOBS_DATABASE_PASS="its" /opt/http-observatory/httpobs/scripts/httpobs-scan-worker
#open new Terminal to start api
sudo su - httpobs
cd /opt/http-observatory/
HTTPOBS_DATABASE_USER="httpobsapi" HTTPOBS_DATABASE_PASS="its" uwsgi --http :57001 --wsgi-file /opt/http-observatory/httpobs/website/main.py --processes 8
--callable app --master
Verwendung der API
- Aufruf zum Scannen einer neuene Seite starten
- POST-Request
- http://localhost:57001/api/v1/analyze?host=www.testseite.de
- hidden=true&rescan=true
- hidden=true&rescan=true
- POST-Request
- Status eines Scans anzeigen
{
"end_time": "Tue, 22 Mar 2016 21:51:41 GMT",
"grade": "A",
"response_headers": { ... },
"scan_id": 1,
"score": 90,
"start_time": "Tue, 22 Mar 2016 21:51:40 GMT",
"state": "FINISHED",
"tests_failed": 2,
"tests_passed": 9,
"tests_quantity": 11
}
<ref>https://github.com/mozilla/http-observatory/blob/master/httpobs/docs/api.md#scan</ref>
- Resultate eines bestimmten Scans anzeigen (Scan-Nr.)
- GET-Request
- http://localhost:57001/api/v1/getScanResults?scan=1
- Beispiel siehe unten
- GET-Request
- Liste Letzter Scans anzeigen
- GET-Request
- http://localhost:57001/api/v1/getRecentScans?max=20
- mit Option von bestimmten "Noten" in diesem Fall alle F, also 20 Punkte und weniger
- mit Option von bestimmten "Noten" in diesem Fall alle F, also 20 Punkte und weniger
- GET-Request
{
"site1.mozilla.org": "A",
"site2.mozilla.org": "B-",
"site3.mozilla.org": "C+",
"site4.mozilla.org": "F",
"site5.mozilla.org": "F",
"site6.mozilla.org": "E",
"site7.mozilla.org": "F",
"site8.mozilla.org": "B+",
"site9.mozilla.org": "A+",
"site0.mozilla.org": "A-"
}
- Liste der möglichen Noten mit Aufteilung getesteter Seiten
{
"A+": 3,
"A": 6,
"A-": 2,
"B+": 8,
"B": 76,
"B-": 79,
"C+": 80,
"C": 88,
"C-": 86,
"D+": 60,
"D": 110,
"D-": 215,
"E": 298,
"F": 46770
}
Beispiel für Resultat eines Scans
The tests object contains one test object for each test conducted by the HTTP Observatory. <ref>https://github.com/mozilla/http-observatory/blob/master/httpobs/docs/api.md#tests</ref> Each test object is contains the following values:
- expectation: the expectation for a test result going in
- name: the name of the test; this should be the same as the parent object's name
- output: artifacts related to the test; these can vary widely between tests and are not guaranteed to be stable over time.
- data: generally as close to the raw output of the test as is possible. For example, in the strict-transport-security test, output -> data contains the raw Strict-Transport-Security header
- ????: other values under output have keys that vary; for example, the strict-transport-security test has a includeSubDomains key that is either set to True or False. Similarly, the redirection test contains a route key that contains an array of the URLs that were redirected to. See example below for more available keys.
- pass: whether the test passed or failed; a test that meets or exceeds the expectation will be marked as passed
- result: result of the test
- score_description: short description describing what result means
- score_modifier: how much the result of the test affected the final score; should range between +5 and -50
{
"content-security-policy": {
"expectation": "csp-implemented-with-no-unsafe",
"name": "content-security-policy",
"output": {
"data": {
"connect-src": [
"'self'",
"https://sentry.prod.mozaws.net"
],
"default-src": [
"'self'"
],
"font-src": [
"'self'",
"https://addons.cdn.mozilla.net"
],
"frame-src": [
"'self'",
"https://ic.paypal.com",
"https://paypal.com",
"https://www.google.com/recaptcha/",
"https://www.paypal.com"
],
"img-src": [
"'self'",
"data:",
"blob:",
"https://www.paypal.com",
"https://ssl.google-analytics.com",
"https://addons.cdn.mozilla.net",
"https://static.addons.mozilla.net",
"https://ssl.gstatic.com/",
"https://sentry.prod.mozaws.net"
],
"media-src": [
"https://videos.cdn.mozilla.net"
],
"object-src": [
"'none'"
],
"report-uri": [
"/__cspreport__"
],
"script-src": [
"'self'",
"https://addons.mozilla.org",
"https://www.paypalobjects.com",
"https://apis.google.com",
"https://www.google.com/recaptcha/",
"https://www.gstatic.com/recaptcha/",
"https://ssl.google-analytics.com",
"https://addons.cdn.mozilla.net"
],
"style-src": [
"'self'",
"'unsafe-inline'",
"https://addons.cdn.mozilla.net"
]
}
},
"pass": false,
"result": "csp-implemented-with-unsafe-inline-in-style-src-only",
"score_description": "Content Security Policy (CSP) implemented with unsafe-inline inside style-src directive",
"score_modifier": -5
},
"contribute": {
"expectation": "contribute-json-with-required-keys",
"name": "contribute",
"output": {
"data": {
"bugs": {
"list": "https://github.com/mozilla/addons-server/issues",
"report": "https://github.com/mozilla/addons-server/issues/new"
},
"description": "Mozilla's official site for add-ons to Mozilla software, such as Firefox, Thunderbird, and SeaMonkey.",
"name": "Olympia",
"participate": {
"docs": "http://addons-server.readthedocs.org/",
"home": "https://wiki.mozilla.org/Add-ons/Contribute/AMO/Code",
"irc": "irc://irc.mozilla.org/#amo",
"irc-contacts": [
"andym",
"cgrebs",
"kumar",
"magopian",
"mstriemer",
"muffinresearch",
"tofumatt"
]
},
"urls": {
"dev": "https://addons-dev.allizom.org/",
"prod": "https://addons.mozilla.org/",
"stage": "https://addons.allizom.org/"
}
}
},
"pass": true,
"result": "contribute-json-with-required-keys",
"score_description": "Contribute.json implemented with the required contact information",
"score_modifier": 0
},
"cookies": {
"expectation": "cookies-secure-with-httponly-sessions",
"name": "cookies",
"output": {
"data": {
"sessionid": {
"domain": ".addons.mozilla.org",
"expires": null,
"httponly": true,
"max-age": null,
"path": "/",
"port": null,
"secure": true
}
}
},
"pass": true,
"result": "cookies-secure-with-httponly-sessions",
"score_description": "All cookies use the Secure flag and all session cookies use the HttpOnly flag",
"score_modifier": 0
},
"cross-origin-resource-sharing": {
"expectation": "cross-origin-resource-sharing-not-implemented",
"name": "cross-origin-resource-sharing",
"output": {
"data": {
"acao": null,
"clientaccesspolicy": null,
"crossdomain": null
}
},
"pass": true,
"result": "cross-origin-resource-sharing-not-implemented",
"score_description": "Content is not visible via cross-origin resource sharing (CORS) files or headers",
"score_modifier": 0
},
"public-key-pinning": {
"expectation": "hpkp-not-implemented",
"name": "public-key-pinning",
"output": {
"data": null,
"includeSubDomains": false,
"max-age": null,
"numPins": null,
"preloaded": false
},
"pass": true,
"result": "hpkp-not-implemented",
"score_description": "HTTP Public Key Pinning (HPKP) header not implemented",
"score_modifier": 0
},
"redirection": {
"expectation": "redirection-to-https",
"name": "redirection",
"output": {
"destination": "https://addons.mozilla.org/en-US/firefox/",
"redirects": true,
"route": [
"http://addons.mozilla.org/",
"https://addons.mozilla.org/",
"https://addons.mozilla.org/en-US/firefox/"
],
"status_code": 200
},
"pass": true,
"result": "redirection-to-https",
"score_description": "Initial redirection is to https on same host, final destination is https",
"score_modifier": 0
},
"strict-transport-security": {
"expectation": "hsts-implemented-max-age-at-least-six-months",
"name": "strict-transport-security",
"output": {
"data": "max-age=31536000",
"includeSubDomains": false,
"max-age": 31536000,
"preload": false,
"preloaded": false
},
"pass": true,
"result": "hsts-implemented-max-age-at-least-six-months",
"score_description": "HTTP Strict Transport Security (HSTS) header set to a minimum of six months (15768000)",
"score_modifier": 0
},
"subresource-integrity": {
"expectation": "sri-implemented-and-external-scripts-loaded-securely",
"name": "subresource-integrity",
"output": {
"data": {
"https://addons.cdn.mozilla.net/static/js/impala-min.js?build=552decc-56eadb2f": {
"crossorigin": null,
"integrity": null
},
"https://addons.cdn.mozilla.net/static/js/preload-min.js?build=552decc-56eadb2f": {
"crossorigin": null,
"integrity": null
}
}
},
"pass": false,
"result": "sri-not-implemented-but-external-scripts-loaded-securely",
"score_description": "Subresource Integrity (SRI) not implemented, but all external scripts are loaded over https",
"score_modifier": -5
},
"x-content-type-options": {
"expectation": "x-content-type-options-nosniff",
"name": "x-content-type-options",
"output": {
"data": "nosniff"
},
"pass": true,
"result": "x-content-type-options-nosniff",
"score_description": "X-Content-Type-Options header set to \"nosniff\"",
"score_modifier": 0
},
"x-frame-options": {
"expectation": "x-frame-options-sameorigin-or-deny",
"name": "x-frame-options",
"output": {
"data": "DENY"
},
"pass": true,
"result": "x-frame-options-sameorigin-or-deny",
"score_description": "X-Frame-Options (XFO) header set to SAMEORIGIN or DENY",
"score_modifier": 0
},
"x-xss-protection": {
"expectation": "x-xss-protection-1-mode-block",
"name": "x-xss-protection",
"output": {
"data": "1; mode=block"
},
"pass": true,
"result": "x-xss-protection-enabled-mode-block",
"score_description": "X-XSS-Protection header set to \"1; mode=block\"",
"score_modifier": 0
}
}
<ref>https://github.com/mozilla/http-observatory/blob/master/httpobs/docs/api.md#tests</ref>
Literatur
<references />