I am implementing a code generator for Swagger/OpenAPI. However, I run into a problem implementing the security requirement. These requirements are defined as a list of objects. The list members are alternatives (or) and the object members are anded. For example:
[ { a:[], b:{} }, { c:{}, d:{} } ]
This supposed to result in (a && b) || ( c && d)
However, implementing this I run into the problem that the actual security requirements have side effects:
OAuth2 - Must redirect if it fails
Basic – Must send a HTTP 401 Unauthorized status and a WWW-Authenticate header
ApiKey – whatever
However, since there is an or you cannot allow the first failure to set these side effects. It seems that you need to first try all combinations and then go back to the first and allow it to set the headers/result code?
Looking at the generators that are out there on http://editor.swagger.io/ I find most generators seem to ignore security and the Java generators seem to and the combined list. In my example I see a && b && c && d.
So my questions are:
Is there a generator that properly implements OpenAPI security?
How to handle these side effects?
Related
I'm developing software for 40+ years but I'm absolutely new to SAP UI5, so maybe this is very basic or a trivial problem but half a day of searching the internet brought no results:
In a Master-Detail View (defined in xml) I want to display a list of items with growing=true, growingThreshold=50 and growingScrollToLoad=false as a List.
In principle it got everything working OK now. But there is a tiny glitch, not essential, more in the category of a "nice to have":
All the examples I've seen so far show something like "[ 50 / 107 ]" below the "More" button. But in my program it is missing. I'm very sure the reason is __count is not included in the response sent from the Odata-Service implementation.
Testing directly with the SAP Gateway Service Builder (/SEGW) shows to include the count in the response $inlinecount=allpages needs to be appended to the service URI. And here it works fine - once I add this to the URI the count is included, when I leave it out or set it to none there is no count included.
Therefore the problem seems not to be in the service implementation. (At least the __count field is present or not present as expected. And I assume this is what enables the "[ # / # ]" indicator.)
When the request is then sent from the controller (implemented in JavaScript) this part is not added to the service URI, despite the OData-Model is created with defaultCountMode: "sap.ui.model.odata.CountMode.InlineRepeat". On the "Network" page of Chrome's developer tools I don't see the $inlinecount=allpages appended and also the "[ 50 / 107 ]" (or whatever is appropriate) is not shown with the "More" button.
I checked with the Chrome developer tools immediately after creating the Odata-Model if my setting in the OData-Model takes effect – and it does. And I checked once more before a request is made based on this OData-Model – and it is still there.
My only idea now is it might have something to do with the fact the request originates from the XML-view (ie. the JavaScript code created on behalf of it) and it might be using a different Odata model in which that option is not set.
How can I test for this?
Any other ideas?
Maybe an internationalization issue? (The trigger-text for displaying more entries is set to "Weiter" in German language. Maybe also the "[ # / # ]" parts needs to be re-defined elsewhere too?
The answer in the comment of Boghyon Hoffmann solved the problem:
[Use] defaultCountMode: "InlineRepeat" instead of adding a fully qualified name in string.
Or more specifically:
Given I am signed in as the 'admin' user, and I want to to impersonate a user 'testSiteUser'
Given the 'testSiteUser' node (rep:User) does not have a protected String[] property called rep:impersonators set with a value containing admin
How do to update the protected property rep:impersonators such that it contains admin?
Once the user node has this set, I'm confident that setting a cookie sling.sudo should allow user impersonation.
What I have tried so far..
curl -F:name=testSiteUser -Fpwd=testSiteUser
-FpwdConfirm=exampleSiteUser
-F'rep:impersonators'=admin
-F'rep:impersonators'#TypeHint='String[]'
-u admin:admin
http://localhost:8080/system/userManager/user.create.html
Which responds with 500
javax.jcr.nodetype.ConstraintViolationException: Attempt to set an
protected property rep:impersonators
According to the JCR Spec
16.3.12 Interaction with Protected Properties
Many features of JCR expose repository metadata as protected properties defined by mixin node types. For example, locking status is exposed by the properties jcr:lockOwner and jcr:lockIsDeep defined by mix:lockable. Changes to protected properties can only be made indirectly through a feature-specific API (for example, Node.lock), not through a generic write method like Node.setProperty. Such changes are not governed by the jcr:modifyProperties privilege, but rather by the particular feature-specific privilege, for example, jcr:lockManagement (see §16.2.3 Standard Privileges).
Perhaps the only way is to write my own Java code as shown below, but I'm pretty sure there should be a REST API to do this...
Authorizable authorizable = userManager.getAuthorizable(user.getId());
Principal admin = userManager.getAuthorizable("admin").getPrincipal();
jackrabbitUser = (User) authorizable;
Impersonation impersonation =jackrabbitUser.getImpersonation();
impersonation.grantImpersonation(admin);
Basically rep:impersonators is a read only property that is managed "indirectly through a feature-specific API" What is the API and procedure to do user impersonations using Apache Sling or Jackrabbit Oak?
I understood your question, that you want to add an impersonator via a REST-call.
As you already found, all security related properties are protected. So they can only be manipulated via API-calls - and not directly written to.
But AEM already has a lot specialized REST-API's for its own user interface. To find them you should first perform the desired action on the normal AEM UI. Then check with the browser network inspector, which http-request was made by the browser.
In your case go to the classic user manager (http://localhost:4502/useradmin).
There you find the curl:
curl 'http://localhost:4502/home/users/J/JfiFIrTqxwUamu2BvWj-' \
-u admin:admin \
-F_charset_=utf-8 \
-FmemberAction=sudoers \
-FmemberEntry=alex
In the example I added for user alex2 the impersonator alex. So alex can impersonate to alex2.
For the user alex you need the repository-path, which is encrypted meanwhile for security reasons. But this path is easy to find with the querybuilder. As example the following query:
http://localhost:4502/bin/querybuilder.json?path=%2fhome%2fusers&property=rep%3aauthorizableId&property.value=alex2&type=rep%3aUser
or via the querybuilder UI http://localhost:4502/libs/cq/search/content/querydebug.html
path=/home/users
type=rep:User
property=rep:authorizableId
property.value=alex2
Q1 - I have been reading through the docs for reCaptcha, and looking at many different forum cases but I am not experienced with API calls at all - I am trying to add a captcha to my custom contact form but I am stuck on the verification step trying to figure out how/where to send the info for verification, and how/where to receive it so I know weather or not the user is verified.
(Side Question: Why is it necessary to validate the token generated by the captcha? Isn't it good enough that you can tell weather or not the puzzle/answer was solved?)
Before the closing head tag:
<script src='https://www.google.com/recaptcha/api.js'></script>
End of my form:
<div class="g-recaptcha" data-sitekey="my-site-key"></div>
I can see the string/token generated by a correct answer when I call:
grecaptcha.getResponse();
Now (as I understand it) I have to verify this string/token which is where I get stuck:
URL: https://www.google.com/recaptcha/api/siteverify
METHOD: POST
DOCS: https://developers.google.com/recaptcha/docs/verify
I am relatively decent with jQuery and vanilla JS but when it comes to API calls I have almost no experience, which is why at this point in the docs I am unsure of how to 1 - form an/the API call (for verification), 2 - where to make the API call from template files-wise, 3 - how to get the response back, or rather how the response comes back.
As I mentioned I am using a Bigcommerce store, and the Google reCaptcha documentation mentioned in several different areas that this step is done on the server-side (or should be). I know that I am fairly restricted in the template files that I can modify - I can view and modify the HTML/CSS/JS files but I have no access to any PHP.
Any help or push in the right direction would be greatly appreciated - at this point I am going in circles finding and trying to read/follow the same docs (Google and other) and forum cases. Thank you.
Trying to answer your questions one by one.
Client side Captcha's are discussed here, please check and note that considering the power of Java Script, client side captchas are not safe.
How reCAPTCHA works: Once someone include below script, google will verify
user.
https://www.google.com/recaptcha/api.js
Writing below attributes in the Form will send data to google first and
response will be added in final post of the current Form with
attribute named g-recaptcha-response :
<div class="g-recaptcha" data-sitekey="your_site_key"></div>
How to validate reCAPTCHA One has to validate this g-recaptcha-response with google. [ NOTE: this is requried becaues
client can send any random value for attribute g-recaptcha-response
without going through Captcha ]
$verifyResponse =
file_get_contents('https://www.google.com/recaptcha/api/siteverify?
secret='.$YOUR_SECRET.'&response='.$_POST['g-recaptcha-response'])
/*allow_url_fopen must be ON if you want to use file_get_contents.
check it using phpinfo();*/
file_put_contents( "logfile", $verifyResponse, FILE_APPEND );
$responseData = json_decode($verifyResponse);
$register_result = 'Robot verification failed, please try again.';
if( $responseData->success )
{
$register_result = 'You are not a bot';
}
else $register_result = 'You are a bot.';
Captcha with HTML/JS/CSS reCaptcha will not work for you if you don't have PHP access.
Puzzles as Captcha Captcha Puzzles are also possible and such captcha's are also available but they are handled on server side.
The reCaptcha verification si to make sure that the answer you received does come from reCaptha server, that the user is not a robot, that it hasn't matured, and that it hasn't been used more than once.
All this is really important to the server running the app, more that the cliente showing the form in order to accept or reject the form to be processed.
This is why the validation has to be done on the server. The client is an unsecure environment that can be tricked so the server cannot trust it.
Besides, to do the validation you need a secret api key. As it is secret it can't be embeded into the client code.
If you don't have access to the php or cannot add and aditional php to do the validation, I don't think you can implement reCaptcha.
EDIT I
The bottom line is that client code (js, jQuery running in a browser) cannot be trusted to do any kind of validation from the server point of view.
For example suppose you implement an input element for the user to enter the result of the sum of two random integers between 0 and 9. Very simple.
In the javascript code in some place there is an:
if(a + b === c){
sendFormToServer();
}else{
reject();
}
Anyone using the browser's developer tools could bypass the "if" and directly call sendFormToServer(). And the server has no way of knowing it.
I am interested in the possibility of providing a set of validation rules for user input values.
So for example a textbox called 'Today' might require a rule that looks something like
IsADate() and (Value >= Date())
My problem is that nobody can tell me what rules are needed. In order to deliver a solution I need users to be able to decide for themselves what rules they want.
It occurred to me I could create a database table containing a separate field for each input - each field having a user-definable check constraint and data type, but this is too limiting (in terms of how many rules I can define)
I could allow the users a UI which would effectively allow them to provide a where clause which then executes a select count(*) from dual where <plugin logic>
And then I started to think I am just database-obsessed.
Any thoughts?
I did something similar using application code and business logic. If you create a token parser based on some of your common business objects that you can load and evaluate for various views or forms then you can start to create a collection of custom variables.
#Date.CurrentDate
#Date.LastQuarter
#Customer.LastInvoiceNumber
#Customer.ZipCode
#Customer.MaxNumberOfOrderItems
If you expose your tokens in a list of rules for a particular field you can build a custom component that will let users build expressions like.
Value [ Greater Than ] [ #Customer.LastOrderNumber ] [ AND ]
Value [ Starts With ] [ #Customer.CustomerID ]
In my opinion this would be more flexible than using sql for validation.
If users have limited of Delphi / Pascal syntax knowledge, a quick solution is to let them create the validation as a pascal function, and use TJvInterpreter from JCL library.
Easy to use, simple to implement, that's a good work around !
Reference:
http://jvcl.delphi-jedi.org/JvInterpreter.htm
I have two questions regarding Fortify.
1 - Lets say I have a windows forms app, which asks for a username
and password, and the name of the textbox for password is
texboxPassword. So in the designer file, you have the following,
generated by the designer.
//
// texboxPassword
//
this.texboxPassword.Location = new System.Drawing.Point(16, 163);
this.texboxPassword.Name = "texboxPassword";
this.texboxPassword.Size = new System.Drawing.Size(200, 73);
this.texboxPassword.TabIndex = 3;
Fortify marks this as a password in comment issue. How can I suppress this by creating a custom rule? I don't want to suppress the whole issue because I still would like to catch certain patterns (such as password followed by = or : in comments) but the blanket search where any line that contains password is flagged is creating so many false positives. I looked into creating a structural rule but could not figure out how to remove the associated tag (where can I find the tag for password in comment anyways?)
2 - Let's say I have a custom UI control. This control html encodes everything and in my context, it is good enough to avoid XSS. Needless to say, it is being flagged by Fortify. How can I suppress XSS when I have a certain control type in my UI and all of its methods are safe for XSS (they sanitize) in my context? I have tried a DataflowCleanseRule (with a label just to test the concept) and wanted to mark get_Text() and set_Text() as sanitizer functions, but it did not make a difference and Fortify still flagged it for XSS.
<DataflowCleanseRule formatVersion="3.16" language="dotnet">
<RuleID>0D495522-BA81-440E-B191-48A67D9092BE</RuleID>
<TaintFlags>+VALIDATED_CROSS_SITE_SCRIPTING_REFLECTED,+VALIDATED_CROSS_SITE_SCRIPTING_PERSISTENT,+VALIDATED_CROSS_SITE_SCRIPTING_DOM,+VALIDATED_CROSS_SITE_SCRIPTING_POOR_VALIDATION</TaintFlags>
<FunctionIdentifier>
<NamespaceName>
<Pattern>System.Web.UI.WebControls</Pattern>
</NamespaceName>
<ClassName>
<Pattern>Label</Pattern>
</ClassName>
<FunctionName>
<Pattern>_Text</Pattern>
</FunctionName>
<ApplyTo implements="true" overrides="true" extends="true"/>
</FunctionIdentifier>
<OutArguments>return</OutArguments>
</DataflowCleanseRule>
Thank you in advance for your help
This is parsed using regular expressions. Unless you think you are able to create a regular expression that can parse human language properly, I would leave it alone and just audit it as not an issue.
The Pattern tag uses a java regular expression in the body, so should be used as user2867433 suggested. However, you stated
This control html encodes everything and in my context, it is good enough to avoid XSS
If you are going to use a custom rule, this has to assume that it will work in EVERY context, as say in the future somebody writes a piece of code that uses get_Text and then places this directly into a piece of JavaScript, html encoding will do NOTHING to stop the XSS problem here. I would advise again to audit this as not an issue or a false positive due to the validation used and explain why it's good enough in that context
Within "Pattern" you can use Java-Regex. So it should work if you use [gs]et_Text