HTTP

You can use the following http headers:
Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"
This ensures that the browser will always display it on the browser window.

Taggings:

Technology:

The problem can be solved by using a Nginx reverse proxy. Each application will be exposed through a corresponding sub-domain.

Dockerfile:

FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY proxy.conf /etc/nginx/includes/proxy.conf

proxy.conf:

proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_intercept_errors off;

nginx.conf:

# pm config.
server {
listen 80;
server_name site1.myproject.com;
location / {
include /etc/nginx/includes/proxy.conf;
proxy_pass http://site1_webserver_1;
}
access_log off;
error_log /var/log/nginx/error.log error;
}
# api config.
server {
listen 80;
server_name site1.myproject.com;
location / {
include /etc/nginx/includes/proxy.conf;
proxy_pass http://site2_webserver_1;
}
access_log off;
error_log /var/log/nginx/error.log error;
}
# Default
server {
listen 80 default_server;
server_name _;
root /var/www/html;
charset UTF-8;
access_log off;
log_not_found off;
error_log /var/log/nginx/error.log error;
}

The proxy_pass is the name of the application's docker container.

Technology:

Allow mixed content in Internet Explorer

TechScreen uses the Google API for advanced visual effects and functions. API is loaded from http site and TechScreen from https secured connection (SSL secured data exchange with the server), this results in an mixed content warning.

There are two possible solutions:
Solution 1:

  • open Internet Options > Security
  • select "trusted sites" zone in the top frame
  • click "sites" - new window opens
  • insert https://techscreen.tuwien.ac.at/ and click "add"
  • insert http://www.google.com
  • uncheck "Require server verification (https:) for all sites in this zone"
  • click "add"
  • close window
  • make sure "trusted sites" is still selected
  • click "custom level" button
  • scroll down to: Miscellaneous -> Display mixed content -> enable
  • close all windows

Now mixed content message should not appear anymore for TechScreen. Make sure to remove http://google.com from Trusted sites, if no longer needed!

Solution 2: (not recommended)

  • open Internet Options > Security
  • make sure "Internet" zone is selected in the top frame
  • click "custom level" button
  • scroll down to: Miscellaneous -> Display mixed content -> enable

With this setting you allow every https-site with secured server connection to load content from an http-site with unsecured connection. This is not recommended.

Implementing secure a secure session management system: A solution approach (implemented in PHP)

The following four problems can be identifiyed when using native PHP sessions (and these can be partly solved):

Problem 1: The session ID is the only thing, which is being used to identify a client
Solution 1: Use additional information about your client, to improve chances, that the identifiyed client is honestly the correct one (e.g. Client IP Adresss (be aware of proxies), Client User Agent, ...)

Problem 2: The process of generating client IPs can be reproduced by an attacker
Solution 2: Use a secure mechanism to generate your session IDs, which is not reproducible

Problem 3: Sessions exist longer than they should (which makes attackes easier)
Solution 3: Instant destruction of session ID if the server suspects that there might be something going wrong

Problem 4: Sessions IDs may be stolen using malicious JavaScript
Solution 4: Use only session cookies and make your cookie HTTP-only

The following PHP is a solution approach to make a secure session management in PHP:

/*
* This file is for generating save sessions.
*/
final class Session {

/**
* Secure start of a session.
*
* @return type
*/
public static function startSession() {

session_name("unique_session_id_name");

// try to start the session
$ok = @session_start();

// no session existing, make a new session
if (!$ok) {
// replace the Session ID
self::session_regenerate_save_id();
// start session
session_start();
}

// make the session cookie secure: HTTPonly and if possible HTTPS
$force_ssl_cookie = false;

$currentCookieParams = session_get_cookie_params();
$sidvalue = session_id();
setcookie(
"sess-aphk-".APP_ID,//name
$sidvalue,//value
0,//expires at end of session
$currentCookieParams['path'],//path
$currentCookieParams['domain'],//domain
$force_ssl_cookie,
true
);

// If the session was already existing, we must have set the client ip
if (isset($_SESSION["client_ip"])) {

// If this client ip does not match the ip of the current client, this might be an attack --> destroy session
if (self::getSessionClientIP() === $_SESSION["client_ip"] && self::getSessionClientAgent() === $_SESSION['client_agent']) {
if(self::checkStillActive()) {
return true;
}
} else {
self::destroy_session_absolute();
header('Location: '.$_SERVER['REQUEST_URI']);
die;
}

} else {
// if we have to create a new session, we do it in a secure, self-defined way
self::destroy_session_absolute();
self::session_regenerate_save_id();
session_start();
self::setSessionClientIP();
self::setSessionClientAgent();
$_SESSION['last_activity'] = time();
}
}

// creates a new, secure session id (MUST be called BEFORE session_start())
public static function session_regenerate_save_id() {
$hash_time = md5(microtime());
$hash_ip = md5($_SERVER["REMOTE_ADDR"]);
$hash_space = sha1(disk_free_space(getcwd()));
$session_id = sha1($hash_time . $hash_ip . $hash_space);
session_id($session_id);
}

// sets the session IP of the current client
private static function setSessionClientIP() {

if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
$_SESSION["client_ip"] = md5($_SERVER["HTTP_X_FORWARDED_FOR"]);
} else {
$_SESSION["client_ip"] = md5($_SERVER["REMOTE_ADDR"]);
}
}

// retrieves the client IP of the session owner
private static function getSessionClientIP() {
if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
return md5($_SERVER["HTTP_X_FORWARDED_FOR"]);
} else {
return md5($_SERVER["REMOTE_ADDR"]);
}
}

private static function setSessionClientAgent() {
$_SESSION['client_agent'] = md5($_SERVER['HTTP_USER_AGENT']);
}

private static function getSessionClientAgent() {
return md5($_SERVER['HTTP_USER_AGENT']);
}

// secure, instant session destruction
public static function destroy_session_absolute() {
session_name("sess-aphk-".APP_ID);
if(session_id()) {
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), "", time() - 42000, "/");
}
session_destroy();
}
}

// retrieve the current session id
public static function get_current_session_id() {
session_name("sess-aphk-".APP_ID);
return session_id();
}

public static function checkStillActive() {
// make sure that a user was not inactive for too long
if(intval($_SESSION['last_activity']) < time()-1200) { //have we expired?
self::destroy_session_absolute();
header('Location: '.$_SERVER['REQUEST_URI']);
die;
} else { //if we haven't expired:
$_SESSION['last_activity'] = time(); //this was the moment of last activity.
return true;
}
}
}

Subscribe to HTTP