Symfony2 and Uploadify : security token is not kept - security

I'm trying to make Symfony2 and Uploadify working together in a secured area.
(Uploadify is a flash/javascript component used to upload multiple files)
My uploadify component is working fine when the back-end script route is out of the secure area, but when in this area, I get a 302 HTTP error.
The log message is :
security.INFO: Authentication exception occurred; redirecting to authentication entry point (A Token was not found in the SecurityContext.)
While searching for an answer, I found that passing the PHPSESSID to the back-end script as a post parameter should work on "non-framework php" but with the Symfony Security Component, it seems that this script is not even reached.
Does anyone know if there is a way to send that token to the back-end script while keeping this script in the secure area ?

After having a read around the Symfony website, it's possible that this solution may work (haven't tested it). In your security.yml file, change your access_contol config option to something like this...
access_control:
- { path: ^/path/to/flash_component, roles: IS_AUTHENTICATED_ANONYMOUSLY }
Where /path/to/flash_component is the URL you are uploading to in Uploadify. Let me know if that works.

Related

Prevent showing the UI5 app internal page without successful authentication

OpenUI5 version: 1.86
Browser/version (+device/version): Chrome Dev
Upon the authentication I validate the user session:
if (isUserSessionValid) {
const oRouter = UIComponent.getRouterFor(this);
oRouter.navTo("overview");
} else {
this.getOwnerComponent().openAuthDialog();
}
If isUserSessionValid is true, then I forward an user to the internal page, otherwise I show the login dialog.
The problem is, however, that an user can change the value of isUserSessionValid in DevTools and then getting forwarded to the UI5 app internal page. Of course, due to a lack of a valid session, no piece of the business data will be displayed, just an empty UI5 app template, but I would like to prevent even such screen.
If it would be a classical webapp, I would just send an appropriate server response with a redirect to the login page (e.g. res.redirect(403, "/login");). But, if I understand it correctly, since I'm sending am asynchronous request, a plain res.redirect won't work out and I'm required to implement a redirection logic on the UI5-client, which can be manipulated and bypassed by user.
How to prevent a manipulation of a view navigation in UI5 and ensure that unauthorized user can't get any piece of the UI5-app code?
The answer from SAP:
If you want to prevent an unauthorized user from accessing the client-side code (e.g. view/controller) you need to enforce
authorization on the server also for those static files. When bundling
the application code you also need to ensure that those files are
separate from the "public" files. One approach would be to have 2
separate components, one for the public page/auth dialog and one for
the actual application.

Cors no-access-control-allow-origin when trying to call B2C login

I cannot resolve this error, i have a .net core web api, with a react application inside of it ( net core react template )
I have also added cors:
services.AddCors(options =>
{
options.AddPolicy("AllowMyOrigin",
builder => builder.WithOrigins("https://localhost:44300")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
);
});
I have tried multiple things but i cant get past this error.
I have found loads of material online to try and nothing seems to work i feel like i am missing something really obvious?
Can someone point me in the right direction.
I expect that there should be an allow origin header:
I also tried using the Mosif browser extension to turn cors on, this stoped the cors error from showing but now i have a 404 (notfound ) on:
https://login.microsoftonline.com/tfp/domainname.onmicrosoft.com/b2c_1_sign_up/v2.0/.well-known/openid-configuration
You mention that you get an 404 error when opening the openid-configuration url. This means that part of your configuration is incorrect. You must be able to open this url in your browser and get back a JSON document. Copy it to a new tab and tweak it until you get back a result.
Please double check your configured policy and tenant name. The full url usually looks like this:
https://tenantname.b2clogin.com/tenantname.onmicrosoft.com/<policy-name>/v2.0/.well-known/openid-configuration
https://tenantname.b2clogin.com/tenantname.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=<policy-name>
https://login.microsoftonline.com/tfp/tenantname.onmicrosoft.com/<policy-name>/v2.0/.well-known/openid-configuration
All of these are equally valid and can be used depending on your scenario.
The config should then look something like this:
authentication.initialize({
instance: 'https://tenantname.b2clogin.com/',
tenant: 'tenantname.onmicrosoft.com',
Another issue might be if your B2C tenant quite new, Microsoft could be blocking support for microsoftonline for your tenant. In this case, try switching to the b2clogin.com domain as your instance.
You can see a possible value for this url when opening the user flow in the Azure Portal.
As a sidenote, I would suggest switching to a different react library. The one you are using is not really being maintained. We are currently using https://github.com/syncweek-react-aad/react-aad

How to fill login prompt with Webdriver IO?

I'm working on a CLI with OCLIF. In one of the commands, I need to simulate a couple of clicks on a web page (using the WebdriverIO framework for that). Before you're able to reach the desired page, there is a redirect to a page with a login prompt. When I use WebdriverIO methods related to alerts such as browser.getAlertText(), browser.sendAlertText() or browser.acceptAlert, I always get the error no such alert.
As an alternative, I tried to get the URL when I am on the page that shows the login prompt. With the URL, I wanted to do something like browser.url(https://<username>:<password>#<url>) to circumvent the prompt. However, browser.url() returns chrome-error://chromewebdata/ as URL when I'm on that page. I guess because the focus is on the prompt and that doesn't have an URL. I also don't know the URL before I land on that page. When being redirected, a query string parameter containing a token is added to the URL that I need.
A screenshot of the prompt:
Is it possible to handle this scenario with WebdriverIO? And if so, how?
You are on the right track, probably there are some fine-tunings that you need to address to get it working.
First off, regarding the chrome-error://chromewebdata errors, quoting Chrome DOCs:
If you see errors with a location like chrome-error://chromewebdata/
in the error stack, these errors are not from the extension or from
your app - they are usually a sign that Chrome was not able to load
your app.
When you see these errors, first check whether Chrome was able to load
your app. Does Chrome say "This site can't be reached" or something
similar? You must start your own server to run your app. Double-check
that your server is running, and that the url and port are configured
correctly.
A lot of words that sum up to: Chrome couldn't load the URL you used inside the browser.url() command.
I tried myself on The Internet - Basic Auth page. It worked like a charm.
URL without basic auth credentials:
URL WITH basic auth credentials:
Code used:
it('Bypass HTTP basic auth', () => {
browser.url('https://admin:admin#the-internet.herokuapp.com/basic_auth');
browser.waitForReadyState('complete');
const banner = $('div.example p').getText().trim();
expect(banner).to.equal('Congratulations! You must have the proper credentials.');
});
What I'd do is manually go through each step, trying to emulate the same flow in the script you're using. From history I can tell you, I dealt with some HTTP web-apps that required a refresh after issuing the basic auth browser.url() call.
Another way to tackle this is to make use of some custom browser profiles (Firefox | Chrome) . I know I wrote a tutorial on it somewhere on SO, but I'm too lazy to find it. I reference a similar post here.
Short story, manually complete the basic auth flow (logging in with credentials) in an incognito window (as to isolate the configurations). Open chrome://version/ in another tab of that session and store the contents of the Profile Path. That folder in going to keep all your sessions & preserve cookies and other browser data.
Lastly, in your currentCapabilities, update the browser-specific options to start the sessions with a custom profile, via the '--user-data-dir=/path/to/your/custom/profile. It should look something like this:
'goog:chromeOptions': {
args: [
'--user-data-dir=/Users/iamdanchiv/Desktop/scoped_dir18256_17319',
],
}
Good luck!

simple form symfony2 firewall redirection

Here is my issue.
Situation:
I am trying to add some custom logic during user login. I could find to ways to do so:
hard way (but with a lot of control); building my own authentication provider, following this guidelines of the cookbook or this complementing publication of vandenbrand
easy way (exactly what I need ): use simple_form. simple_form is a key which has the same options as form_login, but for which I can define an "authenticator".
cookbook tuto I used can be found here
Issue
I had an existing and operational app/security.yml configuration with 'form_login' key.
secured_area:
pattern: ^/foo/user/secured/
form_login:
check_path: /foo/user/secured/login_check
login_path: /foo/user/login
I followed steps of the tutorial described above. therefore, my security.yml gets modified to:
secured_area:
pattern: ^/foo/user/secured/
#form_login:
simple_form:
authenticator: foo_authenticator
check_path: /foo/user/secured/login_check
login_path: /foo/user/login
when I try to access a page /foo/user/secured/target of the secured area, the firewall does its job: it catches the query and asks for credentials (via intermediary page /foo/user/login).
However, once right credentials input (and obviously validated), I keep staying on the same page. It does not redirect to the page /foo/user/secured/target I was asking for in the first place. There is no refreshing to trying to go to that page via new request: I remain stuck at login stage.
EDIT 1: here are the steps I identify based on logs and debugging:
1) user tries to access /foo/user/secured/target, for which you need to be identified at least with ROLE_USER to access
2) firewall intercepts this request, as it matches listened routes (app/config/security.yml):
secured_area:
pattern: ^/foo/user/secured/
3) it redirects toward login route
4) user fills in with username and password, and submits post
5) when form is received, a token gets created by createToken method of custom authenticater. It returns an object of class UsernamePasswordToken created with parameter username, password in clear, authenticater key: UsernamePasswordToken($username, $password, $providerKey)
6) token gets passed onto authenticateToken method de of authenticater object. this method compares clear password hash contained in token andd accessed through $token->getCredentials()) with hashed password in database.
7) authentication worked: we get redirected toward /foo/user/secured/target . token and user get serialized in session (ISSUE STARTS HERE: indeed, user clear password is erased so that it doesn't leave tracks in session, and getCredentials() will return empty string now).
8) while loading page, le firewall is activated. It detects user logged in, seems to want to check its token. Therefore, it calls authenticateToken.
9) authenticateToken tries to compare sha1($token->getCredentials()) to hashed password in database. comme $token->getCredentials() is empty, comparison fails. authenticateToken raises an exception.
10) raised exception triggers firewall redirection toward login page. There we are: stuck in infinite loop landing systematically on login page.
STOP EDIT 1.
Solution
Does anyone know why this change of behaviour between 'form_login' and 'simple_form'? Most of all, would you know a good way to fix this ? I guess authenticate method or custom authenticater should be slightly changed, but I am not yet confident enough with security to solve this elegantly.
Many thanks in advance.
Kind regards,
Wisebes
You have to use some string (not the object) from sample. Or implement __toString() for User entity.
NOT
return new UsernamePasswordToken($user, ...
USE
return new UsernamePasswordToken($user->getEmail() or whatever, ...
if you want to access to the page you was requesting, you could use any of the options that Symfony offers to you:
Redirecting after Login:
always_use_default_target_path (type: Boolean, default: false)
default_target_path (type: string, default: /)
target_path_parameter (type: string, default: _target_path)
use_referer (type: Boolean, default: false)
You could see the section of the book 'SecurityBundle Configuration ("security")'
http://symfony.com/doc/current/reference/configuration/security.html
I hope that this be useful for you.
Kind regards.
well, as I was not able to make it work fine, I created my own custom authentication provider. I hope the issue reported above will be fixed asap. If anyone has got an answer, I still am interested!
For other people facing the same issue, I recommend creating a custom authentication provider. You may even inherit from existing authentication provider, and therefore limit modifications to be done. All in all, you are able to add your custom logic with a limited amount of trouble that way.

Rails 4 path traversal possible?

The app I'm working on has a controller that issues templates to the front end (single page app). It's very basic, and simply consists of
#path = params[:path]
render template: "templates/#{#path}", layout: nil
Here my concern however is the direct use of the users input. Everything about this to me feels like it can be attacked with something as simple as path traversal. The route for this is
get "/templates/:path.html" => "templates#file", constraints: { path: /.+/ }, defaults: { format: 'html' }
I've tried multiple things to attempt a path traversal attack, such as
request /templates/path/to/../somewhere/else.html
request /templates?path=/path/to/../../something.rb
request /templates/index.html?path=/path/to/../../config/something.html
request /templates/path/../../../file.html
Fortunately, I haven't had any success with this. The requests that just start with /templates and don't specify anything after it, don't match the route thanks to the constraint so that is good.
It seems as though when that route is matched, rails doesn't allow you to override the path parameter through a url parameter, so I don't seem to be able to inject it there.
The ones that interest are the first and last examples above, where rails seems to internally be changing the requested URL before invoking the routes file. When I request /templates/path/to/../somewhere/else.html, my console output shows a request for /templates/path/somewhere/else.html. When I make a request for /templates/path/../../../file.html, the log shows a request for /file.html.
Am I missing something somewhere that will leave the app open to security issues, or is this just rails being sensible and protecting itself for me?
UPDATE
I've done some more digging, and if I try doing some URL encoding then I can cause the server to simply not respond at all. If I request /templates/%2e%2e%2f%2e%2e%2f%2e%2e%2ffresult.html then I just get an empty response with a connection: close header.
I assume that the parameter parser higher up in the rack is checking all urls for this type of attack? Regardless, my original question still stands. Am I missing something here?

Resources