diff --git a/CHANGELOG.md b/CHANGELOG.md
index 70505c9e5719ceba2d40ba2b6c1b197e8eefe603..f66c4ca07a1a300bc6d180954bb6fa82fca3c8f4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -48,9 +48,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - #14 - Handle files on file system without File entity: Those entries are
   returned without ID but with a notice now.
 
+* #11 - pam_authentication leaks the password to unprivileged processes on the
+  same machine.
+
 ### Security (in case of vulnerabilities)
 
 - TLS is by default restricted to v1.2 and v1.3 now.
+* #11 - pam_authentication leaks the password to unprivileged processes on the
+  same machine.
 
 
 ## [0.1.0] - 2018-10-09
diff --git a/misc/pam_authentication/makefile b/misc/pam_authentication/makefile
index 47830dc9451abcd3baddb7cce9478e7998287afd..0cd1b7d250358a116a32a45ba18875d5f72d887a 100644
--- a/misc/pam_authentication/makefile
+++ b/misc/pam_authentication/makefile
@@ -4,6 +4,8 @@
 #
 # Copyright (C) 2018 Research Group Biomedical Physics,
 # Max-Planck-Institute for Dynamics and Self-Organization Göttingen
+# Copyright (C) 2020 Indiscale GmbH <info@indiscale.com>
+# Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as
@@ -23,5 +25,5 @@
 # Makefile for pam_authentication.c
 
 main: pam_authentication.c
-	[ -d ./bin ] || mkdir ./bin
+	mkdir -p ./bin
 	gcc -o ./bin/pam_authentication pam_authentication.c -lpam -lpam_misc
diff --git a/misc/pam_authentication/pam_authentication.c b/misc/pam_authentication/pam_authentication.c
index 5d71ec2973fa59d18d10ffa4918a5236707b85af..4abef5bddb2a6c11ecefdcc8a1bf9179835bca84 100644
--- a/misc/pam_authentication/pam_authentication.c
+++ b/misc/pam_authentication/pam_authentication.c
@@ -4,6 +4,8 @@
  *
  * Copyright (C) 2018 Research Group Biomedical Physics,
  * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
+ * Copyright (C) 2020 Indiscale GmbH <info@indiscale.com>
+ * Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -23,17 +25,31 @@
 // Pam Authentication
 // A. Schlemmer, 07/2018
 
-#include <security/pam_appl.h>
-#include <security/pam_misc.h>
+/*
+Note: This program needs sufficient right to authenticate against anyone but
+oneself.  This can be done for example by changing the effective group id:
+
+```
+$ ls -l bin
+-rwxrwsrwx 1 root shadow 16992 Apr 28 07:45 pam_authentication
+```
+*/
+
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <termios.h>
+
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
 
-char * password; // needs to be global
+char *password; // needs to be global
 
 int supply_password(int num_msg, const struct pam_message **msgm,
                     struct pam_response **responsep, void *appdata_ptr) {
-  struct pam_response* response = (struct pam_response*)calloc(sizeof(struct pam_response), num_msg);
+  struct pam_response *response =
+    (struct pam_response*)calloc(sizeof(struct pam_response), num_msg);
   int i;
   for (i=0; i<num_msg; i++) {
     if (msgm[i]->msg_style == PAM_PROMPT_ECHO_OFF) {
@@ -51,24 +67,95 @@ static struct pam_conv conv =
    NULL
   };
 
-int main(int args, char** argv) {
-  if (args != 3) {
-    fprintf(stderr, "Usage: pam_authentication username password\n");
+/**
+ * @brief      Obtain the password from the given file.
+ *
+ * @param      filename: If "-", read from stdin.
+ *
+ * @return     0 if successful, else 1.
+ */
+bool get_password(char *filename) {
+  // With code from https://stackoverflow.com/a/1196696/232888
+  // by user https://stackoverflow.com/users/89266/dfa
+  struct termios backup, secret_setting;
+  bool is_tty = isatty(fileno(stdin));
+  /* disable echo */
+  if (is_tty) {
+    tcgetattr(fileno(stdin), &backup);
+    secret_setting = backup;
+    secret_setting.c_lflag &= ~ECHO;
+    secret_setting.c_lflag |= ECHONL;
+
+    if (tcsetattr(fileno(stdin), TCSANOW, &secret_setting) != 0) {
+      perror("Setting echo-less output flags failed.");
+      return EXIT_FAILURE;
+    }
+  }
+
+  FILE *pwfile;
+  if (strcmp(filename, "-")) {
+    pwfile = fopen(filename, "r");
+    if (pwfile == NULL) {
+      perror(filename);
+      if (is_tty) {
+        tcsetattr(fileno(stdin), TCSANOW, &backup);
+      }
+      return false;
+    }
+  } else {
+    pwfile = stdin;
+    printf("Enter the password: ");
+  }
+  password = NULL;
+  size_t n = 0;
+  ssize_t pwlen = getline(&password, &n, pwfile);
+  if (strcmp(filename, "-")) {
+    fclose(pwfile);
+  }
+  password[pwlen - 1] = 0;
+
+  /* restore terminal settings */
+  if (is_tty) {
+    if (tcsetattr(fileno(stdin), TCSANOW, &backup) != 0) {
+      perror("Resetting output flags failed.");
+    }
+  }
+
+  return true;
+}
+
+int main(int argc, char **argv) {
+  if (argc < 2 || argc > 3) {
+    fprintf(stderr, "Usage: pam_authentication <username> [<password_file>]\n");
     return 2;
   }
 
   pam_handle_t *pamh;
-  char * username = argv[1];
-  password = argv[2];
+  char *username = argv[1];
+  char *pw_file = "-";
+  if (argc == 3) {
+    pw_file = argv[2];
+  }
+
+  if (! get_password(pw_file)) {
+    fprintf(stderr, "Error while reading password.\n");
+    return 3;
+  }
+
   int res = pam_start("login", username, &conv, &pamh);
 
   if (!res == PAM_SUCCESS) {
     fprintf(stderr, "Error in starting pam authentication.\n");
     return 2;
   }
-
+  /* printf("\n>%s<\n", password);  // Warning: this prints the password! */
   res = pam_authenticate(pamh, 0);
-  // printf("Return code %i: %s\n", res, pam_strerror(pamh, res));
+
+/* printf("PAM_AUTH_ERR: %i\n\ */
+/* PAM_CRED_INSUFFICIENT: %i\n\ */
+/* PAM_AUTHINFO_UNAVAIL: %i\n", PAM_AUTH_ERR, PAM_CRED_INSUFFICIENT, PAM_AUTHINFO_UNAVAIL); */
+/*   printf("Return code (success=%i) %i: %s\n", PAM_SUCCESS, res, pam_strerror(pamh, res)); */
+  free(password);
   
   return res;
 }
diff --git a/misc/pam_authentication/pam_authentication.sh b/misc/pam_authentication/pam_authentication.sh
index e2a6fb76d8bada2f21749d1e9c9f3f5330ef8555..972e48f1ccc9c65ca0c56773f7e20a5da0977ebb 100755
--- a/misc/pam_authentication/pam_authentication.sh
+++ b/misc/pam_authentication/pam_authentication.sh
@@ -5,6 +5,8 @@
 #
 # Copyright (C) 2018 Research Group Biomedical Physics,
 # Max-Planck-Institute for Dynamics and Self-Organization Göttingen
+# Copyright (C) 2020 Indiscale GmbH <info@indiscale.com>
+# Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as
@@ -21,7 +23,7 @@
 #
 # ** end header
 #
-if ./bin/pam_authentication $1 $2 ; then
+if ./bin/pam_authentication $1 ; then
     echo "[OK]"
     exit 0
 else
diff --git a/src/main/java/caosdb/server/accessControl/Pam.java b/src/main/java/caosdb/server/accessControl/Pam.java
index 606fddb6858968c9ccf363dfd5fb703d4b264913..0cae6fd74ae3924e868757e1f058a430a23b1ff3 100644
--- a/src/main/java/caosdb/server/accessControl/Pam.java
+++ b/src/main/java/caosdb/server/accessControl/Pam.java
@@ -4,8 +4,9 @@
  *
  * Copyright (C) 2018 Research Group Biomedical Physics,
  * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
- * Copyright (C) 2019 IndiScale GmbH
- * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com)
+ * Copyright (C) 2019, 2020 Indiscale GmbH <info@indiscale.com>
+ * Copyright (C) 2019 Timm Fitschen <t.fitschen@indiscale.com>
+ * Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -70,9 +71,13 @@ public class Pam implements UserSource {
 
       final File script = new File(this.pam_script);
 
-      final ProcessBuilder pb = new ProcessBuilder(script.getAbsolutePath(), username, password);
+      final ProcessBuilder pb = new ProcessBuilder(script.getAbsolutePath(), username);
       pb.directory(script.getParentFile());
-      return pb.start();
+      final Process p = pb.start();
+      p.getOutputStream().write(password.getBytes());
+      p.getOutputStream().write('\n');
+      p.getOutputStream().flush();
+      return p;
     }
 
     @Override