Handling authentication with Apache reverse proxy for plack/PSGI app - perl

This is my scenario:
So,
Requests via encrypted HTTPS go to Apache like: https://server1/MyPerlApp
If the user is not logged in, they get a redirect to some login page (in the server1), and Apache doesn't proxy the request to Server2
When the user logged in - IS authenticated - then Apache forwards all requests that are coming to https://server1/MyPerlApp to http://server2:5000
Question1: Is this possible? (Asking, because I don't know Apache enough deeply, and this is not an simple:
ProxyPass /MyPerlApp http://server2:5000/
because I need need authenticate the user at server1 and set ProxyPass Only if authenticated.
Since Apache is quite flexible I assume the answer is yes for the above (but confirmation and details is very welcomed) - so here are my main specific questions:
How will my Plack application know what user is authenticated at the Apache level (i.e. on the 1st server)?
what is an easy way to deliver some of the user info to the perl app on the server2? e.g. with Apache's mod_rewrite what appends an user=username parameter to each query,
can Apache can set some HTTP headers that my perl app should read?
is there an easy and recommenced way?
I'm looking for how to avoid authentication routines in my starman/perl app, maily because:
the user need to log into server1 anyway (for other tasks in his workflow)
if he is already logged in, authentication in my app is not needed (avoid unnecessary double login)
but I still need to know which users are logged in (via Apache at server1)
There is already similar questions, but:
https://stackoverflow.com/q/12561830/734304 (no answer)
https://stackoverflow.com/q/11907797/734304 (no answer)
Apache reverse proxy with basic authentication (similar, but the backend is in the same server and same apache)

[I think you asked four questions here. Some of them overlap. I will try to answer as many as I can, then edit your question to make it a bit clearer. It might be helpful to post your current Apache httpd.conf so people can see how you are handling access and authentication currently. That way you might get better suggestions on how to integrate the proxied application(s) with your Apache instance.]
Setting up a front-end that can handle "Web Site Single Sign On" requires some planning and configuration but it is worth the effort. To make this easier, you'll want to use Apache-2.4. You probably are using this version, but Apache has become something of a workhorse, such that some sites update it much less frequently than in the past. Apache 2.4 includes mod_session and mod_auth_form which make it possible to set up form-based "web portal Single Sign On" sorts of tools with Apache for sites with multiple back-end application servers (often running on separate machine ports or sockets) combined under one outward facing set of URL/URIs. This pattern of use was so widespread with Apache that the 2.4 release added features to make it easier to do.
You asked about an "easy recommended" way to do what you have described. Well, you are on the right track. Apache's httpd is really useful for this kind of authentication/authorization and "user login" sort of application - so much so that it's become a staple tool for what you are trying to do.
You asked how to "deliver the user information" to the back-end server. You do that in the same way you handle state in any web application: with sessions and cookies. Session information contains key/value pairs encoded as an application/x-www-form-urlencodedstring. You can also create an HTTP_SESSION environment value that you back-end application can read from. Your Plack/Starman application has to be able to handle sessions and cookies (i.e. it has to be "session aware") if you want to use them there of course. Look at Plack::Middleware::Session for ideas on how to approach this.
For sure, setting up authentication with mod_auth_form is more complicated than Basic authentication. But with form based logins javascript can be used (judiciously), client applications can store form information locally for quick logins; as well, forms are flexible and can gather more data and pass more information to the user and some of the complexity (redirection after authentication) can be handled by Apache. Since they are just an HTML <form>, you can start simply and make them more elaborate as your site grows. That said you can have an Apache Reverse Proxy simply provide Basic Auth for your back-end.
Without seeing more details about your installation I can't say how/why you might need mod_rewrite per se, but Rewrite directives can play nicely with ProxyPass. Of course throughout your site you'd want to check for authentication and session information and redirect users to a login form where/when necessary. Using mod_auth_form makes this easier to implement at the cost of a somewhat more complicated configuration. As for the reverse prosy itself, you'd use ProxyPass in the normal way to pass requests to your back end:
ProxyPass /app http://[starmanhost]:3000/
Then you need configure or tweak your current Apache system to have Session On and require authentication for the URLs in question (unless the entire / requires authentication) in the standard Apache way:
<Location /app>
AuthType Basic
Session On
SessionCookieName session path=/
...
require valid-user
</Location>
etc. As the Apache docs point out (and you'll want to read mod_session, mod_proxy among others), you can pass session information around for use by back-end applications.
If the SessionHeader directive is used to define an HTTP request
header, the session, encoded as a application/x-www-form-urlencoded
string, will be made available to the application.
From mod_session documentation Integrating Sessions with External Applications.
For privacy/security you'll want to use mod_session_crypto and SSL if that's possible. As you note you will not need encryption to be "end to end" (i.e. HTTPS from client to outward facing front-end and between the reverse proxy and back-end applications) but if outside connections are https:// and you keep session information on the server (using mod_session_dbd as another response noted) using encrypted storage, you can avoid obvious threats inherent in sharing user session information across servers. The best part of this is you can add these layers one by one without having to modify your back-end applications extensively. This is the advantage of creating a solid "WebSSO server" front-end to handle logins.
Note that I've been using the term WebSSO here a bit loosely. Strictly speaking, WebSSO (and SSO) are much broader and more encompassing concepts with their own standards tracks and technologies (there are a couple Apache projects focused on this). This is why I tend to call the approach you are trying "Web Site SSO". Support for a wide range of authentication, programming language modules, proxying, and rewriting makes Apache's httpd the "swiss army knife/duct tape" of choice for handling logins and sessions in this way.
Your rational for doing this is sound, since you can avoid extra logins and confusing users (and their browsers). As well, by decoupling the authentication steps from your application and dedicating that task to Apache, you make it easier for developers to write back-end applications. Your question is very general though. I think you can start to try out some of the suggestions that begin to appear here and if you run into problems you can follow up with more specific questions focused on your implementation.
Get the Apache bits working correctly first (Session On; ProxyPass, <Location /app>) and make sure the right information is getting created, stored and passed on by the front-end. This will be very useful for lots of things going forward. Apache gurus can help here. Once you have the proper session information being passed to your back-end you can ask questions about how to access and use it in in your perl code with starman and plack. There may be missing or rough bits in tools and documentation but lots of sites want to do what you have described so these things will appear and continue to improve. Good luck.
References
A Gentle Introduction to Plack Sessions
Deploy Catalyst Applications with Starman and Apache
Using Apache mod_auth_form
Authentication in Apache2.4 using mod_auth_form and mod_dbd
Reverse proxying behind Apache

Apache's mod_session looks to be the component you are missing. Since the proxy is the gateway to the applications in the back-end, it can handle the authentication on the HTTP layer and pass back sessions as needed to the Perl script using the proxy entry.
Exposing the user information to the Perl application can happen in a few ways.
mod_session_dbd - is a module to store session information in a database. This could then be shared with the back-end server hosting the Perl application.
mod_session_cookie - is a module to store session information in a cookie on the browser of the client. Session variables would be stored in the cookie and the Perl application would retrieve them.
But, cookies or putting session variables in the URL open up security concerns. Cookies and headers can be modified.
mod_proxy should pass the session variables back to the applications in the form html.
http://httpd.apache.org/docs/trunk/mod/mod_session.html

Related

Encrypted Password Accessible via API Call, Is this Secure?

I am working through some security concepts right now and I was curious if this method has been tried and/or if it is safe taking into consideration "Brute Forcing" is still possible.
Take for example a Microsoft WebAPI Template in Visual Studio where you access a endpoint using a "GET".
The Endpoint would be accessible by any user/application
The String value that a user/application would get from this endpoint would be the password they need, but encrypted using a "KeyValue"
After a TLS Transmission of this Encrypted Value, the user/application would decrypt the String using their "KeyValue"
Is this a secure practice?
Thanks for indulging me and look forward to your responses.
EDIT: Added Further Clarification with Image to Help Illustrate
Suppose the following 2 Scenarios:
Communication between Server and Client
a. Your Server serves the Client application with an encrypted password.
b. The Client can request any password.
c. The passwords are encrypted with a shared Key that is known by both server and client application
As James K Polk already pointed out:
A knowledgable Attacker can and will analyse your deployed application and at some point will find your hardcoded decryption key ("KeyValue"). What prevents him from requesting every password that is stored on the Server?
Rule of thumb here would be: "Do not trust the client side."
Communication between Server and Server
a. You have 2 server applications. Application A is acting as some kind of database server. Application B is your Back-End for a user application of some kind.
b. Application A serves paswords to any requester, not only Server B. With no type of authentication whatsoever.
c. Confidentiality is guaranteed through a shared and hard-coded Key.
I think you are trying to overcomplicate things hoping that no one is able to piece together the puzzle.
Someone with enough time and effort might be able to get information about your server compilation and/or be able to get the Code of Application B. Which again defaults in the scenario of 1. Another point is that there are enough bots out there randomly scanning ips to check responses. Application A might be found and even-though they do not have the shared key might be able to piece together the purpose of Application A and make this server a priority target.
Is this a safe practice?
No. It is never a good idea to give away possibly confidential information for free. Encrypted or not. You wouldn't let people freely download your database would you?
What you should do
All Authentication/Authorization (for example a user login, that's what I expect is your reason to exchange the passwords) should be done on the server side since you're in control of this environment.
Since you didn't tell us what you're actually trying to accomplish I'd recommend you read up on common attack vectors and find out about common ways to mitigate these.
A few suggestions from me:
Communication between 2 End-points -> SSL/TLS
Authorization / Authentication
Open Web Application Security Project and their Top 10 (2017)

OAuth redirect URI alternatives for non-web applications?

What would be the best way to handle redirect URIs for OAuth authentication?
In a few projects, I used to boot up a web server that would wait for the authentication to be sent back. Is there any way to trigger any type of code without a local web server, or is it the recommended way?
I'm not asking for help about any specific languages, this is more like a language agnostic question.
Side note: nice avatar... :)
Deciding on the best approach will depend on the exact scenario and any additional requirements your application might have, however, we can look at a few options and possible implication of choosing them.
The OAuth 2.0 specification suggests a few options to solve this issue, either using an embedded user-agent or relying on an external one.
The embedded user-agent may allow you better control on the UI aspects, however, by leveraging an external user-agent your users might benefit from an already established session and avoid having to input credentials one more time.
For an external user-agent we have a few options:
External user-agent - the native application can capture the response from the authorization server using a (1) redirection URI with a scheme registered with the operating system to invoke the client as the handler, (2) manual copy-and-paste of the credentials, (3) running a local web server, (4) installing a user-agent extension, or by (5) providing a redirection URI identifying a server-hosted resource under the client's control, which in turn makes the response available to the native application.
Option 1:
You configure a redirect using a custom scheme that your application registered in the operationg system, this way your application gets called when an external user-agent receives a response indicating a redirect to your scheme.
Option 2:
You redirect somewhere that just shows a pretty page with the code and ask the user to input it manually in your application.
Option 3:
You already used this one, basically the application starts a local web server and you configure the redirect to be something along the lines of http://localhost:[port]/.
Option 4:
By installing a user-agent extension you would have code running with the browser that could communicate the code automatically to your applications.
Option 5:
You configure a redirection URI that points to some server-side code you host and that your client Android application is aware of so that it can grab the code from that URL.
For much more information on this topic, check: OAuth 2.0 for Native Apps
As an additional not, if you don't want to go full server-side on the options that require some logic on the server, you can accomplish the same using much less lines of code by writing your server-side logic as a Webtask (be sure to use a custom domain).
Disclosure: I'm an Auth0 engineer.

Send emails through VB6 if no email client

I have a VB6 app which is used by a large number of clients.
I need to allow the clients to be able to send emails to me. In the past I have done this using Microsoft MAPI controls. However, not all of them have an email client installed, since they use webmail instead.
Is there any other method anyone can recommend which would allow them to do this?
SMTP
You can use CDO for Windows to do this if we make a few assumptions:
Your users are all on Win2K or later.
The users will never be behind a firewall blocking SMTP or proxying all SMTP port use to a corporate server.
You have an SMTP server that you have an account you can let the user-mails be sent with.
You embed the server's address and account credentials in your program.
Sometimes using an SMTP server listening on an alternate port will address the second issue, but often such an alternate port is even more likely to be blocked.
SMTP is Dying
Abuse over time has made SMTP less and less viable for automated/assisted user contact. There are just too many variables involved in trying to open some sort of "clear channel" for SMTP communication as people work harder to fight spammers and such.
Today I would be much more likely to use either WebDAV or a Web Service for this. Both use HTTP/HTTPS which is more likely to get past firewalls and usually get by most proxy servers as well. WebDAV is often more "slippery" at this than Web Services, which more and more proxies are bocking. You can also use something more RESTful than SOAPy since the traffic "smells more like" user browsing to proxy servers.
WebDAV is a Clean Option
There are even free WebDAV providers offering 2GB of storage with a main and a guest user. The guest account can be given limited rights to various folders so some folders they might post your messages to, other folders they might get data from (read only folders), etc. For a paid account you can get more storage, additional users, etc.
This works well. You can even use the same hosting for program version files, new version code to be downloaded and installed, etc. All you need on your end is an aggregator program that scoops up user posted messages and deletes them using the main user/pw.
You still need to embed user credentials in your program, but it can be a simpler matter to change passwords over time. Just have the program fetch an info file with a new password and an effective date and have the program flip the "new" password to "current" once run on that date or after.
WebDAV support in Windows varies. From WinXP SP3 forward you can simply programmatically map a drive letter to a WebDAV share and then use regular file I/O statements against it, and unmap the letter when done. For more general use across even Win9x you can build a simple WebDAV client on top of XMLHTTPRequest or use a 3rd party library.
Web Services Have Higher Costs
Just to start with you have server-side code to write and maintain, and you have to use a specific kind of hosting. For example if you built it using PHP you need a PHP host, ASP an ASP host, ASP.Net an ASP.Net host, etc.
Web Services can also be more problematic in terms of versioning. If you later update your program to provide different information in these user contact posts you have to make another Web Service as well as changing both the application and the aggregator. Using WebDAV you can just make a "new format" folder on the server and have the new program post the data there in the new format. Your aggregator can simply pull from both folders and do any necessary reformatting into your new local database/message repository format.
This is merely an incremental additional effort though and a Web Service might be the way to go, even if it is just something written like an HTML Form GET/POST acceptor.
Although this question is for VBA you may find it of interest. Sending Emails using VBA without MAPI

Per-session persistent sockets in a web application

I have a perl web application (CGI::Application with ModPerl::Registry) which connects to a authenticated custom server over a socket and exchanges data (command/response) with it. Currently the web application connects to the server, authenticates and disconnects on every page request - even for the same user.
Is there some way I can use the same socket over multiple page requests which share a common session id? Creating a separate daemon that proxies connections and makes them persistent is an option I am exploring, but would like to know if there are any simpler solutions.
I have no control over the design of the custom server unfortunately.
Looks like the same question was asked on PerlMonks. The responses there point in the right direction, but the issue seems to be that you want one cached connection per session, not one cached connection per session per httpd thread/process. You might have to resort to a separate proxy process to get the behaviour you want.

See what website the user is visiting in a browser independent way

I am trying to build an application that can inform a user about website specific information whenever they are visiting a website that is present in my database. This must be done in a browser independent way so the user will always see the information when visiting a website (no matter what browser or other tool he or she is using to visit the website).
My first (partially successful) approach was by looking at the data packets using the System.Net.Sockets.Socket class etc. Unfortunately I discoverd that this approach only works when the user has administrator rights. And of course, that is not what I want. My goal is that the user can install one relatively simple program that can be used right away.
After this I went looking for alternatives and found a lot about WinPcap and some of it's .NET wrappers (did I tell you I am programming c# .NET already?). But with WinPcap I found out that this must be installed on the user's pc and there is nog way to just reference some dll files and code away. I already looked at including WinPcap as a prerequisite in my installer but that is also to cumbersome.
Well, long story short. I want to know in my application what website my user is visiting at the moment it is happening. I think it must be done by looking at the data packets of the network but can't find a good solution for this. My application is build in C# .NET (4.0).
You could use Fiddler to monitor Internet traffic.
It is
a Web Debugging Proxy which logs all HTTP(S) traffic between your computer and the Internet. Fiddler allows you to inspect traffic, set breakpoints, and "fiddle" with incoming or outgoing data. Fiddler includes a powerful event-based scripting subsystem, and can be extended using any .NET language.
It's scriptable and can be readily used from .NET.
One simple idea: Instead of monitoring the traffic directly, what about installing a browser extension that sends you the current url of the page. Then you can check if that url is in your database and optionally show the user a message using the browser extension.
This is how extensions like Invisible Hand work... It scans the current page and sends relevant data back to the server for processing. If it finds anything, it uses the browser extension framework to communicate those results back to the user. (Using an alert, or a bar across the top of the window, etc.)
for a good start, wireshark will do what you want.
you can specify a filter to isolate and view http streams.
best part is wireshark is open source, and built opon another program api, winpcap which is open source.
I'm guessing this is what you want.
capture network data off the wire
view the tcp traffic of a computer, isolate and save(in part or in hole) http data.
store information about the http connections
number 1 there is easy, you can google for a winpcap tutorial, or just use some of their sample programs to capture the data.
I recomend you study up on the pcap file format, everything with winpcap uses this basic format and its structers.
now you have to learn how to take a tcp stream and turn it into a solid data stream without curoption, or disorginized parts. (sorry for the spelling)
again, a very good example can be found in the wireshark source code.
then with your data stream, you can simple read the http format, and html data, or what ever your dealing with.
Hope that helps
If the user is cooperating, you could have them set their browser(s) to use a proxy service you provide. This would intercept all web traffic, do whatever you want with it (look up in your database, notify the user, etc), and then pass it on to the original location. Run the proxy on the local system, or on a remote system if that fits your case better.
If the user is not cooperating, or you don't want to make them change their browser settings, you could use one of the packet sniffing solutions, such as fiddler.
A simple stright forward way is to change the comupter DNS to point to your application.
this will cause all DNS traffic to pass though your app which can be sniffed and then redirected to the real DNS server.
it will also save you the hussel of filtering out emule/torrent traffic as it normally work with pure IP address (which also might be a problem as it can be circumvented by using IP address to browse).
-How to change windows DNS Servers
-DNS resolver
Another simple way is to configure (programmaticly) the browsers proxy to pass through your server this will make your life easier but will be more obvious to users.
How to create a simple proxy in C#?