Can FIDO be implemented for a Use Case which Allows the Use of Shared Devices?

I am a part of an organization that is developing a website that required user authentication, and we are strongly considering FIDO compliance.

However, our use case requires users to be able to log-in from shared computers (i.e. father and son may share the same computer). And we cannot expect our user to carry around a FIDO authentication token (U2F key) as well.

In such a scenario, is it safe to use on-device biometric sensors (i.e. cameras, fingerprint scanner) on a shared device to authenticate multiple users?

How is VPN tunneling actually implemented?

I am new to VPNs, have used them a few times, have read about "how they work" (which is all very high level), and am now confused about how this is actually implemented (so I can come full circle and understand what kind of security they are providing me).

It sounds like a VPN is something you install on your computer. You then perform your actions in the VPN UI (whether it’s a terminal or a GUI). These "local" actions are then encrypted (what is the encryption method/protocol?) locally. Then, say I am at my house using WIFI or at the coffee shop. It uses my newly allocated public IP address (the one I’ve been assigned for only the past few hours), to send this encrypted data across the public internet, in the public WIFI at the coffee shop. So people can tell I am sending something over the internet, just not sure what (because it’s encrypted). The way these articles sound, they make it sound like magic and that you get a static IP address locally which no one can see. That’s not the case right? It is doing exactly what I’m saying. I ask this question to clarify and make sure I’m understanding correctly.

So then the encrypted traffic (going across the public internet, using my publicly known IP address), is sent to some remote server. That server then performs the real actions I was typing at my VPN terminal/GUI. It makes whatever internet requests and whatnot, or SSH’s into some computer I’m targeting, and pipes the info back, encrypted, over the public internet, to decrypt it locally on my computer. Hopefully I’m still on the right track. Then that remote computer I sent my encrypted traffic to, what does it do to obscure my message or secure my message from its standpoint? Does it dynamically change its IP address? Is it situated in some remote wilderness guarded by gates so no one can intercept the traffic? How does it stay secure in sending messages to the actual target location? Or is it just the fact that the requests are no longer coming from my computer, so no one can know its me, all the security its accomplishing?

Basically, I’m wondering if this is sort of how it’s implemented.

Secure HTTP Headers – where should be implemented, WAF or code level?

I have an REST API exposed to the Internet and another application with form-based authentication.

These apps are behind Web Application Firewall.

Question is, where I should implement below Secure HTTP Headers, on WAF or Code level?

X-XSS-Protection X-Frame-Options X-Content-Type-Options X-Permitted-Cross-Domain-Policies HTTP Strict Transport Security HTTP Public Key Pinning Content Security Policy Referrer Policy Feature-Policy

Proof strategy to show that an algorithm cannot be implemented using just hereditarily terminating procedures

I am taking my question here from there. Consider the following scenario:

You are given a fixed programming language with no nonlocal control flow constructs. In particular, the language does not have

  • Exceptions, first-class continuations, etc.
  • Assertions, in the sense of “runtime tests that crash the program if they fail”.

Remark: An example of such a language could be Standard ML, minus the ability to raise exceptions. Inexhaustive pattern matching implicitly raises the Match exception, so it is also ruled out.

Moreover, you are forced to program using only hereditarily terminating values. Inductively, we define hereditarily terminating values as follows:

  • Data constructors (including numeric and string literals) are hereditarily terminating.
  • Applications of data constructors to hereditarily terminating arguments are hereditarily terminating.
  • A procedure f : foo -> bar is hereditarily terminating if, for every hereditarily terminating x : foo, evaluating the expression f x always terminates and the final result is a hereditarily terminating value of type bar.

Remarks:

  • Hereditarily terminating procedures need not be pure. In particular, they may read from or write to a mutable store.

  • A procedure is more than just the function it computes. In particular, functions do not have an intrinsic asymptotic time or space complexity, but procedures do.


Hereditarily terminating procedures formalize my intuitive idea of “program that is amenable to local reasoning”. Thus, I am interested in what useful programs one can write using only hereditarily terminating procedures. At the most basic level, programs are built out of algorithms, so I want to investigate what algorithms are expressible using only hereditarily terminating procedures.

Unfortunately, I have hit an expressiveness ceiling much earlier than I expected. No matter how hard I tried, I could not implement Tarjan’s algorithm for finding the strongly connected components of a directed graph.

Recall that Tarjan’s algorithm performs a depth-first search of the graph. In addition to the usual depth-first search stack, the algorithm uses an auxiliary stack to store the nodes whose strongly connected components have not been completely explored yet. Eventually, every node in the current strongly connected component will be explored, and we will have to pop them from the auxiliary stack. This is the step I am having trouble with: The loop that pops the nodes from the stack terminates when a given reference node has been found. But, as far as the type checker can tell, the reference node could not be in the stack at all! This results in an extra control flow path in which the stack is empty after popping everything from it and still not finding the reference node. At this point, the only thing the algorithm can do is fail.

This leads to the following…

Conjecture: Tarjan’s algorithm cannot be implemented in Standard ML using only hereditarily terminating procedures.

My questions are:

  1. What kind of proof techniques would be necessary to prove the above conjecture?

  2. What is the bare minimum type system in which Tarjan’s algorithm can be expressed as a hereditarily terminating program? That is, what is the bare minimum type system that can “understand” that the auxiliary stack is guaranteed to contain the reference node, and thus will not add a control flow path in which the auxiliary stack is empty before the reference node has been found?


Final remark: It is possible to rewrite this program inside a partiality monad. Then every procedure would be a Kleisli arrow. Instead of

val tarjan : graph -> scc list 

we would have something like

val tarjan : graph -> scc list option 

But, obviously, this defeats the point of the exercise, which is precisely to take out the procedure out of the implicit partiality monad present in most programming languages. So this does not count as a solution.

Why is this defense against “It’s a Unix system!” not widely implemented?

The Jurassic Park scene referenced in the title is infamous for how ludicrous it sounds to those who are tech literate. But it also illustrates what seems to me to be a glaringly huge hole in web security, particularly IoT devices–as soon as attackers find out a server or camera or baby monitor is running linux, they instantly know volumes about how it works. They know that commands like sudo are big juicy targets and they know that shell access will bring with it gobs of useful tools like ls and cat.

So why isn’t OS obfuscation more of a thing? I’m not talking about just hiding the version in web headers. Similar to JavaScript minification or obfuscation, I’m talking about changing the names of binaries and filepaths in the OS itself. Wouldn’t entire classes of attacks be practically useless if the OS had ha7TrUO and RRI6e29 commands instead of sudo and ls? Imagine a hacker that somehow gained remote root access–what are they even going to do if they don’t know any commands?

Implementation would be fairly easy for compilers. Take the simplest case of “rename this function and all calls to it.” You could give an OS compiler and an application compiler the same randomized names and they’d be able to talk to each other. But even if the application has poor security and is vulnerable to bash injection, such attacks would be fruitless.

Obviously this technique can’t be used in all scenarios. Setting aside scenarios like servers maintained by human sysadmins, it seems to me that any device or server managed by automation is a prime candidate for this defense.

I guess the question(s) needs to be a bit more concrete:

  1. Is OS obfuscation as described used widely and I just haven’t encountered it?
  2. If not used widely, what are the practical or technical barriers to usage?

Bellman-Ford algorithm implemented with queues in C

I am in the midst of applying a bellman ford algorithm using a queue and my code works for all cases where the source vertex is 0 however outputs garbage when the source vertex is changed. I think there must be an issue with the line “foredge;edge<(nn);edge);” Thanks.


include

include

include

int readGraphWeighted(int n, int m, int graph[]){ int i; int size = n*n; for(i = 0; i < size; i++){ graph[i] = 0; }

int edgeA; int edgeB; int weight; for(i = 0; i < m; i++){ scanf(“%d %d %d”, &edgeA, &edgeB, &weight); graph[edgeA*n + edgeB] = weight;

} }

int findVal(int element, int queueSize, int queue[]){

//if element is in the queue then function returns 0 //else it returns 1 int i; int toReturn=1; for(i=0;i<queueSize;i++){     if(element==queue[i]){         toReturn=0;     } } return toReturn; 

}

int main(){

//initialize all necessary int n; int m;  scanf("%d %d",&n,&m);   int d[n]; int p[n]; int graph[n*n]; int queue[n]; int source; int edge; int queueSize=0; int head=0;   //intermediary variables int i; int row; int col;  //read in all information needed readGraphWeighted(n,m,graph); scanf("%d",&source);  //intialize everything as instructed for(i=0;i<n;i++){     d[i]=INT_MAX;     p[i]=-1;     queue[i]=0; }  queue[head]=source; queueSize++; d[source]=0; p[source]=source;  //**main body of program**   while(queueSize !=0){     //pop     edge=queue[head];     queueSize=queueSize-1;     head++;      //for every edge     for(edge;edge<(n*n);edge){          if(graph[edge] !=0){             //if we reach a value in graph record its row and col             row=edge/n;             col=edge%n;              //if the value in d is larger replace it             if(d[col]>d[row]+graph[edge]){                 d[col]=d[row]+graph[edge];                  //update predecessor                 p[col]=row;                  if(findVal(col,queueSize,queue) == 1){                      //push                     queue[queueSize-1]=col;                     queueSize++;                 }             }         }     } } printf("\nRESULTS:\nsource vertex: %d\n",source); printf("D: "); for(i=0;i<n;i++){     printf("%d, ",d[i]); } printf("\n"); printf("P: "); for(i=0;i<n;i++){     printf("%d, ",p[i]); } 

}